Call an alias in a case expression - sql

I have this code that is to check each month to see if the person is enrolled in that month and at the end it is suppose to tell you if the person was enrolled for the whole year or not. The Annual is to check each month to see if they have a 1 from the case expression. The issue is I can't get SQL to recognize the alias names like Jan and Feb
Select SSN, FirstName, LastName,
Case (DateEnrolled > '1-1-2019' and DateEnrolled < '1-31-2019' ) then 1 else 0 as [Jan],
Case (DateEnrolled > '2-1-2019' and DateEnrolled < '2-28-2019') then 1 else 0 as [Feb],
...
Case (Jan = 1 AND Feb = 1 AND...) then 1 else 0 as [Annual]
from EmployeePerson

Try this:
with cte as
(
Select SSN, FirstName, LastName,
Case (DateEnrolled > '1-1-2019' and DateEnrolled < '1-31-2019' ) then 1 else 0 end as [Jan],
Case (DateEnrolled > '2-1-2019' and DateEnrolled < '2-28-2019') then 1 else 0 end as [Feb],
...
from EmployeePerson
)
select SSN, FirstName, LastName, [Jan], [Feb]...,[Dec],
Case (Jan = 1 AND Feb = 1 AND...AND [Dec] = 1) then 1 else 0 end as [Annual]
from cte

Try this !
SELECT SSN, FirstName, LastName,
CASE WHEN (DateEnrolled > '01-01-2019' AND DateEnrolled < '01-31-2019') THEN 'Jan',
CASE WHEN (DateEnrolled > '02-01-2019' AND DateEnrolled < '02-28-2019') THEN 'Feb'
END AS 'Annual'
FROM EmployeePerson;
I think it will be helpful.

try
select SSN, FirstName,
Case when Jan is null then 0 else 1 end as Jan,
Case when Feb is null then 0 else 1 end as Feb,
Case when Mar is null then 0 else 1 end as Mar,
Case when Apr is null then 0 else 1 end as Apr,
Case when May is null then 0 else 1 end as May,
Case when Jun is null then 0 else 1 end as Jun,
Case when Jul is null then 0 else 1 end as Jul,
Case when Aug is null then 0 else 1 end as Aug,
Case when Sep is null then 0 else 1 end as Sep,
Case when Oct is null then 0 else 1 end as Oct,
Case when Nov is null then 0 else 1 end as Nov,
Case when [Dec] is null then 0 else 1 end as [Dec],
Case when ([Jan] is not null AND [Feb] is not null AND [Mar] is not null AND
[Apr] is not null AND [May] is not null AND [Jun] is not null AND
[Jul] is not null AND [Aug] is not null AND [Sep] is not null AND
[Oct] is not null AND [Nov] is not null AND [Dec] is not null) then 1 else 0 end as Annual
from(
Select SSN, FirstName, format(DateEnrolled, 'MMM') Enrolled
from EmployeePerson)aa
pivot (max(Enrolled) for Enrolled in([Jan], [Feb], [Mar], [Apr], [May], [Jun], [Jul], [Aug], [Sep], [Oct], [Nov], [Dec])) as dtl

Related

SQL Pivot table not returining expected results

This is the first time I have had to use a SQL pivot table, so I'm not very proficient in getting results with the method, my pivot table is not returning the results I expected and I don't know why...
Here is my instruction:
"Create a sql that will show the total number create [ddateCreated] of patients per branch for each month for 2020 - 2021.
Display Required fields BranchName , Year , Jan , Feb, Mar, Apr, May , Jun , Jul ,Aug , Sept , Oct , Nov , Dec."
so I came up with the below query:
select * from (
select datename(month, b.dDateCreated) as [Month] ,
sName as BranchName ,
datename(Year, b.dDateCreated) as [Year],
p.ipkPatientID from Branch b
inner join Patients p
on p.ifkBranchID=b.ipkBranchID
where (b.dDateCreated BETWEEN '2020-01-01 00:00:00.000'AND '2021-12-31 23:59:59.999')
) as Src
pivot(
count(ipkPatientID)
for [Month] in ([Jan],
[Feb],
[Mar],
[Apr],
[May],
[Jun],
[Jul],
[Aug],
[Sept],
[Oct],
[Nov],
[Dec])
) as Pivot_Table
Here are the results:
BranchName Year Jan Feb Mar Apr May Jun Jul Aug Sept Oct Nov Dec
Cdldttd dd Fhdftwt wndfplpgy 2020 0 0 0 0 0 0 0 0 0 0 0 0
Ddjdlppmdnt 2020 0 0 0 0 14 0 0 0 0 0 0 0
Ddpn Cdhpnfp 2020 0 0 0 0 0 0 0 0 0 0 0 0
dlmfdn Lpnw Lfchtdnwnhg 2020 0 0 0 0 0 0 0 0 0 0 0 0
dlmfdn Lpnw Mwffkdng 2020 0 0 0 0 0 0 0 0 0 0 0 0
Dnhwwnjflld 2020 0 0 0 0 0 0 0 0 0 0 0 0
dthpwd 2020 0 0 0 0 0 0 0 0 0 0 0 0
fnc and wttpcfwtdt 2020 0 0 0 0 5 0 0 0 0 0 0 0
Fwdhfd Gldn 2020 0 0 0 0 0 0 0 0 0 0 0 0
Hdwhdwt pfffcd 2020 0 0 0 0 0 0 0 0 0 0 0 0
Hpmd jftft 2020 0 0 0 0 91 0 0 0 0 0 0 0
I can't understand why it shows 0's everywhere? i have tried to refactor this query mulptiple times but I cant come right... Also note how there is little data in the Month of May, for some odd reason.
Look at the below query, which is the source of the pivot table:
select datename(month, b.dDateCreated) as [Month] ,
sName as BranchName ,
datename(Year, b.dDateCreated) as [Year],
p.ipkPatientID from Branch b
inner join Patients p
on p.ifkBranchID=b.ipkBranchID
where (b.dDateCreated BETWEEN '2020-01-01 00:00:00.000'AND '2021-12-31 23:59:59.999')
These results look correct?
and there is data for every month... So how would I count the patient id's for every month and display it?
Pretty sure this will correct your issue
Select *
From (
select left(datename(month, b.dDateCreated),3) as [Month] , -- Notice Jan,Feb,Mar
sName as BranchName ,
datename(Year, b.dDateCreated) as [Year],
p.ipkPatientID
from Branch b
inner join Patients p on p.ifkBranchID=b.ipkBranchID
where b.dDateCreated BETWEEN '2020-01-01 00:00:00.000'AND '2021-12-31 23:59:59.997'
) as Src
Pivot( count(ipkPatientID) for [Month] in ([Jan],
[Feb],
[Mar],
[Apr],
[May],
[Jun],
[Jul],
[Aug],
[Sep], -- Notice Sep not Sept
[Oct],
[Nov],
[Dec] ) ) as Pivot_Table
I would recommend pivoting with conditional aggregation rather than using the vendor-specific pivot query. I find that the pivot syntax is less intuitive ; it is also less flexible, and of course not easily portable across databases.
Using conditional aggregation, and starting from your existing working query, you would pivot like so:
select b.sName as BranchName, x.[Year],
sum(case when x.[Month] = 'Jan' then 1 else 0 end) as Jan
sum(case when x.[Month] = 'Feb' then 1 else 0 end) as Feb
-- ... repeat for the following months...
sum(case when x.[Month] = 'Dec' then 1 else 0 end) as Dec
from Branch b
inner join Patients p on p.ifkBranchID = b.ipkBranchID
cross apply ( values (datename(year, b.dDateCreated), datename(month, b.dDateCreated) ) d([Month], [Year])
where b.dDateCreated >= '2020-01-01' and b.dDateCreated < '2022-01-01'
group by b.ifkBranchID, b.sName, x.[Year]
Side notes:
filtering dates is often simpler than with half-open intervals than with between
you probably want to group by the primary key of the branch table (which I assumed is ifkBranchID) ; different branches may have the same name.
I used outer apply to compute the datenames just once rather than repeating the expressions all over the queqry
it is good practice to prefix all columns in the query with the table they belong to

How pivot month name in SQL Server after a date

I have a table in SQL Server with these columns:
id int pk
date datetime
value numeric
This is my select query
SELECT
O.Date AS DATE,
O.Value AS VALUE
FROM
Orders O
WHERE
YEAR(Date) = #Year
and this is my data
I want this output:
JAN FEB MAR APR MAY JUNE JULY AUG SEPT OCT NOV DEC
-----------------------------------------------------------------------
600 1200 600 600 0 0 0 0 0 0 0 0
Doesn't need a subquery. Something like this should work
select sum(case when dt.mo=1 then o.[Value] else 0 end) 'Jan',
sum(case when dt.mo=2 then o.[Value] else 0 end) 'Feb',
sum(case when dt.mo=3 then o.[Value] else 0 end) 'Mar',
sum(case when dt.mo=4 then o.[Value] else 0 end) 'Apr',
sum(case when dt.mo=5 then o.[Value] else 0 end) 'May',
sum(case when dt.mo=6 then o.[Value] else 0 end) 'Jun',
sum(case when dt.mo=7 then o.[Value] else 0 end) 'Jul',
sum(case when dt.mo=8 then o.[Value] else 0 end) 'Aug',
sum(case when dt.mo=9 then o.[Value] else 0 end) 'Sep',
sum(case when dt.mo=10 then o.[Value] else 0 end) 'Oct',
sum(case when dt.mo=11 then o.[Value] else 0 end) 'Nov',
sum(case when dt.mo=12 then o.[Value] else 0 end) 'Dec'
from Orders o
cross apply (select month(o.[Date]) mo) dt
where year(o.[DAte])=#Year;
You may try this-
Select
max(case when [Month] = 'Jan' then Value end) As "JAN"
,max(case when [Month] = 'Feb' then Value end) As "FEB"
,.....
,max(case when [Month] = 'Dec' then Value end) As "DEC"
from
(SELECT
Format(O.Date, 'MMM') as [Month],
Max(O.Value) AS VALUE
FROM Orders O
WHERE YEAR(Date) = #Year
Group by
Format(O.Date, 'MMM'))T;

Get months between two dates in TSQL

I have a function that returns the following:
Title Start End
Task A 2015-01-02 2015-03-31
Task B 2015-02-12 2015-04-01
Task C 2014-11-01 2015-02-05
....
I want to return a column for each month and 1 if its within the Start and End period 0 otherwise
Title Start End Jan Feb Mar Apr May Jun ....
Task A 2015-01-02 2015-03-31 1 1 1 0 0 0
Task B 2015-02-12 2015-04-01 0 1 1 1 0 0
Task C 2014-11-01 2015-02-05 1 1 0 0 0 0
....
Anyone have an idea on how to do this?
You would do this with basic case statements:
select title, start, end,
(case when 1 between month(start) and month(end) then 1 else 0 end) as jan,
(case when 2 between month(start) and month(end) then 1 else 0 end) as feb,
. . .
(case when 12 between month(start) and month(end) then 1 else 0 end) as dec
from table t;
Note: I am leaving your column names as in the query, even though some are reserved words and should be escaped (if that is the real name of the columns).
Also note that in your sample data, the dates change between the first table and the second.
If you only wanted to check 1 date, this would work. You should be able to adapt this sample to meet your needs.
SELECT c.CreateDateUTC, DATEPART(MONTH, c.CreateDateUTC) 'MONTH',
CASE DATEPART(MONTH, c.CreateDateUTC)
WHEN 1 THEN 1
END 'JAN',
CASE DATEPART(MONTH, c.CreateDateUTC)
WHEN 2 THEN 1
END 'FEB',
CASE DATEPART(MONTH, c.CreateDateUTC)
WHEN 3 THEN 1
END 'MAR',
CASE DATEPART(MONTH, c.CreateDateUTC)
WHEN 4 THEN 1
END 'APR',
CASE DATEPART(MONTH, c.CreateDateUTC)
WHEN 5 THEN 1
END 'MAY',
CASE DATEPART(MONTH, c.CreateDateUTC)
WHEN 6 THEN 1
END 'JUN',
CASE DATEPART(MONTH, c.CreateDateUTC)
WHEN 7 THEN 1
END 'JUL',
CASE DATEPART(MONTH, c.CreateDateUTC)
WHEN 8 THEN 1
END 'AUG',
CASE DATEPART(MONTH, c.CreateDateUTC)
WHEN 9 THEN 1
END 'SEP',
CASE DATEPART(MONTH, c.CreateDateUTC)
WHEN 10 THEN 1
END 'OCT',
CASE DATEPART(MONTH, c.CreateDateUTC)
WHEN 11 THEN 1
END 'NOV',
CASE DATEPART(MONTH, c.CreateDateUTC)
WHEN 12 THEN 1
END 'DEC'
FROM dbo.Code c
Result:
To expand, make sure you check for null, and you can use ISNULL(StartDate,GetDate()) which will give you today if that fits your range needs.
select *,
case when StartDate is not null and EndDate is not null and 1 between MONTH(StartDate) and Month(EndDate) then 1 else 0 end Jan,
case when StartDate is not null and EndDate is not null and 2 between MONTH(StartDate) and Month(EndDate) then 1 else 0 end Feb,
case when StartDate is not null and EndDate is not null and 3 between MONTH(StartDate) and Month(EndDate) then 1 else 0 end Mar,
case when StartDate is not null and EndDate is not null and 4 between MONTH(StartDate) and Month(EndDate) then 1 else 0 end Apr,
case when StartDate is not null and EndDate is not null and 5 between MONTH(StartDate) and Month(EndDate) then 1 else 0 end May,
case when StartDate is not null and EndDate is not null and 6 between MONTH(StartDate) and Month(EndDate) then 1 else 0 end Jun,
case when StartDate is not null and EndDate is not null and 7 between MONTH(StartDate) and Month(EndDate) then 1 else 0 end Jul,
case when StartDate is not null and EndDate is not null and 8 between MONTH(StartDate) and Month(EndDate) then 1 else 0 end Aug,
case when StartDate is not null and EndDate is not null and 9 between MONTH(StartDate) and Month(EndDate) then 1 else 0 end Sep,
case when StartDate is not null and EndDate is not null and 10 between MONTH(StartDate) and Month(EndDate) then 1 else 0 end Oct,
case when StartDate is not null and EndDate is not null and 11 between MONTH(StartDate) and Month(EndDate) then 1 else 0 end Nov,
case when StartDate is not null and EndDate is not null and 12 between MONTH(StartDate) and Month(EndDate) then 1 else 0 end Dec
from Foo

Can I use pivot to add columns in the sum?

I have a query where i get the ave of a rating for different question q1-q5.
Would it possible to add the q1-q5 and divide it by the count using pivot?
I have try to make a query below:
SELECT
employeedept,YEAR_cse,csedept_name,
SUM(January) as January, SUM(February) as February,
SUM(March) as March, SUM(April) as April,
SUM(May) as May, SUM(June) as June,
SUM(July) as July, SUM(August) as August,
SUM(September) as September, SUM(October) as October,
SUM(November) as November, SUM(December) as December
FROM
(SELECT
CAST(employeedept AS INT) as dept,
ROUND(AVG(case when rating1 > 0 THEN CAST(rating1 AS FLOAT) ELSE null END), 2) as q1,
ROUND(AVG(case when rating2 > 0 THEN CAST(rating2 AS FLOAT) ELSE null END), 2) as q2,
ROUND(AVG(case when rating3 > 0 THEN CAST(rating3 AS FLOAT) ELSE null END), 2) as q3,
ROUND(AVG(case when rating4 > 0 THEN CAST(rating4 AS FLOAT) ELSE null END), 2) as q4,
ROUND(AVG(case when rating5 > 0 THEN CAST(rating5 AS FLOAT) ELSE null END), 2) as q5,
count(*) as 'totalstars',
month_cse = datename(month, approveddate),
YEAR_cse = YEAR(approveddate)
FROM
CSEReduxResponses
WHERE
execoffice_status = 1
and YEAR ([approveddate]) =2014
GROUP BY
month(approveddate), YEAR(approveddate),
DATENAME(month,approveddate), employeedept) AS r
JOIN
CSEReduxDepts d ON d.csedept_id = r.employeedept
AND YEAR_cse is NOT NULL
PIVOT( SUM(q1+q2+q3+q4+q5/totalstars)
FOR [month_cse] IN (
[January],[February],[March],[April],[May],[June],[July],[August], [September],[October],[November],[December]
)) AS pvt
Group BY employeedept,YEAR_cse,csedept_name
With this query I get this error:
Msg 102, Level 15, State 1, Line 21
Incorrect syntax near '+'.'
What I would like to do is be able to sum the q1-q5/totalstars, Would something like this be possible using pivot?
If I run the second select statement it gives me the correct results.
I think this should be your final query that you need.
I have done wrote the count function to do the average if your value is null then it will return 0 for the particular column
Lets say
rating1 = null then ISNULL(COUNT(rating1),0) = 0
rating2 = 2 then ISNULL(COUNT(rating1),0) = 1
rating3 = 3 then ISNULL(COUNT(rating1),0) = 1
so on....
Here's the query. I hope this will help you.
SELECT
employeedept,
YEAR_cse,
csedept_name,
SUM(January) as January,
SUM(February) as February,
SUM(March) as March,
SUM(April) as April,
SUM(May) as May,
SUM(June) as June,
SUM(July) as July,
SUM(August) as August,
SUM(September) as September,
SUM(October) as October,
SUM(November) as November,
SUM(December) as December
FROM
(
SELECT employeedept,
(
ROUND(AVG(case when rating1>0 THEN CAST(rating1 AS FLOAT) ELSE 0 END), 2) +
ROUND(AVG(case when rating2>0 THEN CAST(rating2 AS FLOAT) ELSE 0 END), 2) +
ROUND(AVG(case when rating3>0 THEN CAST(rating3 AS FLOAT) ELSE 0 END), 2) +
ROUND(AVG(case when rating4>0 THEN CAST(rating4 AS FLOAT) ELSE 0 END), 2) +
ROUND(AVG(case when rating5>0 THEN CAST(rating5 AS FLOAT) ELSE 0 END), 2))
/(
ISNULL(COUNT(rating1),0) +
ISNULL(COUNT(rating2),0) +
ISNULL(COUNT(rating3),0) +
ISNULL(COUNT(rating4),0)+
ISNULL(COUNT(rating5),0)) as AG,
count(*) as 'totalstars',month_cse= datename(month,approveddate),YEAR_cse =YEAR(approveddate)
FROM
CSEReduxResponses
Where
YEAR(approveddate) =2014
and execoffice_status=1
group by
employeedept,
month(approveddate),
YEAR(approveddate),
DATENAME(month,approveddate)
)AS r
JOIN CSEReduxDepts d ON d.csedept_id = r.employeedept
AND YEAR_cse is NOT NULL
PIVOT(
SUM(AG)
FOR [month_cse] IN (
[January],[February],[March],[April],[May],[June],[July],[August], [September],[October],[November],[December]
)) AS pvt
Group BY employeedept,YEAR_cse,csedept_name

How can I accomplish this? Would a cursor be appropriate?

I am trying to use TOAD and T-SQL to approximate a user's spreadsheet. Here are the basics of what they want:
Order Number Customer Name June July Aug Sept Oct Nov Dec
12345 Bleh Company 1000
800 200
The first row represents when the order value was received and the second represents the projected ship date of said order.
The following SQL Script delivers this, but it does not alternate between Order Date and Receiving Date.
SELECT 'O', -- For Order Date
(SOM.[fcustno] + ' - ' + SOM.[fcompany]) AS [Customer],
sum(CASE month (SOM.forderdate)
WHEN 6 THEN (sor.forderqty * SOR.funetprice)
ELSE 0
END)
AS [June],
sum(CASE month (SOM.forderdate)
WHEN 7 THEN (sor.forderqty * SOR.funetprice)
ELSE 0
END)
AS [July],
sum(CASE month (SOM.forderdate)
WHEN 8 THEN (sor.forderqty * SOR.funetprice)
ELSE 0
END)
AS [Aug],
sum(CASE month (SOM.forderdate)
WHEN 9 THEN (sor.forderqty * SOR.funetprice)
ELSE 0
END)
AS [Sept],
sum(CASE month (SOM.forderdate)
WHEN 10 THEN (sor.forderqty * SOR.funetprice)
ELSE 0
END)
AS [Oct],
sum(CASE month (SOM.forderdate)
WHEN 11 THEN (sor.forderqty * SOR.funetprice)
ELSE 0
END)
AS [Nov],
sum(CASE month (SOM.forderdate)
WHEN 12 THEN (sor.forderqty * SOR.funetprice)
ELSE 0
END)
AS [Dec]
FROM SORELS SOR
JOIN SOMAST SOM
ON SOM.FSONO = SOR.FSONO
JOIN SOITEM SOI
ON SOI.FSONO = SOR.FSONO AND SOI.FINUMBER = SOR.FINUMBER
WHERE FMASTERREL = 0
AND SOM.forderdate >= CONVERT (DATETIME, '05/29/2009')
AND SOM.forderdate < CONVERT (DATETIME, '08/04/2009')
AND SOI.fduedate < CONVERT (DATETIME, '01/01/2010')
GROUP BY (SOM.[fcustno] + ' - ' + SOM.[fcompany])
UNION
SELECT 'S', -- For Ship Date
(SOM.[fcustno] + ' - ' + SOM.[fcompany]) AS [Customer],
sum(CASE month (SOI.fduedate)
WHEN 6 THEN (sor.forderqty * SOR.funetprice)
ELSE 0
END)
AS [June],
sum(CASE month (SOI.fduedate)
WHEN 7 THEN (sor.forderqty * SOR.funetprice)
ELSE 0
END)
AS [July],
sum(CASE month (SOI.fduedate)
WHEN 8 THEN (sor.forderqty * SOR.funetprice)
ELSE 0
END)
AS [Aug],
sum(CASE month (SOI.fduedate)
WHEN 9 THEN (sor.forderqty * SOR.funetprice)
ELSE 0
END)
AS [Sept],
sum(CASE month (SOI.fduedate)
WHEN 10 THEN (sor.forderqty * SOR.funetprice)
ELSE 0
END)
AS [Oct],
sum(CASE month (SOI.fduedate)
WHEN 11 THEN (sor.forderqty * SOR.funetprice)
ELSE 0
END)
AS [Nov],
sum(CASE month (SOI.fduedate)
WHEN 12 THEN (sor.forderqty * SOR.funetprice)
ELSE 0
END)
AS [Dec]
FROM SORELS SOR
JOIN SOMAST SOM
ON SOM.FSONO = SOR.FSONO
JOIN SOITEM SOI
ON SOI.FSONO = SOR.FSONO AND SOI.FINUMBER = SOR.FINUMBER
WHERE FMASTERREL = 0
AND SOM.forderdate >= CONVERT (DATETIME, '05/29/2009')
AND SOM.forderdate < CONVERT (DATETIME, '08/04/2009')
AND SOI.fduedate < CONVERT (DATETIME, '01/01/2010')
GROUP BY (SOM.[fcustno] + ' - ' + SOM.[fcompany])
Any suggestions?
Try adding the following:
ORDER BY 2, 1
to the end of your script. It seems as though you just need to sort - first by customer, then by Order / Ship
You should give a name to your 'O'/'S' column (maybe RowType). Then order by Customer, RowType.
Rob