SQL - Pivot/Unpivot? - sql

I have a table in SQL Server 2008 in the format as below(simplified format) :
Date Miles Cost
I want to get a result like
Previous Week Current Week Variance
Miles
Cost
How can I achieve this? Do I need pivot/unpivot or what is the easiest and performance effective way to achieve this. Thanks.

SELECT 'Miles' AS Type, SUM(CASE WHEN date = lastweek THEN miles ELSE 0 END) as lastweek
, SUM(CASE WHEN date = thisweek THEN miles ELSE 0 END) as thisweek
SUM(CASE WHEN date = lastweek THEN miles ELSE 0 END) - SUM(CASE WHEN date = thisweek THEN miles ELSE 0 END) as variance
FROM yourtable
UNION
SELECT 'Cost' AS Type, SUM(CASE WHEN date = lastweek THEN cost ELSE 0 END) as lastweek
, SUM(CASE WHEN date = thisweek THEN cost ELSE 0 END) as thisweek
SUM(CASE WHEN date = lastweek THEN cost ELSE 0 END) - SUM(CASE WHEN date = thisweek THEN cost ELSE 0 END) as variance
FROM yourtable
This isn't 100% correct, but the syntax should be correct and should get you pretty close to what you're looking for

Related

SQL Year over Year Performance with Criteria

I am trying to return year over year results based on date criteria. There is additional information I would like to include in the query i.e. first date of activity and first date of activity with spot name like '%6%'. The current query I have is multiplying the correct amounts by 6 and I can't figure out how to solve. When I remove the first "where" clause I get the correct amounts. Any help would be appreciated.
Select
V.IGB_License,
DBA,
V.Sci_Games_Name,
convert(date,v2.Activity_date) as First6thMachineDate,
convert(date,V3.Activity_date) as GoLiveDate,
sum(case when (v.Activity_date between '1/23/2019' and DATEADD(YEAR,-2,getdate()-1)) then v.Funds_in else 0 end) as FundsIn2019,
sum(case when (v.Activity_date between '1/23/2020' and DATEADD(YEAR,-1,getdate()-1)) then v.Funds_in else 0 end) as FundsIn2020,
sum(case when (v.Activity_date between '1/23/2021' and getdate()) then v.Funds_in else 0 end) as FundsIn2021,
sum(case when (v.Activity_date between '1/23/2019' and DATEADD(YEAR,-2,getdate()-1)) then v.Net_funds else 0 end) as NetFunds2019,
sum(case when (v.Activity_date between '1/23/2020' and DATEADD(YEAR,-1,getdate()-1)) then v.Net_funds else 0 end) as NetFunds2020,
sum(case when (v.Activity_date between '1/23/2021' and getdate()) then v.Net_funds else 0 end) as NetFunds2021
From VGT_activity V
Left Join Locations on v.IGB_License = Locations.IGB_License
left join VGT_activity V2 on v.IGB_License = v2.IGB_License
Left join VGT_activity V3 on v.IGB_License = v3.IGB_License
Where v2.Activity_date = (
Select Min(V1.Activity_date)
From VGT_activity V1
Where v1.IGB_License = V2.IGB_License
and Spot_name like '%6%'
)
and v3.Activity_date = (
Select Min(V1.Activity_date)
From VGT_activity V1
Where v1.IGB_License = V3.IGB_License
)
group by V.IGB_License, dba, V.Sci_Games_Name, v2.Activity_date, v3.Activity_date
order by 4

SELECT data grouped by WEEK in SQL

I have a working query (ORACLE SQL) that gives me gallons grouped by store number, with gallons summed by type and a percentage column as well. Each store number has a different conversion date from which I sum up the data -
SELECT StoreNbr,
SUM(CASE WHEN(ClrntSys IN ('844', '84448')) THEN Gallons ELSE 0 END) AS Gallons_844,
SUM(CASE WHEN(ClrntSys ='GIC') THEN Gallons ELSE 0 END) AS Gallons_GIC,
SUM(CASE WHEN(ClrntSys IN ('844', '84448', 'GIC')) THEN Gallons ELSE 0 END) AS Total_Gallons,
CONCAT(CAST((SUM(CASE WHEN(ClrntSys ='GIC') THEN Gallons ELSE 0 END) /
SUM(CASE WHEN(ClrntSys IN ('844', '84448', 'GIC')) THEN Gallons ELSE 0 END)) AS DECIMAL (5,2)) * 100, '%') AS Percent_GIC
FROM MQ_CDS_NETTRAN
WHERE ClrntSys IN ('844', '84448', 'GIC')
AND ((CostCenter = '701104' AND LastTranDate >= DATE '2020-03-10')
OR (CostCenter = '701109' AND LastTranDate >= DATE '2020-03-04')
OR (CostCenter = '701257' AND LastTranDate >= DATE '2020-03-12'))
GROUP BY StoreNbr
ORDER BY StoreNbr;
I now need to also sum it up by week, with Sunday being the first day of each week, but I'm having trouble understanding how DATEPART works. Just so I could get a better idea, I tried only to sum up the data for last week using DATEPART examples I'm seeing online, but this doesn't work. It's giving me "invalid identifier DATEPART". -
SELECT DATEPART(week, 5/17/20) AS weekTotal,
StoreNbr,
SUM(CASE WHEN(ClrntSys IN ('844', '84448')) THEN Gallons ELSE 0 END) AS Gallons_844,
SUM(CASE WHEN(ClrntSys ='GIC') THEN Gallons ELSE 0 END) AS Gallons_GIC,
SUM(CASE WHEN(ClrntSys IN ('844', '84448', 'GIC')) THEN Gallons ELSE 0 END) AS Total_Gallons,
CONCAT(CAST((SUM(CASE WHEN(ClrntSys ='GIC') THEN Gallons ELSE 0 END) /
SUM(CASE WHEN(ClrntSys IN ('844', '84448', 'GIC')) THEN Gallons ELSE 0 END)) AS DECIMAL (5,2)) * 100, '%') AS Percent_GIC
FROM MQ_CDS_NETTRAN
WHERE ((CostCenter = '701104' AND LastTranDate >= DATE '2020-03-10')
OR (CostCenter = '701109' AND LastTranDate >= DATE '2020-03-04')
OR (CostCenter = '701257' AND LastTranDate >= DATE '2020-03-12'))
GROUP BY DATEPART(week, 5/17/20), StoreNbr
ORDER BY StoreNbr;
What I really need, however, is each week's data (with Sunday being the beginning of each week) summed up separately going back to each store's conversion date. Is it possible to do that? Is there something else besides DATEPART that would work better?
Sorry - just noticed that you said Oracle SQL, and my first answer was for SQL Server! The reason you are getting an error is that DATEPART is not an Oracle function. Instead, you can simply do math on the dates, using a known sunday (prior to a known first date in the DB table) as an anchor date:
SELECT
'30-DEC-2018' as "Known Sunday,
trunc((sysdate - to_date('30-DEC-2018')) / 7) as "Week Num",
to_date('30-DEC-2018')
+ (trunc((sysdate - to_date('30-DEC-2018')) / 7) * 7)"
FROM
dual

91/5000 How to show dates between a range and show the number of records in that range using SQLServer

I'm trying to generate a report and it must look like this:
My inicial data is 2019/08/01 and my final data is Today.
I have to show every date between this two dates, and then the amount of records. If there is no record, it must show zero.
So I tried:
SELECT M2.[Date], COUNT(1) AS 'qtd'
FROM [RM].[Mov] AS [m2]
WHERE [m2].[TipMovId] = 1
AND ([m2].[DataExercicio] BETWEEN '2019-07-31' AND GETDATE())
GROUP BY [m2].[DataPosse]
SELECT m2.[Date], COUNT(1) AS 'qtd2'
FROM [RM].[Mov] AS [m2]
WHERE [m2].[TipMovId] = 4
AND ([m2].[DataExercicio] BETWEEN '2019-07-31' AND GETDATE())
GROUP BY [m2].[DataExercicio]
And SQL returns me something like this:
How can I join the results and show all the dates in my period??
You can do something like this
SELECT M2.[Date],
sum(case when [m2].[TipMovId] = 1 then 1 else 0 end) AS 'qtd'
sum(case when [m2].[TipMovId] = 2 then 1 else 0 end) AS 'qtd2'
sum(case when [m2].[TipMovId] = 3 then 1 else 0 end) AS 'qtd3'
sum(case when [m2].[TipMovId] = 4 then 1 else 0 end) AS 'qtd4'
FROM [RM].[Mov] AS [m2]
WHERE
([m2].[DataExercicio] BETWEEN '2019-07-31' AND GETDATE()) GROUP BY [m2].[Date]

Add two sum case statements that are of a negative value

I am trying to add two select statements with onyl negative values, these are the statements:
SUM(CASE WHEN LinkAcc = '8420000' THEN amount < 0 END)
SUM(CASE WHEN LinkAcc = '8400000' THEN amount < 0 END) AS Payments
I have tried :
SUM(CASE WHEN LinkAcc = '8400000,8420000' THEN amount < 0 END) AS Payments
THEN amount < 0 doesn't make much sense. If I understood you correctly, what you want is:
SUM(CASE
WHEN LinkAcc IN ('8420000','8400000') AND amount < 0
THEN amount
END) As Payments

Dynamically Creating Column Counts Per Day of Month

OK, so I have this query to find number of types per day like below. (Courtesy of MarkD here Counting Items/Rows in DB as Columns Grouped by Another Column)
select type,
sum(case when MyDate = '' then 1 else 0 end) as "10/1",
sum(case when MyDate = '' then 1 else 0 end) as "10/2
...etc
from MyTabe
group by type
However, I want to dynamically create date columns and have the count generated for each column, otherwise I would end up manually adding a new column for each day of the month.
I guess the best way to get the output I wanted was to do the following:
define startDate = to_date('2013-10-01', 'yyyy-mm-dd')
select type,
sum(case when MyDate = &&startDate then 1 else 0 end) as "1"
, sum(case when MyDate = &&startDate +1 then 1 else 0 end) as "2"
, sum(case when MyDate = &&startDate +2 then 1 else 0 end) as "3"
, sum(case when MyDate = &&startDate +3 then 1 else 0 end) as "4"
...etc for as many days of current month I am running
, sum(case when MyDate = &&startDate +29 then 1 else 0 end) as "30"
, sum(case when MyDate = &&startDate +30 then 1 else 0 end) as "31"--This would be commented out for Nov
from MyTabe
group by type
order by type
;
This way if I want to run this for Nov, Dec, Jan, and so on, I can just change the variable at the top and run the query. This is what I was looking for; however, I still wonder if it would be possible to generate the columns dynamically, but the more I look at it, the more I think that would require a pivot table.