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
Related
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
For example , I have this table with different column names and the Boolean value below it,
case1 case2 case3 case4
1 0 1 0
What I want to retrieve,only column names with 1 value. So, my desired results from the query should only be case1,case3
Desired Output : case1,case3
there is only one row fetch from sql query
Is there any way?
If I understand correctly, you could use a big case statement:
select stuff(( (case when case1 = 1 then ',case1' else '' end) +
(case when case2 = 1 then ',case2' else '' end) +
(case when case3 = 1 then ',case3' else '' end) +
(case when case4 = 1 then ',case4' else '' end)
), 1, 1, '') as columns
In the case you have multiple rows.
Query
select stuff((
(case when count(*) = sum(cast(case1 as int)) then ',case1' else '' end) +
(case when count(*) = sum(cast(case2 as int)) then ',case2' else '' end) +
(case when count(*) = sum(cast(case3 as int)) then ',case3' else '' end) +
(case when count(*) = sum(cast(case4 as int)) then ',case4' else '' end)), 1, 1, '')
as no_zero_columns
from your_table_name;
SQL Fiddle Demo
I have a questionnaire that my users have filled out (several thousand a day)
The result is each questionnaire record contains 70 something fields (that correspond to each question)
I've been asked to identify all the affirmatives for each of the 70 questions and concatentate them into one field (a summary of all the issues identified for that record).
In other languages (VBA in particular) I would accomlish this by initializing a variable to '', looping through my recordset and setting the variable to what it was previously + the field name of the issue. I'm not sure how to accomplish this in sql.
I've tried...
DECLARE #strFYI AS NVARCHAR
SET #strFYI = ''
SELECT
a.record_num
,CASE
WHEN a.Date_Missing = 'Yes' THEN #strFYI = #strFYI + 'Date_Missing, '
WHEN a.Unclear_Images = 'Yes' THEN #strFYI = #strFYI + 'Unclear_Images, '
WHEN a.Damage = 'Yes' THEN #strFYI = #strFYI + 'Damage, '
ELSE #strFYI
END AS FYI_Reasons
FROM
questionaretable a
But obviously that doesn't work. I'll also need to trim the last comma and space off the list once it's generated, but that shouldn't be a problem... I'm just not sure how to iterate through my records and build this concatenation in tsql :) I'm not even sure (because the syntax is wrong) if the variable would be reset to '' before each record was evaluated!
Can anyone help me out here?
This will be very ugly for 70 columns.
SELECT record_num, LEFT(strFYI, LEN(strFYI) - 2)
FROM (
SELECT
a.record_num,
(CASE WHEN a.Date_Missing = 'Yes' THEN 'Date_Missing, ' ELSE '' END) +
(CASE WHEN a.Unclear_Images = 'Yes' THEN 'Unclear_Images, ' ELSE '' END) +
(CASE WHEN a.Damage = 'Yes' THEN 'Damage, ' ELSE '' END) as strFYI
FROM
questionaretable a
) T
Maybe is cleaner using IIF
IIF ( boolean_expression, true_value, false_value )
SELECT record_num, LEFT(strFYI, LEN(strFYI) - 2)
FROM (
SELECT
a.record_num,
IIF(a.Date_Missing = 'Yes', 'Date_Missing, ' , '' ) +
IIF(a.Unclear_Images = 'Yes', 'Unclear_Images, ', '') +
IIF(a.Damage = 'Yes', 'Damage, ', '') as strFYI
FROM
questionaretable a
) T
As CElliot mention not IIF in 2008 so another solution may be
isnull((select 'Date_Missing, ' where a.Date_Missing = 'Yes'),'')
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
I've got a table with a few boolean columns like: IsProductionWorker, IsMaterialHandler, IsShopSupervisor, etc. A record in this table may have several of these column values as true.
What I would like to do is have a query that returns 1 field with a list of all the attributes that are true, say AttributeList which, if those 3 columns were true would return: "Production Worker, Material Handler, Shop Supervisor".
I can think of a few brute force methods and maybe a more elegant method through the use of a temp-table (I've done similar things before), but I'm curious as to what the best way of doing this would be and if there are any easier implementations.
Thanks.
No elegance is possible, really. Simplicity, yes.
Per row you want to change a flag into a string, for each flag. Not many options for cleverness...
SELECT
SUBSTRING (
CASE WHEN IsProductionWorker = 1 THEN ', Production Worker' ELSE '' END +
CASE WHEN IsMaterialHandler= 1 THEN ', Material Handler' ELSE '' END +
CASE WHEN IsShopSupervisor= 1 THEN ', Shop Supervisor' ELSE '' END +
... ,
3, 8000)
FROM
MyTable
WHERE
...
You can try this.
select CASE WHEN isProductionWorker = 1 THEN 'Production Worker' ELSE '' END
+ CASE WHEN cast(isProductionWorker as int) + isMaterialHandler = 2 THEN ', ' else '' END
+ CASE WHEN isMaterialHandler = 1 THEN 'Material Handler' ELSE '' END
+ CASE WHEN cast(isProductionWorker as int) + isMaterialHandler + isShopSupervisor > 1 THEN ', ' else '' END
+ CASE WHEn isShopSupervisor = 1 THEN 'Shop Supervisor' ELSE '' END AS AttributeList
from MyTable