Access Query - Summing Month to Date - sql

I currently have a crosstab query set up to return amounts by month in 2017. This displays month totals for each location individually. I want to sum year to date (month 1-7) and have it only return one value for the location. I am having trouble doing this for some reason.
TRANSFORM Sum(Location.Amt) AS SumOfAmt
SELECT
Location.Div
, Location.Store
, Location.Year
, Location.Month
FROM
[Location Name]
INNER JOIN Location
ON [Location Name].Line = Location.Line
WHERE
(
Location.Store <> 100
AND Location.Year = 2017
AND Location.Month < 8
AND Location.Line < 11
GROUP BY
Location.Div
, Location.Store
, Location.Year
, Location.Month
ORDER BY
Location.Div
, Location.Store
, [Location Name].LineDesc
PIVOT [Location Name].LineDesc
;

In your select and group by clauses you've listed Year and Month which means it will aggregate for each value in those columns. If you don't want that behavior, you should remove those columns from the query.
TRANSFORM Sum(Location.Amt) AS SumOfAmt
SELECT
Location.Div
, Location.Store
FROM
[Location Name]
INNER JOIN Location
ON [Location Name].Line = Location.Line
WHERE
(
Location.Store <> 100
AND Location.Year = 2017
AND Location.Month < 8
AND Location.Line < 11
GROUP BY
Location.Div
, Location.Store
ORDER BY
Location.Div
, Location.Store
, [Location Name].LineDesc
PIVOT [Location Name].LineDesc
;

Related

How to Show Previous Year on Dynamic Date

I have a database that has customer, product, date and volume/revenue data. I'd like to create two NEW columns to show the previous year volume and revenue based on the date/customer/product.
I've tried unioning two views, one that has dates (unchanged) and a second view that creates a CTE where I select the dates minus one year with another select statement off of that where VOL and REV are renamed VOL_PY and REV_PY but the data is incomplete. Basically what's happening is the PY data is only pulling volume and revenue if there is data in the prior year (for example if a customer didn't sell a product in 2021 but DID in 2020, it wouldn't pull for the VOL_PY for 2020 - because it didn't sell in 2021). How do I get my code to include matches in dates but also the instances where there isn't data in the "current" year?
Here's what I'm going for:
[EXAMPLE DATA WITH NEW COLUMNS]
CURRENT YEAR VIEW:
SELECT
CUSTOMER
,PRODUCT
,DATE
,VOL
,REV
,0 AS VOL_HL_PY
,0 AS REV_DOLS_PY
,DATEADD(YEAR, -1, DATE) AS DATE_PY FROM dbo.vwReporting
PREVIOUS YEAR VIEW:
WITH CTE_PYFIGURES
([AUTONUMBER]
,CUSTOMER
,PRODUCT
,DATE
,VOL
,REV
,DATE_PY
) AS
(
SELECT b.*
, DATEADD(YEAR, 1, DATE) AS DATE_PY
FROM dbo.basetable b
)
SELECT
v.CUSTOMER
,v.PRODUCT
,v.DATE
,0 AS v.VOL
,0 AS v.REV
,CTE.VOL_HL AS VOL_HL_PY
,CTE.REV_DOLS AS REV_DOLS_PY
,DATEADD(YEAR,-1,CTE.PERIOD_DATE_PY) AS PERIOD_DATE_PY
FROM dbo.vwReporting AS v
FULL OUTER JOIN CTE_PYFIGURES AS CTE ON CTE.CUSTOMER=V.CUSTOMER AND CTE.PRODUCT=V.PRODCUT AND CTE.DATE_PY=V.DATE
You need to offset your current year's data to one year forward and then union it with the current data, placing zeroes for "other" measures (VOL and REV for previous year and VOL_PY and REV_PY for current year). Then do aggregation. This way you'll have all the dimensions' values that were in current or previous year.
with a as (
select
CUSTOMER
, PRODUCT
, [DATE]
, VOL
, REV
, 0 as vol_py
, 0 as rev_py
from dbo.vwReporting
union all
select
CUSTOMER
, PRODUCT
, dateadd(year, 1, [DATE]) as [DATE]
, 0 as VOL
, 0 as REV
, vol as vol_py
, rev as rev_py
from dbo.vwReporting
)
select
CUSTOMER
, PRODUCT
, [DATE]
, VOL
, sum(vol) as vol
, sum(rev) as rev
, sum(vol_py) as vol_py
, sum(rev_py) as rev_py
from a
group by
CUSTOMER
, PRODUCT
, [DATE]
, VOL

How to return current and previous row in SQL?

How do I return the current row and the previous row in a SQL query that is organized by date on a join? I have to join the "Crew" table with its "Detail" table. When I execute the query using a subselect, I get the same data for each crew. I am not sure how to pass the current crew ID down to the subselect so that only the previous days work for the current crew is returned.
SELECT Spread_Crew.Description
, Sum(Abs(Daily_Progress.Station_Number_
Begin_Daily_Progress.Station_Number_End)) AS [Feet Total]
, Spread_Crew.Hourly_Employee_Count AS [Hourly]
, Spread_Crew.Salary_Employee_Count AS [Salary]
, (Spread_Crew.Hourly_Employee_Count +
Spread_Crew.Salary_Employee_Count)*10 AS [Weekly Hours]
, (Date() - Spread_Crew.Actual_Start_Date) AS [Crew Days to Date]
, Round(([Feet Total]/ [Crew Days to Date]),0) AS [FT/Day]
, (SELECT Sum(Abs(Daily_Progress.Station_Number_Begin
Daily_Progress.Station_Number_End))
FROM Spread_Crew INNER JOIN Daily_Progress ON Spread_Crew.ID =
Daily_Progress.Spread_Crew_Id
WHERE (((Daily_Progress.PROGRESS_DATE)=[Report Date]))
) AS [Previous Footage]
FROM Spread_Crew LEFT JOIN Daily_Progress ON Spread_Crew.ID =
Daily_Progress.Spread_Crew_Id
GROUP BY Spread_Crew.Description
, Spread_Crew.Hourly_Employee_Count
, Spread_Crew.Salary_Employee_Count
, Spread_Crew.Sort_Order
, Spread_Crew.Print_On_Daily_Report
, Spread_Crew.Actual_Start_Date
HAVING (((Spread_Crew.Print_On_Daily_Report)=True))
ORDER BY Spread_Crew.Sort_Order;
Your subquery probably wants to be a correlated subquery:
(SELECT Sum(Abs(dp.Station_Number_Begin - dp.Station_Number_End))
FROM Daily_Progress as dp
WHERE Spread_Crew.ID = dp.Spread_Crew_Id AND
dp.PROGRESS_DATE = [Report Date]
) AS [Previous Footage]
The expression Spread_Crew.ID refers to the column in the outer SELECT.

sql server complex query

1st one is the source table and 2nd one is the destination table, so in 2nd table by using unpivot the the 12 month columns converted into single column and YTD field should be update automatically. If the month name is Jan means the YTD field will Jan data only, if it is Feb means it will add the Jan data with Feb data. same if it is Dec means it will add from Jan to Dec of the same row.
Using cross apply(values ...) to unpivot your data:
select
t.[oru code]
, t.[bg name]
, t.[bu name]
, t.[domain]
, t.KPI
, t.UoM
, t.[Year]
, t.[ACT/TARGET]
, v.[Month]
, v.KPI
, t.[YTD/ITM]
from t
cross apply (values
('Jan',Jan) ,('Feb',Feb) ,('Mar',Mar)
,('April',April) ,('May',May) ,('Jun',Jun)
,('Jul',Jul) ,('Aug',Aug) ,('Sep',Sep)
,('Oct',Oct) ,('Nov',Nov) ,('Dec',Dec)
) v ([Month],KPI)
Just select all your Month indivitually and then UNION them:
select [ORU code], [BG Name], YEAR, 'Jan' as [Month], [Jan] as [KPI #], [Jan]
as [YTD/ITM] from source_table
union all
select [ORU code], [BG Name], YEAR, 'Feb' as [Month], [Feb] as [KPI #], [Jan]+
[Feb] as [YTD/ITM] from source_table
union all
select ....
you get the Idea
Looks like what you require is to do unpivot as below:
Select *, [YTD] = sum(yourYTD calculation column) over(partition by [OruCode],[year] order by Month) from (
Select OruCode, BGName ---your required columns upto dec
from table1 t1 cross join table2 t2
)
unpivot (KPINo for [Month] in ([Jan],[Feb]...) ) p

How to group some records by name and pivot some values

I am working on a SQL Query to group the results of a View by Id to have only one Row per Id
with a maximum of three pivoted results and keeping some columns static : TestCaseId, TestName, Test Case Num, Owner
Actually this is the Query i Created to get the Desired output but is now working as expected because the MAX is always retriving the max value so i am getting only one row but the pivoted values are repeated to the right.
SELECT DISTINCT TBL1.[TestName], TBL1.[Test Case Num], TBL1.[Owner], MAX(TBL1.[Browser]) as 'Column1', MAX(TBL1.[Run Date]) as 'Column2', MAX(TBL1.[Status]) as 'Column3', MAX(TBL1.[Duration]) as 'Column4', MAX(TBL1.[ErrorMsg]) as 'Column5', MAX(TBL2.[Browser]) as 'Column6', MAX(TBL2.[Run Date]) as 'Column7', MAX(TBL2.[Status]) as 'Column8', MAX(TBL2.[Duration]) as 'Column9', MAX(TBL2.[ErrorMsg]) as 'Column10', MAX(TBL3.[Browser]) as 'Column11' , MAX(TBL3.[Run Date]) as 'Column12', MAX(TBL3.[Status]) as 'Column13', MAX(TBL3.[Duration]) as 'Column14', MAX(TBL3.[ErrorMsg]) as 'Column15'
FROM (SELECT DISTINCT T1.[TestCaseId], T1.[TestName], T1.[Test Case Num], T1.[Owner], T1.[Browser], T1.[Run Date], T1.[Status], T1.[Duration], T1.[ErrorMsg]
FROM [TestRunner].[dbo].RunsRawResults T1) TBL1
cross apply (SELECT DISTINCT T2.[TestCaseId], T2.[Browser], T2.[Run Date], T2.[Status], T2.[Duration], T2.[ErrorMsg]
FROM [TestRunner].[dbo].RunsRawResults T2
WHERE T2.[TestCaseId] = TBL1.[TestCaseId] AND T2.[Run Date] TBL1.[Run Date]) TBL2
cross apply (SELECT DISTINCT T3.[TestCaseId], T3.[Browser], T3.[Run Date], T3.[Status], T3.[Duration], T3.[ErrorMsg]
FROM [TestRunner].[dbo].RunsRawResults T3
WHERE T3.[TestCaseId] = TBL2.[TestCaseId] AND T3.[Run Date] TBL2.[Run Date] AND T3.[Run Date] TBL1.[Run Date]) TBL3
GROUP BY TBL1.[TestCaseId], TBL1.[TestName], TBL1.[Test Case Num], TBL1.[Owner]
Input -
Raw Data (Comes from the RunRawResults View)
Desired and Pivoted Output
Using a common table expression (cte) and row_number() we can simplify the identification and order of multiple run dates. This also lets us skip using distinct and group by.
Switching to outer apply lets us include results where there are less than 3 runs per TestCaseId.
;with cte as (
select *
, rn = row_number() over (
partition by TestCaseId
order by [Run Date]
)
from TestRunner.dbo.RunsRawResults
)
select
tbl1.TestName
, tbl1.[Test Case Num]
, tbl1.Owner
, tbl1.Browser
, [Run Date]_tbl1 = tbl1.[Run Date]
, Status_tbl1 = tbl1.Status
, Duration_tbl1 = tbl1.Duration
, ErrorMsg_tbl1 = tbl1.ErrorMsg
, Browser_tbl2 = tbl2.Browser
, [Run Date]_tbl2 = tbl2.[Run Date]
, Status_tbl2 = tbl2.Status
, Duration_tbl2 = tbl2.Duration
, ErrorMsg_tbl2 = tbl2.ErrorMsg
, Browser_tbl3 = tbl3.Browser
, [Run Date]_tbl3 = tbl3.[Run Date]
, Status_tbl3 = tbl3.Status
, Duration_tbl3 = tbl3.Duration
, ErrorMsg_tbl3 = tbl3.ErrorMsg
from cte as tbl1
outer apply (
select
i.[Run Date]
, i.Status
, i.Duration
, i.ErrorMsg
from cte as i
where i.TestCaseId = tbl1.TestCaseId
and i.rn = 2
) as tbl2
outer apply (
select
i.[Run Date]
, i.Status
, i.Duration
, i.ErrorMsg
from cte as i
where i.TestCaseId = tbl1.TestCaseId
and i.rn = 3
) as tbl3
where tbl1.rn = 1

SQL Calculate Percentage in Group By

I have an SQL query that is used as the basis for a report. The report shows the amount of fuel used grouped by Year, Month and Fuel Type. I would like to calculate the percentage of the total for each fuel type, but I'm not having much luck. In order to calculate the percentage of the whole, I need to be able to get the total amount of fuel used regardless of the group it is in and I can't seem to figure out how to do this. Here is my query:
SELECT Year([DT1].[TransactionDate]) AS [Year], Month([DT1].[TransactionDate]) AS [Month], DT1.FuelType, Format(Sum(DT1.Used),"#.0") AS [Total Used],
FROM (SELECT TransactionDate, FuelType, Round([MeterAfter]-[MeterBefore],2) AS Used FROM FuelLog) AS DT1
WHERE (((DT1.TransactionDate) Between [Start Date] And [End Date]))
GROUP BY Year([DT1].[TransactionDate]), Month([DT1].[TransactionDate]), DT1.FuelType
ORDER BY Year([DT1].[TransactionDate]), Month(DT1.TransactionDate), DT1.FuelType;
I tried adding the following as a subquery but I get an error saying the subquery returns more than one result.
(SELECT Sum(Round([MeterAfter]-[MeterBefore],2)) AS Test
FROM Fuellog
WHERE Year([Year]) and Month([Month])
GROUP BY Year([TransactionDate]), Month([TransactionDate]))
Once I get the total of all fuel I will need to divide the amount of fuel used by the total amount of both fuel types. Should I be approaching this a different way?
Try this
SELECT A.[Year]
,A.[Month]
,A.[FuelType]
,A.[Total Used]
,(A.[Total Used] / B.[Total By Year Month]) * 100 AS Percentage
FROM
(
SELECT Year([DT1].[TransactionDate]) AS [Year]
, Month([DT1].[TransactionDate]) AS [Month]
, DT1.FuelType
, Format(Sum(DT1.Used),"#.0") AS [Total Used]
FROM (
SELECT TransactionDate
, FuelType
, Round([MeterAfter]-[MeterBefore],2) AS Used
FROM FuelLog
) AS DT1
WHERE (((DT1.TransactionDate) Between [Start Date] And [End Date]))
GROUP BY Year([DT1].[TransactionDate]), Month([DT1].[TransactionDate]), DT1.FuelType
ORDER BY Year([DT1].[TransactionDate]), Month(DT1.TransactionDate), DT1.FuelType
) A
INNER JOIN
(
SELECT Sum(Round([MeterAfter]-[MeterBefore],2)) AS [Total By Year Month]
, Year([TransactionDate]) AS [Year]
, Month([TransactionDate])) AS [Month]
FROM Fuellog
GROUP
BY Year([TransactionDate])
, Month([TransactionDate]))
) B
ON A.[Year] = B.[Year]
AND A.[Month] = B.[Month]
You need to join to the totals -- something like this (untested might have typos)
SELECT
Year([DT1].[TransactionDate]) AS [Year],
Month([DT1].[TransactionDate]) AS [Month],
DT1.FuelType,
Format(Sum(DT1.Used),"#.0") AS [Total Used],
(Sum(DT1.Used) / FT.Total) * 100 AS Percent
FROM (
SELECT
TransactionDate,
FuelType,
Round([MeterAfter]-[MeterBefore],2) AS Used
FROM FuelLog
) AS DT1
JOIN (
SELECT
Sum(Round([MeterAfter]-[MeterBefore],2)) AS Total
FuelType
FROM Fuellog
WHERE TransactionDate Between [Start Date] And [End Date]
GROUP BY FuelType
) FT ON DT1.FuelType = FT.FeulType
WHERE DT1.TransactionDate Between [Start Date] And [End Date]
GROUP BY Year([DT1].[TransactionDate]), Month([DT1].[TransactionDate]), DT1.FuelType, FT.Total
ORDER BY Year([DT1].[TransactionDate]), Month(DT1.TransactionDate), DT1.FuelType, FT.Total;