SQL Pivot from an Access Pivot query - sql-server

I have the following Access query that needs turned into SQL -
TRANSFORM
Sum([anaes_downtime]![ANAESENDTIME]-[anaes_downtime]![anaesstarttime])/24/60 AS Expr1
SELECT downtime_seq.THEATRE, downtime_seq.OPSESSION, downtime_seq.OPDATE
FROM ANAES_Downtime
INNER JOIN downtime_seq ON ANAES_Downtime.opnumber = downtime_seq.opnumber
WHERE (((ANAES_Downtime.ANAESSTARTTIME) <> 0 )
AND ((ANAES_Downtime.ANAESENDTIME) <> 0 ))
GROUP BY downtime_seq.THEATRE, downtime_seq.OPSESSION, downtime_seq.OPDATE
PIVOT "d" & [opseq] IN ("d0","d1","d2","d3","d4","d5","d6","d7","d8","d9","d10","d11","d12","d13","d14","d15","d16","d17","d18","d19","d20");
I understand the basics of sql pivot but have been unable to convert this successfully. Any help?

I have found an answer to my question using the CASE statement -
SELECT ad.THEATRE, ad.OPSESSION, ad.OPDATE,
SUM(CASE WHEN opseq = 0
THEN ad.ANAESENDTIME - ad.anaesstarttime ELSE 0 END) AS 'd0',
SUM(CASE WHEN opseq = 1
THEN ad.ANAESENDTIME - ad.anaesstarttime ELSE 0 END) AS 'd1',
SUM(CASE WHEN opseq = 2
THEN ad.ANAESENDTIME - ad.anaesstarttime ELSE 0 END) AS 'd2',
SUM(CASE WHEN opseq = 3
THEN ad.ANAESENDTIME - ad.anaesstarttime ELSE 0 END) AS 'd3',
SUM(CASE WHEN opseq = 4
THEN ad.ANAESENDTIME - ad.anaesstarttime ELSE 0 END) AS 'd4',
SUM(CASE WHEN opseq = 5
THEN ad.ANAESENDTIME - ad.anaesstarttime ELSE 0 END) AS 'd5'...
...FROM #ANAES_Downtime ad INNER JOIN #DowntimeSeq ds ON ad.opnumber = ds.opnumber
WHERE ad.ANAESSTARTTIME <> 0 AND ad.ANAESENDTIME <> 0
GROUP BY ad.THEATRE, ad.OPSESSION, ad.OPDATE
ORDER BY ad.THEATRE, ad.OPSESSION, ad.OPDATE

Related

Where condition a outer applied sql query

I am using a sql query but sorry to say unable to use a where condition. I post my query below.
SELECT * , CAST( RIGHT(FileNo,3) AS numeric) as IntFileNo
FROM ExportLcs A
OUTER APPLY (
SELECT SUM(ReceivedTTUsd) AS TtTotal,
SUM(ReceivedPDCUsd) AS PdcTotal,
SUM(CASE WHEN ReceivedPDCUsd > 0 THEN 1 ELSE 0 END) AS PdcCashCount,
SUM(CASE WHEN ReceivedPDCUsd > 0 THEN ConvertRate ELSE 0 END) AS PdcRateTotal,
SUM(CASE WHEN ConvertRate > 0 THEN CEILING(ReceivedPDCUsd / ConvertRate) ELSE 0 END) AS PdcTotalUsd,
Count(ExportLcId) AS TotalPaymentCount
FROM dbo.ExportPayments G
WHERE A.ExportLcId = G.ExportLcId AND (G.PdcTotal+G.PdcTotalUsd)>0
) AS G
I want to use condition like
A.ExportLcId = G.ExportLcId AND (G.PdcTotal+G.PdcTotalUsd)>0
but and part not working.
Any one can help.
How about having clause instead of where?
SELECT * , CAST(RIGHT(FileNo, 3) AS NUMERIC) AS IntFileNo
FROM dbo.ExportLcs AS A
OUTER APPLY (
SELECT SUM(ReceivedTTUsd) AS TtTotal
, SUM(ReceivedPDCUsd) AS PdcTotal
, SUM(CASE WHEN ReceivedPDCUsd > 0 THEN 1 ELSE 0 END) AS PdcCashCount
, SUM(CASE WHEN ReceivedPDCUsd > 0 THEN ConvertRate ELSE 0 END) AS PdcRateTotal
, SUM(CASE WHEN ConvertRate > 0 THEN CEILING(ReceivedPDCUsd / ConvertRate) ELSE 0 END) AS PdcTotalUsd
, COUNT(ExportLcId) AS TotalPaymentCount
FROM dbo.ExportPayments AS G
WHERE A.ExportLcId = G.ExportLcId
HAVING (SUM(ReceivedPDCUsd) + SUM(CASE WHEN ConvertRate > 0 THEN CEILING(ReceivedPDCUsd / ConvertRate) ELSE 0 END)) > 0
) AS G;
You should consider using Outer Join instead, so try the following:
SELECT * , CAST( RIGHT(FileNo,3) AS numeric) as IntFileNo from ExportLcs A left outer join
(
SELECT SUM(ReceivedTTUsd) AS TtTotal,
SUM(ReceivedPDCUsd) AS PdcTotal,
SUM(CASE WHEN ReceivedPDCUsd > 0 THEN 1 ELSE 0 END) AS PdcCashCount,
SUM(CASE WHEN ReceivedPDCUsd > 0 THEN ConvertRate ELSE 0 END) AS PdcRateTotal,
SUM(CASE WHEN ConvertRate > 0 THEN CEILING(ReceivedPDCUsd / ConvertRate) ELSE 0 END) AS PdcTotalUsd,
Count(ExportLcId) AS TotalPaymentCount
FROM dbo.ExportPayments) G
on A.ExportLcId = G.ExportLcId where (G.PdcTotal+G.PdcTotalUsd)>0
just put your part where clause outside.
SELECT * , CAST( RIGHT(FileNo,3) AS numeric) as IntFileNo
FROM Export
where (G.PdcTotal+G.PdcTotalUsd)>0Lcs A
OUTER APPLY (
SELECT SUM(ReceivedTTUsd) AS TtTotal,
SUM(ReceivedPDCUsd) AS PdcTotal,
SUM(CASE WHEN ReceivedPDCUsd > 0 THEN 1 ELSE 0 END) AS PdcCashCount,
SUM(CASE WHEN ReceivedPDCUsd > 0 THEN ConvertRate ELSE 0 END) AS PdcRateTotal,
SUM(CASE WHEN ConvertRate > 0 THEN CEILING(ReceivedPDCUsd / ConvertRate) ELSE 0 END) AS PdcTotalUsd,
Count(ExportLcId) AS TotalPaymentCount
FROM dbo.ExportPayments G
WHERE A.ExportLcId = G.ExportLcId
) AS G

unpivot one row of aggregates to 1 column

I have this query that returns 1 row of aggregate sums
DECLARE #Income9 int
SELECT #Income9 = IncomeLevel FROM PovertyLevels WHERE HouseholdNumber = 9
;WITH CTE
AS
(
SELECT PatientProfileID, CASE WHEN v.FamilyMembersinHousehold > 8
THEN ROUND((CAST(AnnualIncome as float)/(CAST(#Income9 as float) +((V.FamilyMembersinHousehold-8)* CAST(#Income9 as Float)))*100.00), 5)
WHEN ((v.FamilyMembersinHousehold IS NULL) OR (AnnualIncome IS NULL)) THEN NULL
ELSE ROUND(((CAST(AnnualIncome AS Float)/CAST(pl.IncomeLevel as Float)) * 100.00), 5) END AS PercentOfPoverty
FROM vPatientDemographics v
LEFT OUTER JOIN PovertyLevels pl ON v.FamilyMembersinHousehold = pl.HouseholdNumber
)
SELECT SUM(CASE WHEN PercentOfPoverty <= 100 THEN 1 ELSE 0 END) AS NumOfPatientsBelow100,
SUM(CASE WHEN PercentOfPoverty BETWEEN 101 AND 150 THEN 1 ELSE 0 END) AS NumOfPatientsBetween101And150,
SUM(CASE WHEN PercentOfPoverty BETWEEN 151 AND 200 THEN 1 ELSE 0 END) AS NumOfPatientsBetween151And200,
SUM(CASE WHEN PercentOfPoverty > 200 THEN 1 ELSE 0 END) AS NumOfPatientsOver200,
SUM(CASE WHEN PercentOfPoverty IS NULL THEN 1 ELSE 0 END) AS NumOfPatientsUnknown
FROM CTE
I would like to have the sum data to be in rows not columns.
I tried adding this UNPIVOT but it does not recognize the column names.
UNPIVOT
(
Levels for PovertyLevels in (NumOfPatientsBelow100, NumOfPatientsBetween101And150, NumOfPatientsBetween151And200,
NumOfPatientsOver200, NumOfPatientsUnknown)
) as Unpvt
How can I unpivot the initial data set to that it is in rows not columns?
It is because Where clause is evaluated before the select
SELECT #Income9 = IncomeLevel FROM PovertyLevels WHERE HouseholdNumber = 9
;WITH CTE
AS
(
SELECT PatientProfileID, CASE WHEN v.FamilyMembersinHousehold > 8
THEN ROUND((CAST(AnnualIncome as float)/(CAST(#Income9 as float) +((V.FamilyMembersinHousehold-8)* CAST(#Income9 as Float)))*100.00), 5)
WHEN ((v.FamilyMembersinHousehold IS NULL) OR (AnnualIncome IS NULL)) THEN NULL
ELSE ROUND(((CAST(AnnualIncome AS Float)/CAST(pl.IncomeLevel as Float)) * 100.00), 5) END AS PercentOfPoverty
FROM vPatientDemographics v
LEFT OUTER JOIN PovertyLevels pl ON v.FamilyMembersinHousehold = pl.HouseholdNumber
),intr as
(
SELECT SUM(CASE WHEN PercentOfPoverty <= 100 THEN 1 ELSE 0 END) AS NumOfPatientsBelow100,
SUM(CASE WHEN PercentOfPoverty BETWEEN 101 AND 150 THEN 1 ELSE 0 END) AS NumOfPatientsBetween101And150,
SUM(CASE WHEN PercentOfPoverty BETWEEN 151 AND 200 THEN 1 ELSE 0 END) AS NumOfPatientsBetween151And200,
SUM(CASE WHEN PercentOfPoverty > 200 THEN 1 ELSE 0 END) AS NumOfPatientsOver200,
SUM(CASE WHEN PercentOfPoverty IS NULL THEN 1 ELSE 0 END) AS NumOfPatientsUnknown
FROM CTE
)
Select cnt,range from intr
cross apply (values (NumOfPatientsBelow100,'NumOfPatientsBelow100'),
(NumOfPatientsBetween101And150,'NumOfPatientsBetween101And150'),
(NumOfPatientsBetween151And200,'NumOfPatientsBetween151And200'),
(NumOfPatientsOver200,'NumOfPatientsOver200'),
(NumOfPatientsUnknown,'NumOfPatientsUnknown')) cs (cnt,range)

SQL procedure sum and sum inside select and insert to

I have a little problem. I have a insert into block with select and inside select I have sum. Thats works well. But In this select I need also do some operation on these sums. I don't know how.
Code:
insert into [dbo].[DiscountDailyStatsTemp]
SELECT
#DiscountId,
cast([dbo].[TelemetryData].[EventTime] as date) as 'Date',
sum(case when [dbo].[TelemetryData].[EventName] = 'DiscountLike' then 1 else 0 end) as 'Likes',
sum(case when [dbo].[TelemetryData].[EventName] = 'DiscountDislike' then 1 else 0 end) as 'Dis likes',
sum(case when [dbo].[TelemetryData].[EventName] = 'DiscountShare' then 1 else 0 end) as 'Shares',
SUM(case when [dbo].[TelemetryData].[EventName]='DiscountView' then 1 else 0 end) as 'Views',
SUM(case when [dbo].[TelemetryData].[EventName]='DiscountClick' then 1 else 0 end) as 'Clicks',
Sum(case when [dbo].[TelemetryData].[EventName] = 'DiscountCode' then 1 else 0 end) as 'Downloaded codes',
Sum(case when [dbo].[TelemetryData].[EventName] = 'DiscountSave' then 1 else 0 end) as 'Saves',
sum(case when [dbo].[TelemetryData].[EventName] = 'DiscountClickWWW' then 1 else 0 end) as 'Page redirections',
0 as 'Average CTR',
#UniqueUsers as 'Unique users',
#NewUsers as 'New users',
#ReturningUsers as 'Returning users',
Sum(case when [dbo].[TelemetryData].[EventName] = 'DiscountCommentPositive' then 1 else 0 end) as 'Positive comments',
sum(case when [dbo].[TelemetryData].[EventName] = 'DiscountCommentNegative' then 1 else 0 end) as 'Negative comments'
from [dbo].[TelemetryData]
where [dbo].[TelemetryData].[DiscountId] = #DiscountId
and ([dbo].[TelemetryData].[EventName] = 'DiscountView' or [dbo].[TelemetryData].[EventName] = 'DiscountClick' or
[dbo].[TelemetryData].[EventName] = 'DiscountDislike' or [dbo].[TelemetryData].[EventName] = 'DiscountCode' or
[dbo].[TelemetryData].[EventName] = 'DiscountLike' or [dbo].[TelemetryData].[EventName] = 'DiscountShare' or
[dbo].[TelemetryData].[EventName] = 'DiscountClickWWW' or [dbo].[TelemetryData].[EventName] = 'DiscountSave' or
[dbo].[TelemetryData].[EventName] = 'DiscountCommentPositive' or [dbo].[TelemetryData].[EventName] = 'DiscountCommentNegative')
group by cast([dbo].[TelemetryData].[EventTime] as date)
order by cast([dbo].[TelemetryData].[EventTime] as date) asc
And look there is 0 as 'Average CTR' I need to change it for this:
Round(cast('Clicks' as float) / cast(case when 'Views' = 0 then 1 else 'Views') end as float) * 100, 2) as 'Average CTR',
But it not working. How I can do it?
You can't use the aliases in the same level they are created, and also this is a query with a group by clause, which means each column should be either in the group by or with an aggregation function around it.
You can wrap your query with another select :
SELECT [date],
[likes],
....
Round(cast([Clicks] as float) / cast(case when [Views] = 0 then 1 else [Views] end) as float) * 100, 2) as [Average CTR],
FROM(YOUR QUERY HERE)
Also, use square brackets for columns name.

Need to add a subquery in a CASE expression that is part of an aggregate function

I need to add the number of records in which the status is set to 'reopened'. But the 'reopened' status has several IDs.
This is the subquery that will Id the 'reopen' statuses:
SELECT (CASE WHEN s.sr_status_recid = 1 THEN 1 ELSE 0 END) AS Reopened
from v_rpt_service s
where vsrv.sr_status_recid in
(select distinct SR_Status_RecID from SR_Status where [Description] like '%Re-opened%'))
This is the main query that the above query needs to be a part:
SELECT DATEPART(WK, vsrv.date_entered) as WkNumber,
COUNT(vsrv.TicketNbr) AS OpenedIssues, --total ticket count
SUM(CASE WHEN vsrv.Closed_Flag = 1 THEN 1 ELSE 0 END) AS ClosedIssues, --sum of tickets with closed_flag = 1
(SELECT SUM(CASE WHEN s.sr_status_recid = 1 THEN 1 ELSE 0 END)
from v_rpt_service s
where vsrv.sr_status_recid in
(select distinct SR_Status_RecID from SR_Status where [Description] like '%Re-opened%')) AS ReopenedIssues,
SUM(CASE WHEN vsrvy.Surveys_Completed = 1 THEN 1 ELSE 0 END) AS SurveysCompletedWithConnectWise, -- Surveys_Completed flag in view is 1
SUM(CASE WHEN Source = 'Portal' THEN 1 ELSE 0 END) AS IssueLoggedPortal,
SUM(CASE WHEN Source = 'Email Connector' THEN 1 ELSE 0 END) AS IssueLoggedEmai
FROM v_rpt_service vsrv LEFT OUTER JOIN v_rpt_SurveysByTicket vsrvy ON vsrv.TicketNbr = Vsrvy.SR_Service_RecID
WHERE vsrv.company_name <> 'XYZ Test Company' AND vsrv.date_entered BETWEEN '01/01/2016' AND '10/07/2016'
GROUP BY DATEPART(WK, vsrv.date_entered)
ORDER BY WkNumber
How can I have a subquery that uses a CASE statement and the CASE statement is aggregated?
You can use CROSS APPLY
SELECT DATEPART(WK, vsrv.date_entered) as WkNumber,
COUNT(vsrv.TicketNbr) AS OpenedIssues, --total ticket count
SUM(CASE WHEN vsrv.Closed_Flag = 1 THEN 1 ELSE 0 END) AS ClosedIssues, --sum of tickets with closed_flag = 1
SUM(CountReopen.YesNo) AS NumberOfReopen,
SUM(CASE WHEN vsrvy.Surveys_Completed = 1 THEN 1 ELSE 0 END) AS SurveysCompletedWithConnectWise, -- Surveys_Completed flag in view is 1
SUM(CASE WHEN Source = 'Portal' THEN 1 ELSE 0 END) AS IssueLoggedPortal,
SUM(CASE WHEN Source = 'Email Connector' THEN 1 ELSE 0 END) AS IssueLoggedEmail
FROM v_rpt_service vsrv
LEFT OUTER JOIN v_rpt_SurveysByTicket vsrvy
ON vsrv.TicketNbr = Vsrvy.SR_Service_RecID
CROSS APPLY (
SELECT IIF(COUNT(*) > 0,1,0) YesNo
FROM SR_Status
where [Description] like '%Re-opened%'
AND SR_Status_ID = vsrv.sr_status_recid
) CountReopen(YesNo)
WHERE vsrv.company_name <> 'XYZ Test Company'
AND vsrv.date_entered BETWEEN '01/01/2016' AND '10/07/2016'
GROUP BY DATEPART(WK, vsrv.date_entered)
ORDER BY WkNumber

When I SUM values of each month between 2 dates, I get the wrong value

I am really struggling with a query. I want the sum of each month between Aug 2014 and July 2015. If I specify the between dates in the where clause it sums all the months.
Here is my query:
DECLARE #CurrentYear int = DATEpart(year,getdate())
DECLARE #PreviousYear int = DATEpart(year,getdate()) -1
SELECT
SUM(CASE WHEN a.fin_period = concat(#PreviousYear,'08') THEN a.balance ELSE 0 END) AS BalanceAug ,
SUM(CASE WHEN a.fin_period = concat(#PreviousYear,'09') THEN a.balance ELSE 0 END) AS BalanceSep ,
SUM(CASE WHEN a.fin_period = concat(#PreviousYear,'10') THEN a.balance ELSE 0 END) AS BalanceOct ,
SUM(CASE WHEN a.fin_period = concat(#PreviousYear,'11') THEN a.balance ELSE 0 END) AS BalanceNov ,
SUM(CASE WHEN a.fin_period = concat(#PreviousYear,'12') THEN a.balance ELSE 0 END) AS BalanceDec ,
...etc.
FROM subaccount_history a with (nolock)
WHERE fin_period between concat(#PreviousYear,'08') and concat(#CurrentYear,'12')
The issue is with the between clause, i tried group by but that also doesn't work. It sums everything between the 2 dates specified.

Resources