当EXISTS()子查询为false时,获取COUNT以返回0

时间:2011-07-20 10:12:50

标签: sql

给出以下查询:

SELECT M.year, COUNT(C.eid)
  FROM Card AS C, Month AS M
  WHERE EXISTS(SELECT 1 FROM Charge AS CH
               WHERE CH.usingcard=C.eid AND CH.year=M.year)
  GROUP BY M.year

其中EXISTS用于避免匹配给定年份/卡的“费用”数量更改计数。 pb是我想为每个可能的'Month'行生成一行,例如,当没有匹配的'Charge'时,我想得到0作为计数,而我目前根本没有行。

没有EXISTS,我可以使用外连接。对于NOT EXISTS()。

的情况,我也可以使用一个UNION,其查询返回0

任何人都有更聪明的主意吗?

4 个答案:

答案 0 :(得分:2)

这可以避免多个Charge记录的问题:

SELECT M.year, COUNT(distinct CH.usingcard)
FROM Card AS C
CROSS JOIN Month AS M
LEFT JOIN Charge CH on CH.usingcard=C.eid AND CH.year=M.year
GROUP BY M.year

这计算了年内不同卡的收费方式。非连接行的CH.usingcard为null,不计算在内。

答案 1 :(得分:1)

NOT EXISTS排除零计数:正如预期的那样

如果您想要零计数,那么您需要OUTER JOIN。但是,你的FROM子句是一个CROSS JOIN,所以你得错了。你可以忽略Card表,因为usingcard有相同的数据(否则你不会在你的EXISTS中使用它)

就是这么简单......

SELECT
    M.year, COUNT(CH.usingcard)
FROM
    Month AS M
    LEFT JOIN
    Charge AS CH On CH.year = M.year
GROUP BY
    M.year

答案 2 :(得分:-1)

如果所有参数都为NULL,则COALESCE返回NULL。

COALESCE(expression1,...n) is equivalent to the following CASE expression:

CASE

   WHEN (expression1 IS NOT NULL) THEN expression1

   WHEN (expression2 IS NOT NULL) THEN expression2

   ...

   ELSE expressionN

END 

以下示例显示了COALESCE如何从第一列中选​​择具有非空值的数据。

SELECT Name, Class, Color, ProductNumber,
COALESCE(Class, Color, ProductNumber) AS FirstNotNull
FROM Production.Product ;

答案 3 :(得分:-1)

你可以使用NULLIF函数,它可以在count函数中使用。此函数有两个参数:如果参数相等,则返回null,否则返回第一个参数的值。

SELECT M.year, COUNT (NULLIF (CH.usingcard, NULL))
FROM Month as M left join Charge as CH
ON CH.Year = M.Year
GROUP BY M.year