SQL计数(如果不为空)

时间:2018-08-19 03:22:18

标签: sql-server

我必须计算某人一个月内租借自行车的次数(仅作为示例),以及该月归还自行车的次数。在我用excel提供的数据表中,该月应该只退回一辆自行车,尽管它的数量为10(我有十行用户数据)。问题在于这些空格被计数并且没有注册为NULL值或''值,因此这些空格在case语句中不起作用。如何格式化一个案例以计算存在实际日期格式值的地方? 到目前为止,这还算是我的要旨(我知道案例陈述是错误的,只是我想做的事情的主意)。

SELECT
DISTINCT MONTH(createddate) AS [Month], 
COUNT(createddate) AS [Renters],
COUNT(CASE WHEN (datereturned) = DATE THEN 1 ELSE 0 END)  AS [Returns])
FROM Bikes WHERE datereturned IS NOT NULL
GROUP BY MONTH(createddate);

它将每月正确返回表中的数字,我可以正确获取每个月的房客数量,但是返回错误。这是应该返回的内容:

月| 4 | 5- 承租人| 5 | 5- 退货| 0 | 1

这就是我的回报(错误):

月| 4 | 5- 承租人| 5 | 5- 退货| 5 | 5

3 个答案:

答案 0 :(得分:1)

使用总和而不是计数

SELECT
 MONTH(createddate) AS [Month], 
COUNT(createddate) AS [Renters],
sum(CASE WHEN (datereturned) = DATE THEN 1 ELSE 0 END)  AS [Returns])
FROM Bikes WHERE datereturned IS NOT NULL
GROUP BY MONTH(createddate);

答案 1 :(得分:0)

COUNT不计算非零值的数量,而是计算非空值的数量。

因此,要获取某些expr为真的行数,可以使用COUNTSUM。下列所有结果均相同:

COUNT(CASE WHEN expr THEN 1 ELSE NULL END)
COUNT(CASE WHEN expr THEN 1 END)
SUM(CASE WHEN expr THEN 1 ELSE 0 END)

通常选择SUM变体,因为它不依赖于特殊的null处理,这常常会使人们感到困惑。


FYI:由于GROUP BY MONTH(createddate)确保每一行都有不同的值,因此DISTINCT毫无意义,只会减慢查询速度。删除它。


  

该月退还自行车多少次

首先,您的查询仅计算退回的自行车(WHERE datereturned IS NOT NULL)。那么最近租来的还没归还的自行车呢?

我不确定(datereturned) = DATE应该测试什么,但是您所说的方式使我们不清楚在7月租用并在8月退货的自行车是否应计入7月或8月的退货。 / p>

如果您在7月进行计数,并且仅在查询中包括退回的自行车,则Returns将始终与Renters相同,因此我假设需要将其计入{ {1}}。

这意味着您的查询需要查看两次该行,一次要在租用的月份计算,一次要在返回的月份计算。为此,您需要August,然后在联合之后的{em>之后进行UNION ALL

GROUP BY

答案 2 :(得分:0)

在您的情况下,您只需要使用最小日期作为比较日期的起点。这将跳过所有NULL和不是实际日期的任何其他值。

因此,您需要做的更改是将IS NOT NULL替换为任何起始日期。例如,这就是我更改的内容:

WHERE datereturned > '1753-01-01'

您可以看到我用'1753-01-01'取代了IS NOT NULL,这是SQL Server中的最小默认日期。案例中的另一件事,如果您使用我的方法,则不需要这种情况。您只需要createddatedatereturned的DISTINCT计数,因此您的最终查询应该类似于以下内容:

SELECT 
    MONTH(createddate) AS [Month], 
    COUNT(DISTINCT createddate)   AS [Renters], 
    COUNT(DISTINCT datereturned)  AS [Returns]
FROM 
    Bikes 
WHERE 
    datereturned > '1753-01-01'
GROUP BY 
    MONTH(createddate)