Reputation: 9229
I have the following SQL Query:
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
The third case expressions is in practice counting values with a result
of NULL
, but to be safe (between ''
, undefined
and NULL
) I wanted to basically have a catch all "other" type field. However, the issue is that the NULL values aren't being counted. See this SQL Fiddle.
Upvotes: 0
Views: 7092
Reputation: 4786
Don't use ISNULL(). It will work, but it is a T-SQL function. Use COALESCE() instead. It's multi-platform.
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
Also, are the only valid values for jobresponses.result
supposed to be 'true', 'false' or null? If so, you'd be better off making that field a bit/Boolean
instead of a varchar()
. It would significantly reduce storage requirements and be a lot easier and more efficient to work with.
Upvotes: 0
Reputation: 1270091
A simple way of doing this reverses the then
/else
logic:
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
Upvotes: 1
Reputation: 175826
Use 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;
Upvotes: 6
Reputation: 152566
NULL = NULL
evaluates to NULL
, which is neither true nor false. If you want to catch anything that's not 'true'
or 'false'
then you can use use
SUM(CASE WHEN (jobresponses.result = 'true' OR jobresponses.result = 'false') THEN 0 ELSE 1 END) as Incomplete
Upvotes: 1
Reputation: 13959
you can query as below:
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
Upvotes: 0