Convert nvarchar to Int using Case When - sql-server

Currently, i'm trying to convert '20190208-10h9m/1/1' to data type int. This string is identified under column String_Value. In addition, I'm pivoting using Case when syntax.
I've tried:
CASE WHEN PTXMEDE.PAT_ID = 'ID_TABLET' TEHN PTXMEDE.STRING_VALUE ELSE 0 END), CAST(PTXMEDE.STRING_VALUE As nvarchar) As ID_TABLET
I get a converting error.
Full syntax below:
Select
PTXMEDE.ME,
(CASE WHEN PTXMEDE.PAT_ID = 'ID_TABLET' THEN PTXMEDE.STRING_VALUE ELSE 0 END),CAST(PTXMEDE.STRING_VALUE As nvarchar) As ID_TABLET,
SUM(CASE WHEN PTXMEDE.PAT_ID = 'Q1_MD' THEN PTXMEDE.NUM_VALUE ELSE 0 END) As Q1_MD,
SUM(CASE WHEN PTXMEDE.PAT_ID = 'Q1_FPROB' THEN PTXMEDE.NUM_VALUE ELSE 0 END) As Q1_FPROB,
SUM(CASE WHEN PTXMEDE.PAT_ID = 'Q1_RESULT' THEN PTXMEDE.NUM_VALUE ELSE 0 END) As Q1_RESULT,
SUM(CASE WHEN PTXMEDE.PAT_ID = 'WEIGHT' THEN PTXMEDE.NUM_VALUE ELSE 0 END) As WEIGHT,
SUM(CASE WHEN PTXMEDE.PAT_ID = 'HARDNESS' THEN PTXMEDE.NUM_VALUE ELSE 0 END) As HARDNESS,
MAX(CASE WHEN PTXMEDE.PAT_ID = 'WEIGHT.T2+' THEN PTXMEDE.NUM_VALUE ELSE 0 END) As WEIGHTT2ULIMIT,
MAX(CASE WHEN PTXMEDE.PAT_ID = 'WEIGHT.T2-' THEN PTXMEDE.NUM_VALUE ELSE 0 END) As WEIGHTT2LLIMIT,
MAX(CASE WHEN PTXMEDE.PAT_ID = 'HARDNESS.T2-' THEN PTXMEDE.NUM_VALUE ELSE 0 END) As HARDNESST2LLIMIT,
MAX(CASE WHEN PTXMEDE.PAT_ID = 'CQA1Quality' THEN PTXMEDE.NUM_VALUE ELSE 0 END) As CQA1Quality,
MAX(CASE WHEN PTXMEDE.PAT_ID = 'CQA2Quality' THEN PTXMEDE.NUM_VALUE ELSE 0 END) As CQA2Quality,
MAX(CASE WHEN PTXMEDE.PAT_ID = 'CQA3Quality' THEN PTXMEDE.NUM_VALUE ELSE 0 END) As CQA2Quality,
PTXMEDE.DATE_LOCAL,
PTXMEDE.SEQUENCE
FROM
PTXMEDE
JOIN PTXMIIF ON
PTXMIIF.ME = PTXMEDE.ME
WHERE
PTXMEDE.ME IN (
SELECT ME FROM PTXME
WHERE CX_STRING_4 = '20190210-6h31m'
AND MT = 'CDC_CU'
)
GROUP By PTXMEDE.ME, PTXMEDE.DATE_LOCAL,PTXMEDE.NUM_VALUE,PTXMEDE.SEQUENCE,PTXMEDE.STRING_VALUE, PTXMEDE.PAT_ID
My Expected result is to be able to list the value under STRING_VALUE Column

All branches of a CASE expression must have the same type in SQL. An "exception" to this would be where they don't have the same type, but the database does some implicit converting to right things (e.g. such as in MySQL). Here is a corrected version of your CASE expression:
CASE WHEN PTXMEDE.PAT_ID = 'ID_TABLET' THEN PTXMEDE.STRING_VALUE ELSE '0' END
This would make the CASE expression output all text. If PTXMEDE.STRING_VALUE could be converted to an integer, then in theory you could also use this:
CASE WHEN PTXMEDE.PAT_ID = 'ID_TABLET' THEN CAST(PTXMEDE.STRING_VALUE AS INT) ELSE 0 END
This would have the CASE expression return an integer value.

Related

Sum of a column in snowflake

I have two calculated columns with case statements. Now, I need to take Sum of those columns and need the difference in it.
For Ex.
Select Case when account = '30' and status='active' then value as value1,
case when account = '31' and status='active' then value as value2,
Sum(value1) - Sum(Value2) as Total_SUM
from table
How can we achieve this.. This gives me a missing group by clause error. I tried many things but did not work out.
Use conditional aggregation and sum the CASE expressions:
SELECT
SUM(CASE WHEN account = '30' THEN value ELSE 0 END) AS value1,
SUM(CASE WHEN account = '31' THEN value ELSE 0 END) AS value2,
SUM(CASE WHEN account = '30' THEN value ELSE 0 END) -
SUM(CASE WHEN account = '31' THEN value ELSE 0 END) AS Total_SUM
FROM yourTable
WHERE status = 'active';

SQL Server PIVOT Function To Switch Rows, Columns

I'm trying to switch rows and columns with PIVOT (or another method). The documentation is pretty confusing to me. Thanks
DECLARE #CallCenterID Int;
DECLARE #BeginDateofReview SmallDateTime;
DECLARE #EndDateofReview SmallDateTime;
SELECT
COUNT(case when Score_Greeting = 'Yes' then Score_Greeting END) AS Score_Greeting_Passed,
SUM(CASE WHEN Score_Greeting IS NOT NULL THEN 1 ELSE 0 END) AS Score_Greeting_Reviewed,
ROUND(CONVERT(decimal(4,1), (COUNT(CASE WHEN Score_Greeting = 'Yes' THEN Score_Greeting END) * 100.0) / NULLIF(SUM(CASE WHEN Score_Greeting IS NOT NULL THEN 1 ELSE 0 END),0),0),0) AS Score_Greeting_PctngPassed,
COUNT(CASE WHEN Score_Authentication = 'Yes' THEN Score_Authentication END) AS Score_Authentication_Passed,
SUM(CASE WHEN Score_Authentication IS NOT NULL THEN 1 ELSE 0 END) AS Score_Authentication_Reviewed,
ROUND(CONVERT(decimal(4,1), (COUNT(CASE WHEN Score_Authentication = 'Yes' THEN Score_Authentication END) * 100.0) / NULLIF(SUM(CASE WHEN Score_Authentication IS NOT NULL THEN 1 ELSE 0 END), 0), 0), 0) AS Score_Authentication_PctngPassed,
FROM
Calls
WHERE
CallCenterID = #CallCenterID AND
(DateofReview >= #BeginDateofReview AND DateofReview <= #EndDateofReview)
Desired results:
Score_Greeting_Passed 5
Score_Greeting_Reviewed 9
Score_Greeting_PctngPassed 56
Score_Authentication_Passed 6
Score_Authentication_Reviewed 9
Score_Authentication_PctngPassed 67
You can use the UNPIVOT operator to transpose the rows and columns. If we assume your query above is stored in #YourData, it's going to be something like:
SELECT
UnpivotedData.ScoreType
, UnpivotedData.ScoreValue
FROM
#YourData
UNPIVOT (ScoreValue FOR ScoreType IN ( [Score_Greeting_Passed], [Score_Greeting_Reviewed], [Score_Greeting_PctngPassed],
[Score_Authentication_Passed], [Score_Authentication_Reviewed], [Score_Authentication_PctngPassed] )) AS UnpivotedData

How To Get Non-Null,Non-0 for Average with SqlServer Select

**Note: I need to go a little further and add NULLIF(0 or 5). I wrote a short post about my answer here:
http://peterkellner.net/2013/10/13/creating-a-compound-nullif-in-avg-function-with-sqlserver/
but am not happy with my solution)
I've got a table with results where attendees type in estimated attendance to a course. If they type 0 or leave it empty, I want ignore that and get the average of values typed in. I can't figure out how to add that constraint to my AVG function without having a where clause for the entire SQL. Is that possible? My code looks like this: (EstimatedNumberAttendees is what I'm going after).
SELECT dbo.SessionEvals.SessionId,
AVG(Cast (dbo.SessionEvals.CourseAsWhole as Float)) AS CourseAsWholeAvg,
COUNT(*),
COUNT(case
when dbo.SessionEvals.InstructorPromptness = 'On Time' then 1
else null
end) AS SpeakerOnTime,
COUNT(case
when dbo.SessionEvals.InstructorPromptness = 'Late' then 1
else null
end) AS SpeakerLate,
COUNT(case
when dbo.SessionEvals.InstructorPromptness = 'NoShow' then 1
else null
end) AS SpeakerNoShow,
COUNT(case
when dbo.SessionEvals.PercentFull = '10% to 90%' then 1
else null
end) AS PercentFull10to90,
COUNT(case
when dbo.SessionEvals.PercentFull = '> 90%' then 1
else null
end) AS PercentFullGreaterThan90,
COUNT(case
when dbo.SessionEvals.PercentFull = ' < 10% Full ' then 1
else null
end) AS PercentFullLessThan10,
AVG(Cast (dbo.SessionEvals.EstimatedNumberAttendees as Float)) AS
EstimatedAttending
FROM dbo.Sessions
INNER JOIN dbo.SessionEvals ON (dbo.Sessions.Id =
dbo.SessionEvals.SessionId)
WHERE dbo.Sessions.CodeCampYearId = 8
GROUP BY dbo.SessionEvals.SessionId
AVG omits NULLs. Therefore make it treat 0s as NULLs. Use NULLIF for that:
...
AVG(NULLIF(Cast (dbo.SessionEvals.CourseAsWhole as Float), 0)) AS CourseAsWholeAvg,
...
AVG(NULLIF(Cast (dbo.SessionEvals.EstimatedNumberAttendees as Float), 0)) AS EstimatedAttending
...
You can try to use an inner query to get the same sessions but exclude zero and null:
SELECT dbo.SessionEvals.SessionId,
(
SELECT AVG(SE1.CourseAsWhole)
FROM dbo.SessionEvals SE1
WHERE SE1.SessionId = dbo.SessionEvals.SessionId
AND ISNULL(SE1.CourseAsWhole, 0) <> 0
) AS CourseAsWholeAvg,
COUNT(*),
COUNT(case
when dbo.SessionEvals.InstructorPromptness = 'On Time' then 1
else null
end) AS SpeakerOnTime,
COUNT(case
when dbo.SessionEvals.InstructorPromptness = 'Late' then 1
else null
end) AS SpeakerLate,
COUNT(case
when dbo.SessionEvals.InstructorPromptness = 'NoShow' then 1
else null
end) AS SpeakerNoShow,
COUNT(case
when dbo.SessionEvals.PercentFull = '10% to 90%' then 1
else null
end) AS PercentFull10to90,
COUNT(case
when dbo.SessionEvals.PercentFull = '> 90%' then 1
else null
end) AS PercentFullGreaterThan90,
COUNT(case
when dbo.SessionEvals.PercentFull = ' < 10% Full ' then 1
else null
end) AS PercentFullLessThan10,
AVG(Cast (dbo.SessionEvals.EstimatedNumberAttendees as Float)) AS
EstimatedAttending
FROM dbo.Sessions
INNER JOIN dbo.SessionEvals ON (dbo.Sessions.Id =
dbo.SessionEvals.SessionId)
WHERE dbo.Sessions.CodeCampYearId = 8
GROUP BY dbo.SessionEvals.SessionId
SQL AVG function will by default ignore null values so you need to only exclude the 0s. Your AVG code can be changed to below:
AVG(nullif( Cast(dbo.SessionEvals.CourseAsWhole as Float), 0) AS CourseAsWholeAvg

Set declaration and use in where clause in SQL Server

I have a SQL statement that has multiple case statements like the below:
SUM(CASE [Type]
WHEN 418
THEN CASE WHEN PMTS.DateCreated BETWEEN #sd AND #ed
AND( PMTS.Amount >0 OR PMTS.Mileage >0)
AND PMTS.PaymentEventID = 0 THEN Mileage END
ELSE 0 END) AS DriverMileage
But I need the result of the sum to set a variable and use that in the where in the WHERE clause.
Example below
DECLARE #contribution decimal
SElECT PMTS.VolunteerId ,
SET #contribution = SUM(CASE [Type]
WHEN 1003
THEN CASE WHEN PMTS.DateCreated BETWEEN #sd AND #ed
AND( PMTS.Amount >0 OR PMTS.Mileage >0)
AND PMTS.PaymentEventID = 0
THEN Amount END
ELSE 0 END) AS GPContributions
FROM PMTS WHERE #contribution >0
Many thanks
I don't think that you need a variable here, also please confirm the "case when" syntax used. Here is a sample query:
select * from
(SElECT PMTS.VolunteerId ,SUM(CASE [Type]
WHEN 1003
THEN CASE WHEN PMTS.DateCreated BETWEEN #sd AND #ed
AND( PMTS.Amount >0 OR PMTS.Mileage >0)
AND PMTS.PaymentEventID = 0
THEN Amount END
ELSE 0 END) AS GPContributions
FROM PMTS)as A WHERE GPContributions >0

group inside sql code rather than in cfoutput

I have a sql-server code of cities as rows and months as columns, there are sums by months but there are no sum by the city_id, I mean I have to count all the sum by city inside the output, and group it by city_id, anyway here is the sql code:
SELECT
SC.CITY_ID,SC.CITY_NAME, DATEPART(MM,I.INVOICE_DATE) AS INVOICE_MONTH,
JAN=SUM(CASE WHEN DATEPART(MM,I.INVOICE_DATE)=1 THEN COALESCE(NETTOTAL,0) ELSE 0 END),
FEB=SUM(CASE WHEN DATEPART(MM,I.INVOICE_DATE)=2 THEN COALESCE(NETTOTAL,0) ELSE 0 END),
MAR=SUM(CASE WHEN DATEPART(MM,I.INVOICE_DATE)=3 THEN COALESCE(NETTOTAL,0) ELSE 0 END),
APR=SUM(CASE WHEN DATEPART(MM,I.INVOICE_DATE)=4 THEN COALESCE(NETTOTAL,0) ELSE 0 END),
MAY=SUM(CASE WHEN DATEPART(MM,I.INVOICE_DATE)=5 THEN COALESCE(NETTOTAL,0) ELSE 0 END),
JUN=SUM(CASE WHEN DATEPART(MM,I.INVOICE_DATE)=6 THEN COALESCE(NETTOTAL,0) ELSE 0 END),
JUL=SUM(CASE WHEN DATEPART(MM,I.INVOICE_DATE)=7 THEN COALESCE(NETTOTAL,0) ELSE 0 END),
AUG=SUM(CASE WHEN DATEPART(MM,I.INVOICE_DATE)=8 THEN COALESCE(NETTOTAL,0) ELSE 0 END),
SEP=SUM(CASE WHEN DATEPART(MM,I.INVOICE_DATE)=9 THEN COALESCE(NETTOTAL,0) ELSE 0 END),
OCT=SUM(CASE WHEN DATEPART(MM,I.INVOICE_DATE)=10 THEN COALESCE(NETTOTAL,0) ELSE 0 END),
NOV=SUM(CASE WHEN DATEPART(MM,I.INVOICE_DATE)=11 THEN COALESCE(NETTOTAL,0) ELSE 0 END),
DEC=SUM(CASE WHEN DATEPART(MM,I.INVOICE_DATE)=12 THEN COALESCE(NETTOTAL,0) ELSE 0 END)
FROM
SETUP_CITY SC
LEFT OUTER JOIN COMPANY C ON C.CITY = SC.CITY_ID
LEFT OUTER JOIN #DSN2_ALIAS#.INVOICE I ON I.COMPANY_ID = C.COMPANY_ID AND I.INVOICE_CAT IN (50,52,53,531,532,56,58,561,54,55,51,63,48) AND I.PURCHASE_SALES = 1
WHERE SC.COUNTRY_ID=1
GROUP BY SC.CITY_ID,SC.CITY_NAME,I.INVOICE_DATE
ORDER BY SC.CITY_ID,SC.CITY_NAME,I.INVOICE_DATE
and output:
<cfoutput query="get_top_sales_TOTAL" group="CITY_ID">
If I don't define the group by city_id, there are multiple rows of one city displayed. How is it possible to group the values (sum up) inside the sql code? So that I won't have to use the group statement inside the cfoutput?
Here is the screenshots to make it more clear, here's the screenshot with defined group="city_id"
If I don't define the group="city_id"
Mark is right about the invoice_month, there is no point for doing this. Your "correct" sql should be
SELECT
SC.CITY_ID,SC.CITY_NAME,
TOTAL=SUM(COALESCE(NETTOTAL,0)),
JAN=SUM(CASE WHEN DATEPART(MM,I.INVOICE_DATE)=1 THEN COALESCE(NETTOTAL,0) ELSE 0 END),
FEB=SUM(CASE WHEN DATEPART(MM,I.INVOICE_DATE)=2 THEN COALESCE(NETTOTAL,0) ELSE 0 END),
MAR=SUM(CASE WHEN DATEPART(MM,I.INVOICE_DATE)=3 THEN COALESCE(NETTOTAL,0) ELSE 0 END),
APR=SUM(CASE WHEN DATEPART(MM,I.INVOICE_DATE)=4 THEN COALESCE(NETTOTAL,0) ELSE 0 END),
MAY=SUM(CASE WHEN DATEPART(MM,I.INVOICE_DATE)=5 THEN COALESCE(NETTOTAL,0) ELSE 0 END),
JUN=SUM(CASE WHEN DATEPART(MM,I.INVOICE_DATE)=6 THEN COALESCE(NETTOTAL,0) ELSE 0 END),
JUL=SUM(CASE WHEN DATEPART(MM,I.INVOICE_DATE)=7 THEN COALESCE(NETTOTAL,0) ELSE 0 END),
AUG=SUM(CASE WHEN DATEPART(MM,I.INVOICE_DATE)=8 THEN COALESCE(NETTOTAL,0) ELSE 0 END),
SEP=SUM(CASE WHEN DATEPART(MM,I.INVOICE_DATE)=9 THEN COALESCE(NETTOTAL,0) ELSE 0 END),
OCT=SUM(CASE WHEN DATEPART(MM,I.INVOICE_DATE)=10 THEN COALESCE(NETTOTAL,0) ELSE 0 END),
NOV=SUM(CASE WHEN DATEPART(MM,I.INVOICE_DATE)=11 THEN COALESCE(NETTOTAL,0) ELSE 0 END),
DEC=SUM(CASE WHEN DATEPART(MM,I.INVOICE_DATE)=12 THEN COALESCE(NETTOTAL,0) ELSE 0 END)
FROM
SETUP_CITY SC
LEFT OUTER JOIN COMPANY C ON C.CITY = SC.CITY_ID
LEFT OUTER JOIN #DSN2_ALIAS#.INVOICE I ON I.COMPANY_ID = C.COMPANY_ID
AND I.INVOICE_CAT IN (50,52,53,531,532,56,58,561,54,55,51,63,48)
AND I.PURCHASE_SALES = 1
WHERE SC.COUNTRY_ID=1
GROUP BY SC.CITY_ID, SC.CITY_NAME
ORDER BY SC.CITY_ID,SC.CITY_NAME
Your problem is that "invoice_date" in the group by and order by are going to produce multiple rows. Try this:
GROUP BY SC.CITY_ID, SC.CITY_NAME, DATEPART(MM,I.INVOICE_DATE)
ORDER BY SC.CITY_ID, SC.CITY_NAME, INVOICE_MONTH
Can't try it so I can't debug it - but basically your GROUP can't have individual items in it that expand the uniqueness of the row (as an "invoice date" would likely do). Good luck!

Resources