在case语句中计算NULL值

时间:2017-08-18 13:36:37

标签: sql sql-server tsql

我有以下SQL查询:

SELECT jobs.ID,  jobs.title,
SUM(CASE WHEN jobresponses.result = 'true' THEN 1 ELSE 0 END) as True,
SUM(CASE WHEN jobresponses.result = 'false' THEN 1 ELSE 0 END) as False,
SUM(CASE WHEN jobresponses.result != 'true' AND jobresponses.result != 'false' THEN 1 ELSE 0 END) as Incomplete
FROM jobresponses 
JOIN jobs on jobresponses.jobId = jobs.ID
WHERE jobs.ID = 1
GROUP BY jobs.ID, jobs.title

第三种情况表达式实际上使用result NULL来计算值,但要安全(''undefinedNULL之间)我想基本上抓住所有“其他”类型字段。但是,问题是不计算NULL值。请参阅this SQL小提琴。

5 个答案:

答案 0 :(得分:6)

使用IS NULL

SELECT jobs.ID,  jobs.title,
SUM(CASE WHEN jobresponses.result = 'true' THEN 1 ELSE 0 END) as True,
SUM(CASE WHEN jobresponses.result = 'false' THEN 1 ELSE 0 END) as False,
SUM(CASE WHEN jobresponses.result IS NULL                      -- detect NULL
              OR jobresponses.result NOT IN ('true', 'false')  -- other values
   THEN 1 ELSE 0 END) as Incomplete
FROM jobresponses 
JOIN jobs on jobresponses.jobId = jobs.ID
WHERE jobs.ID = 1
GROUP BY jobs.ID, jobs.title;

<强> Rextester Demo

答案 1 :(得分:1)

NULL = NULL评估为NULL,这既不是真也不是假。如果您想要抓住任何不是'true''false'的内容,那么您可以使用

SUM(CASE WHEN (jobresponses.result = 'true' OR jobresponses.result = 'false') THEN 0 ELSE 1 END) as Incomplete

答案 2 :(得分:1)

这样做的一种简单方法可以反转then / else逻辑:

SELECT j.ID,  j.title,
       SUM(CASE WHEN jr.result = 'true' THEN 1 ELSE 0 END) as True,
       SUM(CASE WHEN jr.result = 'false' THEN 1 ELSE 0 END) as False,
       SUM(CASE WHEN jr.result IN ('true', 'false') THEN 0 ELSE 1 END) as Incomplete
FROM jobresponses jr JOIN
     jobs j
     ON jr.jobId = j.ID
WHERE j.ID = 1;
GROUP BY j.ID, j.title

答案 3 :(得分:0)

您可以查询如下:

SELECT jobs.ID,  jobs.title,
SUM(CASE WHEN jobresponses.result = 'true' THEN 1 ELSE 0 END) as True,
SUM(CASE WHEN jobresponses.result = 'false' THEN 1 ELSE 0 END) as False,
SUM(CASE WHEN jobresponses.result is null or ltrim(rtrim(jobresponses)) = '' THEN 1 ELSE 0 END) as Incomplete
FROM jobresponses 
JOIN jobs on jobresponses.jobId = jobs.ID
WHERE jobs.ID = 1
GROUP BY jobs.ID, jobs.title

答案 4 :(得分:0)

不要使用ISNULL()。它会工作,但它是一个T-SQL函数。请改用COALESCE()。它是多平台的。

SUM(CASE WHEN COALESCE(jobresponses.result,'') = 'true' THEN 1 ELSE 0 END) as True,
SUM(CASE WHEN COALESCE(jobresponses.result,'') = 'false' THEN 1 ELSE 0 END) as False,
SUM(CASE WHEN COALESCE(jobresponses.result,'') NOT IN ('true','false') THEN 1 ELSE 0 END) as Incomplete

此外,jobresponses.result的唯一有效值应该是&#39; true&#39;,&#39; false&#39;还是null?如果是这样,您最好将该字段设为bit/Boolean而不是varchar()。它将显着降低存储要求,并且使用起来更容易,更有效。