我有一个发布文章的网站,并为某些文章分配了位置和个人资料,因此只有该位置和相关个人资料中的人才能看到它。
我有一个查询,它返回分配到该位置的文章的位置和数量
SELECT locations.id, locations.location, COUNT( DISTINCT article.id) AS Number
FROM ar.locations
JOIN ar.articleLocation
ON articleLocation.locationId = locations.id
JOIN ar.article
ON article.id=articleLocation.articleId
JOIN ar.articleProfile
ON article.id = articleProfile.articleId
WHERE article.createDate >= '2013-11-30'
AND article.startDate <= '2014-05-30'
AND articleProfile.profileId
IN ('1000000410','1000000408','1000000393')
AND articleLocation.locationId IN ('250','194','195','204','281')
GROUP BY locations.id, locations.location
ORDER BY locations.location
返回结果
id location Number
194 LocationA 1
250 LocationB 16
281 LocationC 2
但是在查询中还有2个其他位置ID,并且因为没有为这些位置分配文章,所以没有为这些IDS返回任何内容
理想情况下我想要
id location Number
194 LocationA 1
250 LocationB 16
281 LocationC 2
204 LocationD 0
195 LocationE 0
如果该位置没有文章,我似乎无法弄清楚如何带回0。 任何正确方向的帮助/指针都将非常感激。如果有更有效/更好的方式来做我目前正在做的事情,我也不仅仅接受建议。
答案 0 :(得分:5)
您可以使用LEFT JOIN
来实现此目的,如下所示。括号未正确定位,已在下面更正。
SELECT locations.id, locations.location, COALESCE(COUNT( DISTINCT article.id), 0) AS Number
FROM ar.locations
JOIN ar.articleLocation
ON articleLocation.locationId = locations.id
LEFT JOIN
(SELECT article.* FROM ar.article
JOIN ar.articleProfile
ON article.id = articleProfile.articleId
WHERE article.createDate >= '2013-11-30'
AND article.startDate <= '2014-05-30'
AND articleProfile.profileId
IN ('1000000410','1000000408','1000000393')
) article
ON article.id=articleLocation.articleId
WHERE articleLocation.locationId IN ('250','194','195','204','281')
GROUP BY locations.id, locations.location
ORDER BY locations.location;
如果没有记录(而不是返回NULL),COALESCE函数将打印0。
<强>参考强>:
答案 1 :(得分:1)
在文章表格上使用左连接。 这会将NULL添加到您希望看到0的行中。并且要看到0,只需要ISNULL(0,)
答案 2 :(得分:0)
您需要将除locations
表之外的所有表的条件移动到on
子句中。这些将您的外部联接转变为内部联接:
SELECT l.id, l.location, COUNT( DISTINCT a.id) AS Number
FROM ar.locations l LEFT JOIN
ar.articleLocation al
ON al.locationId = l.id LEFT JOIN
ar.article a
ON a.id = al.articleId AND
a.createDate >= '2013-11-30' AND
a.startDate <= '2014-05-30' LEFT JOIN
ar.articleProfile ap
ON a.id = ap.articleId AND
ap.profileId IN ('1000000410', '1000000408', '1000000393')
WHERE l.locationId IN ('250', '194', '195', '204', '281')
GROUP BY l.id, l.location
ORDER BY l.location;
一些注意事项:
where
子句确实包含对第一个表的过滤。将其移至on
子句不会做正确的事。where
子句使用location
而不是articlelocation
。on
条款中。count(a.id)
会与count(distinct a.id)
做同样的事情。