[英]SQL joining the same table multiple times on the same column with differing restrictions
我有2张桌子
| Categories | | Products |
:--------------------: :------------------------:
| Id int | | Id int |
| Name nvarchar(max) | | Name vnarchar(max) |
| ApprovedForRelease bit |
| ApprovedForRecall bit |
| CategoryId int |
我需要获取所有类别的 ApprovedForRealease、notapprovedForRelease、ApprovedForRecall 和 not ApprovedForRecall 的产品计数
像这样的东西
| Category | #Released | #NotReleased | #Recalled | #NotRecalled |
:----------------------------------------------------------------:
| Arts | 5 | 1 | 3 | 4 |
| Crafts | 13 | 7 | 7 | 8 |
我的查询看起来像这样
SELECT
Category = cat.Name,
#Releases = Count(released.Id),
#NotReleased = Count(notReleased.Id),
#Recalled = Count(recalled.Id),
#NotRecalled = Count(notRecalled.Id),
-- Selected product ids
releasedIds = STRING_AGG(released.Id, ', '),
notReleasedIds = STRING_AGG(notReleased.Id, ', '),
recalledIds = STRING_AGG(recalled.Id, ', '),
notRecalledIds = STRING_AGG(notRecalled.Id, ', ')
FROM
Categories as cat
LEFT JOIN Products as released ON released.CategoryId = cat.Id AND released.ApprovedForRelease = 1
LEFT JOIN Products as notReleased ON released.CategoryId = cat.Id AND notReleased.ApprovedForRelease = 0
LEFT JOIN Products as recalled ON released.CategoryId = cat.Id AND recalled.ApprovedForRecall = 1
LEFT JOIN Products as notRecalled ON released.CategoryId = cat.Id AND notRecalled.ApprovedForRecall = 0
GROUP BY
cat.Name
我注意到产品数量有点太多,所以我添加了 Selected product ids 列来检查实际连接的内容,并注意到连接的表多次具有相同的行
我会得到的结果示例:
| Category | #Released | #NotReleased | #Recalled | #NotRecalled | releasedIds | notReleasedIds | recalledIds | notRecalledIds |
:------------------------------------------------------------------------------------------------------------------------------:
| Arts | 3 | 3 | 3 | 3 | 1, 2, 3 | 4, 5, 6 | 10, 10, 10 | 6, 6, 6 |
| Crafts | 2 | 2 | 4 | 2 | 25, 26 | 96, 98 | 7, 8, 7, 8 | 9, 9 |
有人可以向我解释发生了什么以及为什么某些产品会多次加入吗?
有没有办法在不使用子查询的情况下实现我想要的结果,例如:
SELECT
Category = cat.Name,
#Releases = (SELECT COUNT (Id) FROM PRODUCTS WHERE CategoryId = cat.Id AND ApprovedForRelease = 1),
#NotReleased = (SELECT COUNT (Id) FROM PRODUCTS WHERE CategoryId = cat.Id AND ApprovedForRelease = 0),
#Recalled = (SELECT COUNT (Id) FROM PRODUCTS WHERE CategoryId = cat.Id AND ApprovedForRecall= 1),
#NotRecalled = (SELECT COUNT (Id) FROM PRODUCTS WHERE CategoryId = cat.Id AND ApprovedForRecall= 0)
FROM Categories
使用条件聚合:
SELECT c.name as category,
SUM(CASE WHEN p.ApprovedForRelease = 1 THEN 1 ELSE 0 END) as released,
SUM(CASE WHEN p.ApprovedForRelease = 0 THEN 1 ELSE 0 END) as not_released,
SUM(CASE WHEN p.ApprovedForRecall = 1 THEN 1 ELSE 0 END) as recalled,
SUM(CASE WHEN p.ApprovedForRecall = 0 THEN 1 ELSE 0 END) as not_recalled
FROM Categories c LEFT JOIN
Products p
ON p.CategoryId = cat.Id
released.ApprovedForRelease = 1
GROUP BY c.name;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.