And condition in Case Statement IN SQL Server - sql

I have the below sql..#FeeType is a parameter of the stored procedure..I am getting a error when I call the below logic..If I remove the and condition and make the logic just
WHEN ''ItemDesc'' THEN ''Item Description1''
then the logic works fine..Can someone please have a look and let me know what I am doing wrong here.
SELECT #FIELDS = (COALESCE(#FIELDS, '' '','''') + ''<td style='' +
''"border:1px solid black;color:white">'' +
(CASE name
WHEN ''ItemDesc'' and '+ #FeeType +' = ''1'' THEN ''Item Description1''
WHEN ''ItemDesc'' and '+ #FeeType +' = ''2'' THEN ''Item Description2''
WHEN ''Units'' THEN ''Units''
WHEN ''Rate'' THEN ''Rate''
WHEN ''Frequency'' THEN ''Frequency''
WHEN ''Annual'' THEN ''Annual''
WHEN ''BasedOn'' THEN ''Based On'' ELSE ''Misc'' END) + ''</td>''
)
FROM tempdb.sys.Columns
WHERE object_id=object_id(''tempdb..#FeesCalculation'')
AND name not like ''CustColHTML_ID''
AND name not like ''ItemID''
Thanks

Because CASE has two different possible syntaxes:
CASE variable WHEN value1 THEN expression2 WHEN value2 THEN expression2 [...] ELSE expression3 END
CASE WHEN condition1 THEN expression1 ELSE expression2 END
The first one is when you simply need to compare the value. If you need any more complex logic you should probably use the second option. In your case it seems you can use a combination of two of the first syntax.
So, what you need to do is:
SELECT #FIELDS = (COALESCE(#FIELDS, '' '','''') + ''<td style='' +
''"border:1px solid black;color:white">'' +
(CASE name
WHEN ''ItemDesc'' THEN CASE #FeeType WHEN ''1'' THEN ''Item Description1'' WHEN ''2'' THEN ''Item Description2'' END
WHEN ''Units'' THEN ''Units''
WHEN ''Rate'' THEN ''Rate''
WHEN ''Frequency'' THEN ''Frequency''
WHEN ''Annual'' THEN ''Annual''
WHEN ''BasedOn'' THEN ''Based On'' ELSE ''Misc'' END) + ''</td>''
)
You will probably need to fix the concatenation and quotes, I removed them for simplicity.

Related

Replace NULL with some other message in pivot query

I want to put 'NA' instead of null in else block.
Any way of doing that ?
select #query = coalesce(#query, '') +
N',max(case when A.[Date] = ''' +
cast(cte.startdate as nvarchar(20)) +
N''' then A.Attendance end) ' +
quotename(convert(char(6), cte.startdate,106))
You would need to do it after the max(). So I think you want:
coalesce(max(case when A.[Date] = #Date then A.Attendance end), 'N/A')
This assumes that Attendance is a string. Otherwise, you have a type error.
I should also note that embedding values in SQL strings is definitely not a good practice. You should be using parameters. In SQL Server, you would do so by using exec sp_executesql rather than just exec.

Fill Variable with Case Statement Results

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'),'')

Printing out list of attribute descriptions based on boolean columns in SQL

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

If statement within switch

I know I'm just thinking of the logic all wrong here but how do I achieve the following:
update #table
set column1 = case
when column1 <> ''
then rtrim(column1) + ', ' + rtrim(column2)--if statement here
else rtrim(column2)
end
from #othertable
I basically want to check if rtrim(column 2) = 'value' then replace it with something else. I understand this is within a switch statement, so how would this be acheived?
update #table
set column1 = case
when column1 <> ''
then rtrim(column1) + ', ' +
case
when column2 = 'value'
then rtrim(column2)
else ...
end
else rtrim(column2)
end
from #othertable
Use a REPLACE within your CASE statement
eg: REPLACE(rtrim(column2),'value','newValue');
Refer MSDN for more details on REPLACE
may be you don't need any switch and if clause:
update #table set column1 = rtrim(isnull(nullif(column1,'') + ', ', '')) + rtrim(column2)

Conditionals in transact-sql select column lists

I've got a query that looks a bit like this:
select
records.id,
contacts.name + ' (' + contacts.organization + ')' as contact,
from records
left join contacts on records.contact = contacts.contactid
Problem is - contacts.organization is frequently empty, and I get contacts like "John Smith ()". Is there a way to only concatenate the organization if it's non-empty?
Use a CASE statement
SELECT
records.id,
CASE contacts.organization
WHEN '' THEN contacts.name
ELSE contacts.name + ' (' + contacts.organization + ')'
END as Contact
FROM records
LEFT JOIN contacts ON records.contact = contacts.contactid
You could modify it to also check for NULL values, but I do not believe you have that issue because if you had a NULL in your contacts.organization, your entire result field would be null instead of blank.
Not sure if this is the best way to do it:
CASE contacts.organization
WHEN '' THEN ''
ELSE '(' + contacts.organzation + ')' END
use a CASE, like CASE WHEN contacts.organization not null then ' (' + c.o + ') ' else '' end
You always need to expect nulls, because of your outer join:
select
records.id,
contacts.name + CASE WHEN contacts.organization IS NULL OR contacts.organization='' THEN '' ELSE ' (' + contacts.organization + ')' END as contact,
from records
left join contacts on records.contact = contacts.contactid
If you're dealing with NULL values there are some functions that specialize in them which are worth knowing.
ISNULL()
COALESCE()
NULLIF()
NULLIF() might be the one you're looking for. It basically takes two params. It returns the first param unless it is NULL, otherwise it returns the second.
Here's what I approximate your code would be:
select
records.id,
contacts.name + ISNULL(' (' + contacts.organization + ')', '') as contact,
from records
left join contacts on records.contact = contacts.contactid
Most NULL-related functions can be replaced by a larger CASE statement. CASE is your more general tool. But using specific functions will make your code cleaner, or at least more terse.