TSQL CONVERT + CASE functions - sql

I'm running into a problem with my query below. I'm using case to input a value of -- when a field is left blank. I can update the value of -- to 0 instead but i'm still getting an error message when the query executes, I suspect it's because the addition cannot complete with null/blank values.
I'm having the same problem with UPDATE statements.
INSERT:
INSERT INTO AME_GridF18
(SubmissionID,TS_Added,ProjectNumber,ProjectName,TypeofWork,Mile,Toll,Park,MonRT,MonOT,TuesRT,TuesOT,WedsRT,WedsOT,ThursRT,ThursOT,FriRT,FriOT,Saturday,Sunday,Total)
VALUES
(
'[querystring:SubmissionID]'
,'[DateTime:Now]'
,case when '[ProjectNumber]' = '' then '--' else '[ProjectNumber]' end
,case when '[ProjectName]' = '' then '--' else '[ProjectName]' end
,case when '[TypeofWork]' = '' then '--' else '[TypeofWork]' end
,case when '[Mile]' = '' then '--' else '[Mile]' end
,case when '[Toll]' = '' then '--' else '[Toll]' end
,case when '[Park]' = '' then '--' else '[Park]' end
,case when '[MonRT]' = '' then '--' else '[MonRT]' end
,case when '[MonOT]' = '' then '--' else '[MonOT]' end
,case when '[TuesRT]' = '' then '--' else '[TuesRT]' end
,case when '[TuesOT]' = '' then '--' else '[TuesOT]' end
,case when '[WedsRT]' = '' then '--' else '[WedsRT]' end
,case when '[WedsOT]' = '' then '--' else '[WedsOT]' end
,case when '[ThursRT]' = '' then '--' else '[ThursRT]' end
,case when '[ThursOT]' = '' then '--' else '[ThursOT]' end
,case when '[FriRT]' = '' then '--' else '[FriRT]' end
,case when '[FriOT]' = '' then '--' else '[FriOT]' end
,case when '[Saturday]' = '' then '--' else '[Saturday]' end
,case when '[Sunday]' = '' then '--' else '[Sunday]' end
,CONVERT(Varchar, ([MonRT] + [MonOT] + [TuesRT] + [TuesOT] + [WedsRT] + [WedsOT] + [ThursRT] + [ThursOT] + [FriRT] + [FriOT] + [Saturday] + [Sunday])
))
UPDATE:
UPDATE AME_GridF18
SET
SubmissionID = '[querystring:SubmissionID]',
TS_Added = '[DateTime:Now]',
ProjectNumber = '[ProjectNumber]',
ProjectName = '[ProjectName]',
TypeofWork = '[TypeofWork]',
Mile = '[Mile]',
Toll = '[Toll]',
Park = '[Park]',
MonRT = '[MonRT]',
MonOT = '[MonOT]',
TuesRT = '[TuesRT]',
TuesOT = '[TuesOT]',
WedsRT = '[WedsRT]',
WedsOT = '[WedsOT]',
ThursRT = '[ThursRT]',
ThursOT = '[ThursOT]',
FriRT = '[FriRT]',
FriOT = '[FriOT]',
Saturday = '[Saturday]',
Sunday = '[Sunday]',
Total = CONVERT(Varchar, ([MonRT] + [MonOT] + [TuesRT] + [TuesOT] + [WedsRT] + [WedsOT] + [ThursRT] + [ThursOT] + [FriRT] + [FriOT] + [Saturday] + [Sunday]))
WHERE ID = [ID]

Maybe you're trying to do this?
DECLARE
#SubmissionID INT
,#TS_Added SMALLDATETIME
,#ProjectNumber VARCHAR(MAX)
,#ProjectName VARCHAR(MAX)
,#TypeofWork VARCHAR(MAX)
,#Mile FLOAT
,#Toll FLOAT
,#Park FLOAT
,#MonRT FLOAT
,#MonOT FLOAT
,#TuesRT FLOAT
,#TuesOT FLOAT
,#WedsRT FLOAT
,#WedsOT FLOAT
,#ThursRT FLOAT
,#ThursOT FLOAT
,#FriRT FLOAT
,#FriOT FLOAT
,#Saturday FLOAT
,#Sunday FLOAT
,#Total FLOAT
INSERT INTO AME_GridF18
(
SubmissionID
,TS_Added
,ProjectNumber
,ProjectName
,TypeofWork
,Mile
,Toll
,Park
,MonRT
,MonOT
,TuesRT
,TuesOT
,WedsRT
,WedsOT
,ThursRT
,ThursOT
,FriRT
,FriOT
,Saturday
,Sunday
,Total
)
SELECT
#SubmissionID
,GETDATE()
,CASE WHEN ISNULL(#ProjectNumber,'') = '' THEN '--' ELSE #ProjectNumber END
,CASE WHEN ISNULL(#ProjectName,'') = '' THEN '--' ELSE #ProjectName END
,CASE WHEN ISNULL(#TypeofWork,'') = '' THEN '--' ELSE #TypeofWork END
,CASE WHEN ISNULL(#Mile,0) =0 THEN '--' ELSE CAST(#Mile AS VARCHAR(30)) END
,CASE WHEN ISNULL(#Toll,0) = 0 THEN '--' ELSE CAST(#Toll AS VARCHAR(30)) END
,CASE WHEN ISNULL(#Park,0) = 0 THEN '--' ELSE CAST(#Park AS VARCHAR(30)) END
,CASE WHEN ISNULL(#MonRT,0) = 0 THEN '--' ELSE CAST(#MonRT AS VARCHAR(30)) END
,CASE WHEN ISNULL(#MonOT,0) = 0 THEN '--' ELSE CAST(#MonOT AS VARCHAR(30)) END
,CASE WHEN ISNULL(#TuesRT,0) = 0 THEN '--' ELSE CAST(#TuesRT AS VARCHAR(30)) END
,CASE WHEN ISNULL(#TuesOT,0) = 0 THEN '--' ELSE CAST(#TuesOT AS VARCHAR(30)) END
,CASE WHEN ISNULL(#WedsRT,0) = 0 THEN '--' ELSE CAST(#WedsRT AS VARCHAR(30)) END
,CASE WHEN ISNULL(#WedsOT,0) = 0 THEN '--' ELSE CAST(#WedsOT AS VARCHAR(30)) END
,CASE WHEN ISNULL(#ThursRT,0) = 0 THEN '--' ELSE CAST(#ThursRT AS VARCHAR(30)) END
,CASE WHEN ISNULL(#ThursOT,0) = 0 THEN '--' ELSE CAST(#ThursOT AS VARCHAR(30)) END
,CASE WHEN ISNULL(#FriRT,0) = 0 THEN '--' ELSE CAST(#FriRT AS VARCHAR(30)) END
,CASE WHEN ISNULL(#FriOT,0) = 0 THEN '--' ELSE CAST(#FriOT AS VARCHAR(30)) END
,CASE WHEN ISNULL(#Saturday,0) = 0 THEN '--' ELSE CAST(#Saturday AS VARCHAR(30)) END
,CASE WHEN ISNULL(#Sunday,0) = 0 THEN '--' ELSE CAST(#Sunday AS VARCHAR(30)) END
,CAST((#MonRT + #MonOT + #TuesRT + #TuesOT + #WedsRT + #WedsOT + #ThursRT + #ThursOT + #FriRT + #FriOT + #Saturday + #Sunday) AS VARCHAR(MAX))

The reason I used CASE is because if the user did not specify a value for any of the weekdays it needed to result in 0. My problem was during the calculation on INSERT if the user left any inputs blank the SQL would run like: 1+1++1+1 instead of 1+1+0+1+1 and would throw an error.
I ended up switching all my week fields to Integer and setup an auto-calculation on the table itself to calculate the total field and just disregarded that on my INSERT statement, which works as needed.

Related

Concatenation by using CASE statement

I want to CONCAT between this on my SELECT statement in SQL Server.
All the columns are booleans.
The output will be like this if all of columns that are true
GGPNES
I tried to use this and it doesn't work
DECLARE #concat VARCHAR(40) ='';
SELECT
Smoke, Invoice,
Party, Summary,
MySelf, Export,
CASE
WHEN MyTable.Smoke = 1 OR MyTable.Invoice = 1
THEN #concat + 'GG'
WHEN MyTable.Party = 1
THEN #concat + 'P'
WHEN MyTable.Summary = 1
THEN #concat + 'N'
WHEN MyTable.MySelf = 1
THEN #concat + 'E'
WHEN MyTable.Export = 1
THEN #concat + 'S'
END
FROM
MyTable
I think that you want a concatenation of CASE expressions:
CASE WHEN Smoke = 1 OR Invoice = 1 THEN 'GG' ELSE '' END +
CASE WHEN Party = 1 THEN 'P' ELSE '' END +
CASE WHEN Summary = 1 THEN 'N' ELSE '' END +
CASE WHEN MySelf = 1 THEN 'E' ELSE '' END +
CASE WHEN Export = 1 THEN 'S' ELSE '' END

SQL working strange

When I execute this SQL code:
select id, opis, vidrabota, tipprov, hitnost, valuta, drzava, zbirnaprov, tip_zbirprov, kanal
from dev_1450autoebanktip
where opis is null or Opis like case when isnull('','') = '' then Opis else '%' + '' + '%' end
and VidRabota = case when isnull('','') = '' then VidRabota else '' end
and TipProv = case when isnull(0,0) = 0 then TipProv else 0 end
and Valuta = case when isnull('','') = '' then Valuta else '' end
and drzava is null or Drzava = case when isnull('','') = '' then Drzava else '' end
I get this set of results:
But when I add one more condition (last row):
select id, opis, vidrabota, tipprov, hitnost, valuta, drzava, zbirnaprov, tip_zbirprov, kanal
from dev_1450autoebanktip
where opis is null or Opis like case when isnull('','') = '' then Opis else '%' + '' + '%' end
and VidRabota = case when isnull('','') = '' then VidRabota else '' end
and TipProv = case when isnull(0,0) = 0 then TipProv else 0 end
and Valuta = case when isnull('','') = '' then Valuta else '' end
and drzava is null or Drzava = case when isnull('','') = '' then Drzava else '' end
and KANAL = case when isnull(0,0) = 0 then KANAL else 0 end
I am losing one row in the result. What is causing this change?
Kanal is NULL in the last row.
and KANAL = case when isnull(0,0) = 0 then KANAL else 0 end
boils down to
and KANAL = KANAL
But this is not true for NULL, because NULL is the unknown value. When comparing null with null the result is neither true nor false, but unknown. Thus the added criteria dismisses the last record.
There is one thing I'd like to add: Use parentheses when mixing AND and OR. For instance
a = b or a = c and d = e
means
a = b or (a = c and d = e)
because AND has precedence over OR and you may want the expression to mean
(a = b or a = c) and d = e
Use parentheses in order to avoid any mistakes.

Combining SQL string alias into comma delimited string

I am working on this stored proc which check to see which BIT fields are true and depending on it assigns a text to it using alias name. I want to be able to combine these alias values (string) and have it comma delimited to I can display it on my SSRS report.
Below is part of my stored proc.
,CASE
WHEN sr.[ReservationAlreadySentAttached] = 1 THEN 'Reservation Already Sent'
END AS ReservationAttached
,CASE
WHEN sr.[HPOfficeAttached] = 1 THEN 'H&P Office'
END AS HPOfficeAttached
WHEN sr.[NotesAttached] = 1 THEN 'Notes'
END AS NotesAttached
,CASE
WHEN sr.[OpPermitAttached] = 1 THEN 'Op Permit'
END AS OpPermitAttached
,CASE
WHEN sr.[TestResultsAttached] = 1 THEN 'Test Results'
END AS TestResultsAttached
,CASE
WHEN sr.[ConsultationReportsAttached] = 1 THEN 'Consultation Reports'
END AS ConsultationReportsAttached
,CASE
WHEN sr.[OtherAttached] = 1 THEN 'Other'
END AS OtherAttached
so lets say in case where only NotesAttached and ReservationAlreadySentAttached were only true ones then I want the end result to come out as Notes, Reservation Already Sent.
How do i concatenate these aliases ?
Another option is to build your string and then just remove the leading comma with STUFF()
Example (abbreviated)
Declare #YourTable table (ReservationAlreadySentAttached bit,HPOfficeAttached bit,NotesAttached bit)
Insert Into #YourTable values
(1,0,1)
Select NewValue = stuff(
case when ReservationAlreadySentAttached = 1 then ', Reservation Already Sent' else '' end
+case when HPOfficeAttached = 1 then ', H&P Office' else '' end
+case when NotesAttached = 1 then ', Notes' else '' end
,1,2,'')
From #YourTable
Returns
NewValue
Reservation Already Sent, Notes
EDIT - Just the Expression
NewValue = stuff(
case when sr.[ReservationAlreadySentAttached] = 1 then ', Reservation Already Sent' else '' end
+case when sr.[HPOfficeAttached] = 1 then ', H&P Office' else '' end
+case when sr.[NotesAttached] = 1 then ', Notes' else '' end
,1,2,'')
Not the prettiest solution...
RIGHT((CASE
WHEN sr.[ReservationAlreadySentAttached] = 1
THEN ',Reservation Already Sent'
END + CASE
WHEN sr.[HPOfficeAttached] = 1
THEN ',H&P Office'
END + CASE
WHEN sr.[NotesAttached] = 1
THEN ',Notes'
END + CASE
WHEN sr.[OpPermitAttached] = 1
THEN ',Op Permit'
END + CASE
WHEN sr.[TestResultsAttached] = 1
THEN ',Test Results'
END + CASE
WHEN sr.[ConsultationReportsAttached] = 1
THEN ',Consultation Reports'
END + CASE
WHEN sr.[OtherAttached] = 1
THEN ',Other'
END)
,LEN(CASE
WHEN sr.[ReservationAlreadySentAttached] = 1
THEN ',Reservation Already Sent'
END + CASE
WHEN sr.[HPOfficeAttached] = 1
THEN ',H&P Office'
END + CASE
WHEN sr.[NotesAttached] = 1
THEN ',Notes'
END + CASE
WHEN sr.[OpPermitAttached] = 1
THEN ',Op Permit'
END + CASE
WHEN sr.[TestResultsAttached] = 1
THEN ',Test Results'
END + CASE
WHEN sr.[ConsultationReportsAttached] = 1
THEN ',Consultation Reports'
END + CASE
WHEN sr.[OtherAttached] = 1
THEN ',Other'
END) - 1 )
Edit: You may have to take into consideration when NONE of them are 1 so you don't get Invalid length parameter passed to the right function.
CASE
WHEN sr.[ReservationAlreadySentAttached] = 1 THEN ', Reservation Already Sent' ELSE ''
END
+ CASE
WHEN sr.[HPOfficeAttached] = 1 THEN ', H&P Office' ELSE ''
END
+ CASE etc...
And wrap this in some function to remove the first comma + space.

How to count non-null/non-blank values in SQL

I have data like the following:
And what I want is to count the PONo, PartNo, and TrinityID fields with a value in them, and output data like this:
How can I do this counting in SQL?
select
Job_number, Item_code,
case when RTRIM(PONo) = '' or PONo is null then 0 else 1 end +
case when RTRIM(PartNo) = '' or PartNo is null then 0 else 1 end +
case when RTRIM(TrinityID) = '' or TrinityID is null then 0 else 1 end
as [Count]
from YourTable
Try this:
select Job_Number = t.Job_Number ,
Item_Code = t.Item_Code ,
"Count" = sum( case ltrim(rtrim(coalesce( PONo , '' ))) when '' then 0 else 1 end
+ case ltrim(rtrim(coalesce( PartNo , '' ))) when '' then 0 else 1 end
+ case ltrim(rtrim(coalesce( TrinityID , '' ))) when '' then 0 else 1 end
)
from dbo.my_table t
group by t.Job_Number , t.Item_Code
If you want to exclude data where all the tested fields are null or empty, add a having clause:
having sum( case ltrim(rtrim(coalesce( PONo , '' ))) when '' then 0 else 1 end
+ case ltrim(rtrim(coalesce( PartNo , '' ))) when '' then 0 else 1 end
+ case ltrim(rtrim(coalesce( TrinityID , '' ))) when '' then 0 else 1 end
) > 0
Easy!

T SQL Conditional String Concatenation

Have a 5 columns of address data. I need to concatenate these fields into a single address with spaces in between the values if they exist. If the column has a null value I should skip it and not enter any space.
select
case
when street_number != '' THEN (cast(street_number as int))
end as street_number,
case
when street_ext != '' then
case
when street_ext = 50 then '1/2'
end
end as street_ext,
case
when street_direct ! = '' then street_direct
end as street_direct,
case
when site_street ! = '' then site_street
end as site_street,
case
when site_address ! = '' then site_address
end as site_address
from parcel
what I'd like to do is have a variable and assign it to the value of the first column street_number, then when I move on to the next column, street_ext, if it isn't null I'd like to check to see if the variable is null and if not, append a space and the value...and so on down the road.
I'm rusty as hell and could use a push in the right direction.
Thanks everyone.
Use the "+" to concatenate strings in TSQL:
SELECT CASE
WHEN LEN(p.street_number) > 0 THEN p.street_number + ' '
ELSE ''
END +
CASE
WHEN p.street_ext = 50 THEN '1/2'
WHEN LEN(p.street_ext) > 0 THEN ''
ELSE p.street_ext
END + ' ' +
CASE
WHEN LEN(p.street_direct) > 0 THEN p.street_direct + ' '
ELSE ''
END +
CASE
WHEN LEN(p.site_street) > 0 THEN p.site_street + ' '
ELSE ''
END +
CASE
WHEN LEN(p.site_address) > 0 THEN p.site_address + ' '
ELSE ''
END AS full_address
FROM PARCEL p
The LEN function returns zero if the string value is NULL, or a zero length string.
Nested isnulls could do what you need. Something like:
SELECT
ISNULL(streetnumber + ' ', '')
+ ISNULL(streetext + ' ', '')
etc
relying on the fact that NULL + ' ' = NULL.
Something along the lines of:
select coalesce(street_number+' ','')+
coalesce(case when street_ext=50 then '1/2' else null end+' ','')+
coalesce(street_direct+' ','')+
coalesce(site_street+' ','')+
coalesce(site_address,'')
from parcel
I have assumed your data types are all varchar or similar for simplicity. If you are OK with removing any double spaces, how about:
rtrim(ltrim(replace(isnull(street_number) + ' '
+ isnull(street_ext) + ' '
+ isnull(street_direct) + ' '
+ isnull(site_street) + ' '
+ isnull(site_address), ' ', ' ')))
First I would declare the seperator as a variable, because customers are notorious for changing these.
I would do this as follows:
DECLARE #AddressSeperator NVARCHAR(5) = ' '
...and then for the column declation, I'd use the following:
, CONCAT
(
(CASE WHEN LEN(p.street_number) > 0 THEN p.street_number + #AddressSeperator ELSE '' END)
, (CASE WHEN p.street_ext = 50 THEN '1/2' + #AddressSeperator WHEN LEN(p.street_ext) > 0 THEN p.street_ext + #AddressSeperator ELSE '' END)
, (CASE WHEN LEN(p.street_direct) > 0 THEN p.street_direct + #AddressSeperator ELSE '' END)
, (CASE WHEN LEN(p.site_street) > 0 THEN p.site_street + #AddressSeperator ELSE '' END)
, ISNULL(p.site_address, '')
) AS [full_address]