case statement to find one value - sql

I'm trying to show one row per id but it is returning three.
If the id has a 'y' then it should show a 'y'.
If it shows a 'y' and 'r' it should be 'y'.
If it has 'y', 'r', 'n' it should be 'y'.
If it is just id and 'r' it should be 'r' and id and just 'n' then 'n'.
I can't seem to get it to work using a case statement. Any ideas? Thanks.
I've tried this:
,CASE WHEN result = 'Y' THEN 'Y'
WHEN result = 'Y' AND result = 'R') THEN 'Y'
WHEN result = 'R' THEN 'R'
ELSE 'N' END AS CARE_PLAN
What it is returning:
ID result
3434 'y'
3434 'r'
3434 'n'

You can use Listagg function,
Writing a subquery and DISTINCT then use Listagg function.
SELECT id, Listagg (result, ', ')
within GROUP (ORDER BY result) as CARE_PLAN
FROM (SELECT DISTINCT id,
( CASE
WHEN result = 'Y' THEN 'Y'
WHEN result = 'Y'
AND result = 'R' THEN 'Y'
WHEN result = 'R' THEN 'R'
ELSE 'N'
END ) AS result
FROM t) T
GROUP BY id
sqlfiddle:http://sqlfiddle.com/#!4/02cd5/2
[Results]:
| ID | CARE_PLAN |
|------|-----------|
| 1234 | N, R, Y |

It shall be proper to use ASCII and CHR functions for your case instead of using CASE .. WHEN, as in the following :
SELECT ID, CHR(MAX(ASCII(result))) AS CARE_PLAN
FROM TAB
GROUP BY ID
ORDER BY ID;
SQL Fiddle Demo

You would seem to want aggregation with some conditional logic:
select id,
(case when sum(case when result = 'y' then 1 else 0 end) > 0 then 'y'
when sum(case when result = 'r' then 1 else 0 end) > 0 then 'r'
when min(result) = max(result) and min(result) = 'n' then 'n'
else '?'
end) as new_result
from t
group by id;
If there are only those three values, then perhaps this simplified logic works:
select id, max(result) as new_result
from t
group by id;

Related

Is there a way to contruct this kind of result using group by in sql?

I have a table which consists of data where in I'm having trouble counting the corresponding rows.
Here is the sample table:
I am expecting an output like this:
You can do conditional aggregation:
select
sum(case when result = 'X' then 1 else 0 end) count_x,
sum(case when result is null then 1 else 0 end) count_blank
from mytable
I assume that by blank you mean null. If not, then you can change the condition in the second sum() from result is null to result = ''.
If you are running MySQL, this can be shortened a little:
select
sum(result = 'X') count_x,
sum(result is null) count_blank
from mytable

Ignore else from CASE in SQL

Is there a way to avoid the else part when CASE is used ? For example below is the case STATUS column should display only A or B and there should not any NULL
(CASE
WHEN …..
THEN 'A'
WHEN …
THEN 'B'
END) as STATUS
Something like this:
SELECT *
FROM
(
SELECT
--ORIGINAL COLUMNS / EXPRESSIONS
, (CASE
WHEN ... THEN 'A'
WHEN ... THEN 'B'
END) as STATUS
FROM ...
)
WHERE STATUS IS NOT NULL

counting records on the same table with different values possibly none sql server 2008

I have a inventory table with a condition i.e. new, used, other, and i am query a small set of this data, and there is a possibility that all the record set contains only 1 or all the conditions. I tried using a case statement, but if one of the conditions isn't found nothing for that condition returned, and I need it to return 0
This is what I've tried so far:
select(
case
when new_used = 'N' then 'new'
when new_used = 'U' then 'used'
when new_used = 'O' then 'other'
end
)as conditions,
count(*) as count
from myDB
where something = something
group by(
case
when New_Used = 'N' then 'new'
when New_Used = 'U' then 'used'
when New_Used = 'O' then 'other'
end
)
This returns the data like:
conditions | count
------------------
new 10
used 45
I am trying to get the data to return like the following:
conditions | count
------------------
new | 10
used | 45
other | 0
Thanks in advance
;WITH constants(letter,word) AS
(
SELECT l,w FROM (VALUES('N','new'),('U','used'),('O','other')) AS x(l,w)
)
SELECT
conditions = c.word,
[count] = COUNT(x.new_used)
FROM constants AS c
LEFT OUTER JOIN dbo.myDB AS x
ON c.letter = x.new_used
AND something = something
GROUP BY c.word;
try this -
DECLARE #t TABLE (new_used CHAR(1))
INSERT INTO #t (new_used)
SELECT t = 'N'
UNION ALL
SELECT 'N'
UNION ALL
SELECT 'U'
SELECT conditions, ISNULL(r.cnt, 0) AS [count]
FROM (
VALUES('U', 'used'), ('N', 'new'), ('O', 'other')
) t(c, conditions)
LEFT JOIN (
SELECT new_used, COUNT(1) AS cnt
FROM #t
--WHERE something = something
GROUP BY new_used
) r ON r.new_used = t.c
in output -
new 2
used 1
other 0
You can do it as a cross-tab:
select
sum(case when new_used = 'N' then 1 else 0 end) as N,
sum(case when new_used = 'U' then 1 else 0 end) as U,
sum(case when new_used = 'O' then 1 else 0 end) as Other
from myDB
where something = something

T-SQL IF-ELSE

Is it possible to do something like this with IF-ELSE, or something similar:
SELECT
MemberID,
ProfileTypeID
PrCountryID, -- 3
PrStateID, -- 4
PrStateInt
FROM Member
WHERE PrCity IS NOT NULL
IF #ShowUnclaimed = 'N'
AND Claimed = 'Y'
AND SBIcon = 'N'
END
AND Viewable = 'Y'
AND SystemID = 2
Many thanks in advance for any information.
neojakey
No need to use Case for this one
SELECT
MemberID,
ProfileTypeID
PrCountryID, -- 3
PrStateID, -- 4
PrStateInt
FROM Member
WHERE PrCity IS NOT NULL
AND Viewable = 'Y'
AND SystemID = 2
AND ( #ShowUnclaimed != 'N'
OR ( Clamed = 'Y' AND SBIcon = 'N' )
)
You're looking for the case expression (MSDN)
SELECT MemberID,
ProfileTypeID
PrCountryID, -- 3
PrStateID, -- 4
PrStateInt
FROM Member
WHERE PrCity IS NOT NULL
AND CASE
WHEN #ShowUnclaimed = 'N' AND Claimed = 'Y' AND SBIcon = 'N' THEN 1
END = 1
AND Viewable = 'Y'
AND SystemID = 2
If I understand your intention correctly there is no need for IF, or CASE for that matter.
Just something like this seems to be what you were trying to do...?
WHERE PrCity IS NOT NULL
AND (#ShowUnclaimed = 'Y'
OR (Claimed = 'Y'
AND SBIcon = 'N'))
AND Viewable = 'Y'
AND SystemID = 2
Give this a try using CASE:
SELECT
MemberID,
ProfileTypeID
PrCountryID, -- 3
PrStateID, -- 4
PrStateInt
FROM Member
WHERE PrCity IS NOT NULL
AND Viewable = 'Y'
AND SystemID = 2
AND Claimed = CASE WHEN #ShowUnclaimed = 'N' THEN 'Y' ELSE Claimed END
AND SBIcon = CASE WHEN #ShowUnclaimed = 'N' THEN 'N' ELSE SBIcon END
This is just one way to do it. Best of luck.

Case statement problem to show values without null in a row

select CASE WHEN ( rtt.us_code = 's' )
THEN rtt.name
ELSE '' END AS input_tax_name,
CASE WHEN ( rtt2.us_code = 'r')
THEN rtt2.name
ELSE '' END AS output_tax_name,
CASE WHEN ( rtt.us_code = 's' )
THEN rtt.acc_id
ELSE 0 END AS input_tax_rate,
CASE WHEN ( rtt2.us_code = 'r')
THEN rtt2.acc_id
ELSE 0 END AS output_tax_rate
from supplier_item si
JOIN ret_tx_type rtt
ON si.ret_tx_type_id = rtt.ret_tx_type_id
JOIN ret_tx_type rtt2
ON si.ret_tx_type_id = rtt2.ret_tx_type_id
where si.ret_tx_type_id is not null
I am trying to display input and output tax in the same row for a report depends on us_code is 'r' and 's'.
But i am getting the results like
if input tax is there ...output tax column will be null
if output tax is there ...input tax column will be null
i am want to get the both in same row and no need to make null in any rows
please help
SELECT
MAX(CASE rtt.us_code WHEN 's' THEN rtt.name END) AS input_tax_name,
MAX(CASE rtt.us_code WHEN 'r' THEN rtt.name END) AS output_tax_name,
MAX(CASE rtt.us_code WHEN 's' THEN rtt.acc_id END) AS input_tax_rate,
MAX(CASE rtt.us_code WHEN 'r' THEN rtt.acc_id END) AS output_tax_rate
FROM supplier_item si
INNER JOIN ret_tx_type rtt
ON si.ret_tx_type_id = rtt.ret_tx_type_id
GROUP BY ??? /* here you should supply a column,
presumably in 'si', that is common
to both of the related 'r'- and
's'-tax records */
You need to add a GROUP BY to your query on something (possibly GROUP BY si.id?)
And put the CASE statements into aggregates. e.g.
MAX(CASE WHEN ( rtt2.us_code = 'r')
THEN rtt2.acc_id
ELSE 0 END)