Bel*_*igh 0 sql-server t-sql sql-server-2008-r2
我正在尝试使用左外连接从两个表中返回数据。MetaKnight 拥有最多的 storeNames,我希望所有这些都返回,当然还有来自 KnightNinja 的相应数据。我把下面的语法放在一起,但我的语法只返回两个表中符合条件的商店的名称。例如,应该返回 Store D 和 Store E,因为日期是 2017 年 1 月 - 但语法不会返回它。为什么?
这是示例垃圾 DDL 和查询
Create Table MetaKnight
(
storeName varchar(500) NOT NULL
,storeNumber varchar(100) NOT NULL Primary Key
,openDate date NOT NULL
)
Create NonClustered Index snIndex
On MetaKnight (storeName ASC)
Create Table KnightNinja
(
storeName varchar(500) NOT NULL
,ssID varchar(100) NOT NULL Primary Key
,c1 int not null Default(0)
,c2 int not null Default(0)
,c3 int not null Default(0)
,c4 int not null Default(0)
,d1 date not null
)
Create NonClustered Index storeIndex
On KnightNinja (storeName ASC)
Insert Into KnightNinja (storeName, ssID, c1, c2, c3, c4, d1) Values
('Store A', '1234', '7018', '0', '4635', '6', '2017-03-13'),
('Store B', '5678', '0', '0', '0', '0', '2017-01-28'),
('Store C', '9101', '219', '898', '154', '11', '2017-01-10'),
('Store D', '8842', '25019', '258947', '5746', '0', '2017-01-31'),
('Store E', '6643', '26682', '25920', '3410', '281', '2017-02-15'),
('Store F', '2211', '57', '0', '392', '22', '2017-03-11'),
('Store G', '1432', '398', '1007', '407', '0', '2017-01-10'),
('Store G', '8879', '534', '3125', '954', '19', '2017-03-11'),
('Store H', '8675', '40', '0', '146', '147', '2017-01-01'),
('Store I', '2411', '0', '4899', '0', '0', '2017-01-20')
INSERT INTO MetaKnight (storeName, storeNumber, openDate) Values
('Store A', '2.2', '2017-01-19'),
('Store B', '8103', '2017-10-25'),
('Store C', '5522', '2017-10-25'),
('Store D', 'Blue', '2017-09-26'),
('Store E', 'B6565','2017-04-28'),
('Store G', 'E999', '2017-01-14'),
('Store G', 'L1354','2017-01-14'),
('Store G', 'R2288','2017-01-14'),
('Store H', 'A5678','2017-01-28'),
('Store I', 'C1234','2017-01-14')
Select
mk.storeName
,[Ninja Count] = COUNT(kn.ssID)
,[Meta Count] = COUNT(mk.storeNumber)
,[C1 Total] = SUM(COALESCE(kn.c1,0))
,[C2 Total] = SUM(COALESCE(kn.c2,0))
,[C3 Total] = SUM(COALESCE(kn.c3,0))
,[C4 Total] = SUM(COALESCE(kn.c4,0))
FROM MetaKnight mk
LEFT OUTER JOIN KnightNinja kn
ON mk.storeName = kn.storeName
AND kn.d1 >= '2017-01-01'
AND kn.d1 < '2017-02-01'
WHERE mk.openDate >= '2017-01-01'
AND mk.openDate < '2017-02-01'
GROUP BY mk.storeName
ORDER BY mk.storeName ASC
Drop Table KnightNinja
Drop Table MetaKnight
Run Code Online (Sandbox Code Playgroud)
看看Aaron Bertrand 的这个有趣的答案,你会得到关于正在发生的事情的详细答案。
您应该将 WHERE 子句的所有条件移动到 LEFT JOIN 子句。
Run Code Online (Sandbox Code Playgroud)Select mk.storeName ,[Ninja Count] = COUNT(kn.ssID) ,[Meta Count] = COUNT(mk.storeNumber) ,[C1 Total] = SUM(COALESCE(kn.c1,0)) ,[C2 Total] = SUM(COALESCE(kn.c2,0)) ,[C3 Total] = SUM(COALESCE(kn.c3,0)) ,[C4 Total] = SUM(COALESCE(kn.c4,0)) FROM MetaKnight mk LEFT OUTER JOIN KnightNinja kn ON mk.storeName = kn.storeName AND kn.d1 >= '2017-01-01' AND kn.d1 < '2017-02-01' AND mk.openDate >= '2017-01-01' AND mk.openDate < '2017-02-01' GROUP BY mk.storeName ORDER BY mk.storeName ASC GO店名 | 忍者伯爵| 元计数 | C1 总计 | C2 总计 | C3 总计 | C4 总计 :-------- | ----------: | ---------: | -------: | -------: | -------: | -------: 店铺 A | 0 | 1 | 0 | 0 | 0 | 0 店铺 B | 0 | 1 | 0 | 0 | 0 | 0 店铺 C | 0 | 1 | 0 | 0 | 0 | 0 店铺 D | 0 | 1 | 0 | 0 | 0 | 0 商店 E | 0 | 1 | 0 | 0 | 0 | 0 商店 G | 3 | 3 | 第1194章 3021 | 第1221章 0 店铺 H | 1 | 1 | 40 | 0 | 146 | 147 店铺我 | 1 | 1 | 0 | 4899 | 0 | 0 警告:空值被聚合或其他 SET 操作消除。
dbfiddle在这里
更新
在这种情况下会出现问题,因为您的查询都没有返回 all storeName。
Run Code Online (Sandbox Code Playgroud)SELECT mk.storeName, [Meta Count] = COUNT(mk.storeNumber) FROM MetaKnight mk WHERE mk.openDate >= '2017-01-01' AND mk.openDate < '2017-02-01' GROUP BY mk.storeName;店名 | 元计数 :-------- | ---------: 店铺 A | 1 商店 G | 3 店铺 H | 1 店铺我 | 1
Run Code Online (Sandbox Code Playgroud)SELECT kn.storeName, [Ninja Count] = COUNT(kn.ssID), [C1 Total] = SUM(COALESCE(kn.c1,0)), [C2 Total] = SUM(COALESCE(kn.c2,0)), [C3 Total] = SUM(COALESCE(kn.c3,0)), [C4 Total] = SUM(COALESCE(kn.c4,0)) FROM KnightNinja kn WHERE kn.d1 >= '2017-01-01' AND kn.d1 < '2017-02-01' GROUP BY kn.storeName GO店名 | 忍者伯爵| C1 总计 | C2 总计 | C3 总计 | C4 总计 :-------- | ----------: | -------: | -------: | -------: | -------: 店铺 B | 1 | 0 | 0 | 0 | 0 店铺 C | 1 | 第219话 第898话 154 | 11 店铺 D | 1 | 25019 | 258947 | 5746 | 0 商店 G | 1 | 第398话 1007 | 407 | 0 店铺 H | 1 | 40 | 0 | 146 | 147 店铺我 | 1 | 0 | 4899 | 0 | 0
让我建议另一种方法:
Run Code Online (Sandbox Code Playgroud)WITH sn AS ( SELECT DISTINCT storeName FROM MetaKnight ) SELECT sn.storeName, kn1.[Ninja Count], cnt.[Meta Count], kn1.[C1 Total], kn1.[C2 Total], kn1.[C3 Total], kn1.[C4 Total] FROM sn LEFT JOIN (SELECT mk.storeName ,[Meta Count] = COUNT(mk.storeNumber) FROM MetaKnight mk WHERE mk.openDate >= '2017-01-01' AND mk.openDate < '2017-02-01' GROUP BY mk.storeName) cnt ON sn.storeName = cnt.storeName LEFT JOIN (SELECT kn.storeName, [Ninja Count] = COUNT(kn.ssID), [C1 Total] = SUM(COALESCE(kn.c1,0)), [C2 Total] = SUM(COALESCE(kn.c2,0)), [C3 Total] = SUM(COALESCE(kn.c3,0)), [C4 Total] = SUM(COALESCE(kn.c4,0)) FROM KnightNinja kn WHERE kn.d1 >= '2017-01-01' AND kn.d1 < '2017-02-01' GROUP BY kn.storeName) kn1 ON sn.storeName = kn1.storeName ORDER BY sn.storeName ASC GO店名 | 忍者伯爵| 元计数 | C1 总计 | C2 总计 | C3 总计 | C4 总计 :-------- | ----------: | ---------: | -------: | -------: | -------: | -------: 店铺 A | 空| 1 | 空| 空| 空| null 店铺 B | 1 | 空| 0 | 0 | 0 | 0 店铺 C | 1 | 空| 第219话 第898话 154 | 11 店铺 D | 1 | 空| 25019 | 258947 | 5746 | 0 商店 E | 空| 空| 空| 空| 空| 空值 商店 G | 1 | 3 | 第398话 1007 | 407 | 0 店铺 H | 1 | 1 | 40 | 0 | 146 | 147 店铺我 | 1 | 1 | 0 | 4899 | 0 | 0
dbfiddle在这里
| 归档时间: |
|
| 查看次数: |
65 次 |
| 最近记录: |