CONCAT with IF condition in SQL Server - sql

I have a table with four columns presenting {YES, NO, N/A} values. What I'd like to obtain is a column with concatenated names of those columns which present a 'YES' value separate by a double underscore.
\, A, B, C, D
1, YES, NO, YES, N/A
2, NO, YES, N/A, N/A
3, YES, NO, NO, YES
Expected result:
A__C
B
A__D
Something like:
select CONCAT(
IF(A = 'YES', 'A'),
IF(B = 'YES', 'B'),
IF(C = 'YES', 'C'),
IF(D = 'YES', 'D'))
from my_table

Hope I understand you right, that you want a double underscore separator.
This solution works without any subquery or cte processing.
select substring(
iif(a='YES','__A','') + iif(b='YES','__B','') +
iif(c='YES','__C','') + iif(d='YES','__D','')
,3,100)
from table1
One should know that this: substring('', 3, 100) will work using SqlServer.

Assuming T1 is your table:
SELECT CASE WHEN LEN(X)>0 THEN LEFT(X, LEN(X)-2) ELSE '' END AS Y
FROM (
SELECT
CASE WHEN A='YES' THEN 'A__' ELSE '' END + CASE WHEN B='YES' THEN 'B__' ELSE '' END + CASE WHEN C='YES' THEN 'C__' ELSE '' END + CASE WHEN D='YES' THEN 'D__' ELSE '' END AS X
FROM T1
) A

WITH ABC
as
(
Select
(
CASE WHEN A = 'YES' THEN 'A_' ELSE '' END as A +
CASE WHEN B = 'YES' THEN 'B_' ELSE '' END as B +
CASE WHEN C = 'YES' THEN 'C_' ELSE '' END as C +
CASE WHEN D = 'YES' THEN 'D_' ELSE '' END as D
) as output
)
Select case when len(output) = 2 then left (output,1)
else output
end as output
From ABC

Select case A then 'YES' then 'A' else '_'end + case B then 'YES' then 'B' else '_'end +case C then 'YES' then 'C' else '_'end +case D then 'YES' then 'D' else '_'end as result from my_table

Related

Need help setting a column value in the SQL JOIN

I am using the below code to update column value in the SQL JOIN statement.
CASE when SUBSTRING(m.x1,1,1) = 1 then '1, ' else '' END
+ CASE when SUBSTRING(m.x1,2,1) = 1 then '2, ' else '' END
+ CASE when SUBSTRING(m.x1,3,1) = 1 then '3, ' else '' END
+ CASE when SUBSTRING(m.x1,4,1) = 1 then '4, ' else '' END
+ CASE when SUBSTRING(m.x1,5,1) = 1 then '5, ' else ''
END AS "x1",
For Example, if all the conditions are TRUE within the above CASE statements, the value for x1 will be "1, 2, 3, 4, 5, " but I need the value to be "1, 2, 3, 4, 5". How do I remove the last "Comma delimiter" from the string in the JOIN itself.
Thank you in advance!
Don't put the comma at the end, put it at the start, and then remove the first character. Removing the first character is far easier in SQL Server, as you can use STUFF to remove it STUFF(<String Expression>,1,1,''). As you have a comma (,) and a space (' '), then you need to remove 2 characters, not 1. YOu can also use CONCAT to remove the ELSE '':
SELECT STUFF(CONCAT(CASE SUBSTRING(m.x1,1,1) WHEN 1 then ', 1' END,
CASE SUBSTRING(m.x1,2,1) WHEN 1 then ', 2' END,
CASE SUBSTRING(m.x1,3,1) WHEN 1 then ', 3' END,
CASE SUBSTRING(m.x1,4,1) WHEN 1 then ', 4' END,
CASE SUBSTRING(m.x1,5,1) WHEN 1 then ', 5' END),1,2,'') AS x1
If you're on a more recent version of SQL you can use CONCAT_WS instead:
SELECT CONCAT_WS(' ,',CASE SUBSTRING(m.x1,1,1) WHEN 1 then '1' END,
CASE SUBSTRING(m.x1,2,1) WHEN 1 then '2' END,
CASE SUBSTRING(m.x1,3,1) WHEN 1 then '3' END,
CASE SUBSTRING(m.x1,4,1) WHEN 1 then '4' END,
CASE SUBSTRING(m.x1,5,1) WHEN 1 then '5' END) AS x1
I would recommend concat_ws(): it adds the separator in between its arguments, and, in SQL Server, has the nice feature of ignoring null values; this further simplify the code by avoiding the need of else branches to the case expressions.
concat_ws (',',
case when substring(m.x1,1,1) = 1 then '1' end,
case when substring(m.x1,2,1) = 1 then '2' end,
case when substring(m.x1,3,1) = 1 then '3' end,
case when substring(m.x1,4,1) = 1 then '4' end,
case when substring(m.x1,5,1) = 1 then '5' end,
) as x1
Change it to
CASE when SUBSTRING(m.x1,1,1) = 1 then '1, ' else '' END
+ CASE when SUBSTRING(m.x1,2,1) = 1 then '2, ' else '' END
+ CASE when SUBSTRING(m.x1,3,1) = 1 then '3, ' else '' END
+ CASE when SUBSTRING(m.x1,4,1) = 1 then '4, ' else '' END
+ CASE when SUBSTRING(m.x1,5,1) = 1 then '5' else ''
END AS "x1

Concat String columns in hive

I need to concat 3 columns from my table say a,b,c. If the length of the columns is greater than 0 then I have to concat all 3 columns and store it as another column d in the below format.
1:a2:b3:c
I have tried the following query but I am not sure how to proceed as I am getting null as the result.
select a,b,c,
case when length(a) >0 then '1:'+a else '' end + case when length(b) > 0 then '2:'+b else '' end + case when length(c) > 0 then '3:'+c else '' end AS d
from xyz;
Appreciate the help :)
Use concat() function:
select a,b,c,
concat(
case when length(a)>0 then concat('1:',a) else '' end,
case when length(b)>0 then concat('2:',b) else '' end,
case when length(c)>0 then concat('3:',c) else '' end
) as d
from (--test dataset
select stack(4, 'a','b','c', --all
'','b','c', --one empty
null,'b','c', --null
'','','' --all empty
) as (a,b,c)
)your_data;
Result:
OK
a b c 1:a2:b3:c
b c 2:b3:c
NULL b c 2:b3:c
Time taken: 0.284 seconds, Fetched: 4 row(s) - last one row is empty
As of Hive 2.2.0. you can use || operator instead of concat:
select a,b,c,
case when length(a)>0 then '1:'||a else '' end||
case when length(b)>0 then '2:'||b else '' end||
case when length(c)>0 then '3:'||c else '' end as d

SQL - Query to seperate single column and create new columns based on column data

Sorry, if the title is horrible. Have a table T. With a column Name, Num, and Status that either contains a I, O, or S.
Ex:
Name Num Status
Bob 1 I
Bob 2 O
Bob 3 O
John 4 I
John 5 S
Joe 6 O
Want result to look like:
Name Num I O S
Bob 1 x
Bob 2 x
Bob 3 X
John 4 X
John 5 X
Thanks!
Edit: Follow up question.
Name Num I O S
Bob 1 x
Bob 1 x
Bob 2 X
Need result:
Name Num I O S
Bob 1 X X
Bob 2 X
EDIT 2: Actual Query:
SELECT Name, Card_Nmbr,
[Out] = case when d.Status='I' then 'X' else '' end,
[In] = case when d.Status='O' then 'X' else '' end,
[Sales] = case when d.Status='S' then 'X' else '' end
FROM [PCOdb].[dbo].[GC_Header] as h
INNER JOIN GC_Detail as d on h.GC_TransNmbr = d.GC_TransNmbr
INNER JOIN GC_Master as m on d.GCM_Nmbr = m.GCM_Nmbr
INNER JOIN Galaxy1.dbo.GxUsers as u on h.UserID = u.UserID
WHERE GC_TransDate between '11/29/16' and dateadd(day,1, '11/29/16')
Group BY Card_Nmbr, Name
A simple case statement would help here
Select Name
,Num
,[I] = case when [Status]='I' then 'X' else '' end
,[O] = case when [Status]='O' then 'X' else '' end
,[S] = case when [Status]='S' then 'X' else '' end
From YourTable
EDIT to handle multiple rows
Select Name
,Num
,[I] = max(case when [Status]='I' then 'X' else '' end)
,[O] = max(case when [Status]='O' then 'X' else '' end)
,[S] = max(case when [Status]='S' then 'X' else '' end)
From YourTable
Group By Name,Num
Edit 2 - Full Query (Assuming the Joins are doing what you need)
SELECT Name
,Card_Nmbr
,[Out] = max(case when d.[Status]='I' then 'X' else '' end)
,[In] = max(case when d.[Status]='O' then 'X' else '' end)
,[Sales] = max(case when d.[Status]='S' then 'X' else '' end)
FROM [PCOdb].[dbo].[GC_Header] as h
JOIN GC_Detail as d on h.GC_TransNmbr = d.GC_TransNmbr
JOIN GC_Master as m on d.GCM_Nmbr = m.GCM_Nmbr
JOIN Galaxy1.dbo.GxUsers as u on h.UserID = u.UserID
WHERE GC_TransDate between '2016-11-29' and DateAdd(DD,1,'2016-11-29')
Group BY Card_Nmbr, Name
Use Case expression.
Demo:
Create table #temp
(Name varchar (10),
Num int ,
[Status] char(1))
insert into #temp values ('Bob' , '1' , 'I')
insert into #temp values ('Bob' , '2' , 'O')
insert into #temp values ('Bob' , '3' , 'O')
insert into #temp values ('John' , '4' , 'I')
insert into #temp values ('John' , '5' ,'S')
insert into #temp values ('Joe' , '6' , 'O')
select Name,
Num,
[I] = case
when [Status] ='I'
then 'X'
else ''
end
,[O] = case
when [Status] ='O'
then 'X'
else ''
end
,[S] = case when [Status] ='S'
then 'X'
else ''
end
from #temp
drop table #temp
Result:
For SQL Server 2012 and Later you can use IIF (Transact-SQL) function too.
Select Name
,Num
,IIF([Status] = 'I' , 'X', '' ) AS [I]
,IIF([Status] = 'O' , 'X', '' ) AS [O]
,IIF([Status] = 'S' , 'X', '' ) AS [S]
FROM TableName

Show column names having null values in row

I would like to display only those column name against the student id whose question(q1,q2,q3,q4...etc) value is null below is the printscreen of table against the id i would like to have question id . with below expected o/p
You can use FOR XML to achieve the result:
SQL Fiddle
;WITH Cte AS(
SELECT id, name, q = 'q1' FROM Test WHERE q1 IS NULL UNION ALL
SELECT id, name, q = 'q2' FROM Test WHERE q2 IS NULL UNION ALL
SELECT id, name, q = 'q3' FROM Test WHERE q3 IS NULL UNION ALL
SELECT id, name, q = 'q4' FROM Test WHERE q4 IS NULL UNION ALL
SELECT id, name, q = 'q5' FROM Test WHERE q5 IS NULL UNION ALL
SELECT id, name, q = 'q6' FROM Test WHERE q6 IS NULL
)
SELECT
id,
name,
incompletes = STUFF((
SELECT ',' + c2.q
FROM Cte c2
WHERE
c1.id = c2.id
AND c1.name = c2.name
GROUP BY c2.id, c2.name, c2.q
FOR XML PATH(''), TYPE).value('.', 'varchar(max)')
, 1, 1, '')
FROM Cte c1
GROUP BY c1.id, c1.name
ORDER BY c1.id, c1.name
SELECT ID, NAME,
RTRIM ((CASE WHEN Q1 IS NULL THEN 'Q1,' END)||
(CASE WHEN Q2 IS NULL THEN 'Q2,' END)||
(CASE WHEN Q3 IS NULL THEN 'Q3,' END)||
(CASE WHEN Q4 IS NULL THEN 'Q4,' END)||
(CASE WHEN Q5 IS NULL THEN 'Q5,' END)||
(CASE WHEN Q6 IS NULL THEN 'Q6,' END),',') AS NULL_QUESTIONS
FROM TABLE
EDIT: Added STUFF to get rid of the leading comma and added ELSE '':
SELECT ID, NAME,
STUFF (
CASE WHEN Q1 IS NULL THEN ',q1' ELSE '' END +
CASE WHEN Q2 IS NULL THEN ',q2' ELSE '' END +
CASE WHEN Q3 IS NULL THEN ',q3' ELSE '' END +
CASE WHEN Q4 IS NULL THEN ',q4' ELSE '' END +
CASE WHEN Q5 IS NULL THEN ',q5' ELSE '' END +
CASE WHEN Q6 IS NULL THEN ',q6' ELSE '' END
, 1,1,'') AS NULL_QUESTIONS
FROM Test
SELECT Panelist_ID, EmailAddress collate Latin1_General_CI_AI,
STUFF (
CASE WHEN convert (nvarchar (14), PQ_160175) IS NULL THEN ',PQ_160175' ELSE '' END +
CASE WHEN convert (nvarchar (14), PQ_161979) IS NULL THEN ',PQ_161979' ELSE '' END +
CASE WHEN convert (nvarchar (14), PQ_161980) IS NULL THEN ',PQ_161980' ELSE '' END +
CASE WHEN convert (nvarchar (14), PQ_161981) IS NULL THEN ',PQ_161981' ELSE '' END +
CASE WHEN convert (nvarchar (14), PQ_161982) IS NULL THEN ',PQ_161982' ELSE '' END +
CASE WHEN convert (nvarchar (14), PQ_161983) IS NULL THEN ',PQ_161983' ELSE '' END +
CASE WHEN convert (nvarchar (14), PQ_161986) IS NULL THEN ',PQ_161986' ELSE '' END +
CASE WHEN PQ_172469 IS NULL THEN ',PQ_172469' ELSE '' END +
CASE WHEN PQ_180972 IS NULL THEN ',PQ_180972' ELSE '' END +
CASE WHEN PQ_180973 IS NULL THEN ',PQ_180973' ELSE '' END +
CASE WHEN PQ_189924 IS NULL THEN ',PQ_189924' ELSE '' END +
CASE WHEN PQ_195859 IS NULL THEN ',PQ_195859' ELSE '' END +
CASE WHEN PQ_195860 IS NULL THEN ',PQ_195860' ELSE '' END +
CASE WHEN PQ_196605 IS NULL THEN ',PQ_196605' ELSE '' END +
CASE WHEN PQ_196606 IS NULL THEN ',PQ_196606' ELSE '' )
i have been using the aboce case statement and i am not able to see the output after 161983 nos

MS sql combine columns in select

I am trying to combine multiple columns (varchar, but used to store boolean 'Y' or '') into a single column (list) with human readable text.
The Table layout is like this:
MEMBER_ID (int) | PROC (varchar) | 50K_12_MTHS (varchar) | 100K_12_MTHS (varchar)
1||||
2|Y|Y||
3|Y|Y|Y|
4|Y|||
For the output of the able sample I am trying to get:
1|
2|Proc, 50
3|Proc, 50, 100
4|Proc
I think the way to do this is with a Case (see below) but can't get it to work.
SELECT
MEMBER_ID,
Gorup =
Select(
CASE PROC
WHEN 'Y'
THEN 'Proc'
END + ', ' +
CASE 50K_12_MTHS
WHEN 'Y'
THEN '50K'
END-- + ', ' +
CASE 100K_12_MTHS
WHEN 'Y'
THEN '100K'
END + ', ' +)
from Members
Nearly...!
SELECT
MEMBER_ID,
CASE [PROC]
WHEN 'Y' THEN 'Proc, '
ELSE ''
END +
CASE [50K_12_MTHS]
WHEN 'Y' THEN '50K,'
ELSE ''
END +
CASE [100K_12_MTH]
WHEN 'Y' THEN '100K, '
ELSE ''
END as [group]
from Members
Try this
SELECT
MEMBER_ID,
(CASE [PROC] WHEN 'Y'
THEN 'Proc' ELSE ''
END +
CASE [50K_12_MTHS] WHEN 'Y'
THEN ', 50K' ELSE '' END
+ CASE [100K_12_MTHS] WHEN 'Y'
THEN ', 100K' ELSE ''
END) as [GROUP]
from Members