Reputation: 516
I have to distinguish different values in a group, how do I perform that? Example of my table:
Person Status
1 Y
2 N
3 Y
3 N
-If a person only has Y
status then display Yes
-If a person only has N
status then display No
-If a person has both Y
and N
status then display No
Result:
Person Status
1 Yes
2 No
3 No
How do I perform last logic when a person has both status? Here is the statement I tried which worked but I am not 100% sure if it is accurate:
CASE WHEN SUM(CASE WHEN Status = 'Y' THEN 1 ELSE 0 END)>=1 AND SUM(CASE WHEN Status = 'N' THEN 1 ELSE 0 END)>=1 THEN 'No'
WHEN SUM(CASE WHEN Status = 'Y' THEN 1 ELSE 0 END)>=1 THEN 'Yes'
ELSE 'No'END
Upvotes: 0
Views: 498
Reputation: 5232
For simplicity let's say that:
(Y) -> SUM(CASE WHEN Status = 'Y' THEN 1 ELSE 0 END)
(N) -> SUM(CASE WHEN Status = 'N' THEN 1 ELSE 0 END)
So your query can be written as pseudocode:
case when (Y)>=1 and (N)>=1 then 'No'
when (Y)>=1 then 'Yes'
else 'No'
end
To check if your query is correct You need to build a truth table from your query for all possible input:
(Y) | (N) (Y)>=1 | (N)>=1 (Y)>=1 and (N)>=1 Result
----------- ----------------- ------------------- --------
0 | 0 false | false false 'No'
0 | >=1 => false | true => false => 'No'
>=1 | 0 true | false false 'Yes'
>=1 | >=1 true | true true 'No'
Look's like You got it right!
To be sure if You are making your condition correctly You need to build a truth table:
(1)
Yes | No | Result
-------------------------------
found | found | No
not found | found | No
found | not found | Yes
not found | not found | Null
or
(2)
\ No
Yes \ Found | Not Found |
-------------------------------
Found | No | Yes |
-------------------------------
Not Found | No | Null |
------------------------------
The first thing to notice is that if status==No is found the result is always No.
Only when a No is not found and a Yes is found then we return Yes.
So Your condition can be written with a nested case.
select columns, ....
(
case when (SUM(CASE WHEN Status = 'N' THEN 1 ELSE 0 END)>=1) then 'No'
else case when (SUM(CASE WHEN Status = 'Y' THEN 1 ELSE 0 END)>=1) then 'Yes'
else NULL
end
end
) as result
It's easy with 2 variables in a condition.
If You have more variables then I suggest You look into a Karnaugh map
Another answer here gave an original solution:
select CASE WHEN MIN(status) = 'Y' THEN 'Yes' ELSE 'No' END
, Person
from table
group by Person
Is it correct?
Let's check first all the possible input.
Input:
{Y} - contains only Y in the column
{N} - contains only N in the column
{Y,N} - contains Y and N in the column
{} - Y and N do not appear in the column
Let's calculate all the possible results:
Input MIN(status) Result
------- ------------- --------
{Y} Y Yes
{N} => N => No
{Y,N} N No
{} NULL No
It's a correct answer.
Upvotes: 0
Reputation: 8584
You can use MIN:
select CASE WHEN MIN(status) = 'Y' THEN 'Yes' ELSE 'No' END
, Person
from table
group by Person
Upvotes: 1