SQL Difference Between Sum of Two Months - sql

I'm trying to find the difference between the previous years month and current years month. An example would be the SUM of sales for January 2013 and the difference of SUM of sales for January 2014 sales. This is being done to see how much we made from the previous year. I have a group by that shows the total sales by month and year. I'm having trouble on defining how to find the difference between the two months. Thank you for your help. Its greatly appreciated.
Table
Date Sales
1/1/2013 100
1/12/2013 150
1/21/2013 90
1/4/2014 200
1/17/2014 50
1/20/2014 100
Result of Group By
Jan 2013
340
Jan 2014
350
Difference
Jan 2014 - Jan 2013
340 - 350 = 10

The best way to do this depends on the database. The first thing you need to do is to aggregate the data. Then a simple join will get the data you need. Here is one method:
with ym as (
select year(date) as yr, month(date) as mon,
sum(sales) as sales
from table t
group by year(date), month(date)
)
select ym.yr, ym.mon, ym.sales, ymprev.sales as prev_sales,
(ym.sales - ymprev.sales) as diff
from ym join
ym ymprev
on ymprev.yr = ym.yr - 1 and ymprev.mon = ym.mon;

Related

Is there a way to count distinct from first record to last day of each month? BigQuery

I am trying to compute the total of customer base from 2018-01-01 till last day of the months this year to achieve a month on month look. For instance, for the month of Jan in 2022, it will be the total count of distinct customers from 2018-01-01 to 2022-01-30. For the month of feb in 2022, it will be total count of distinct customers from 2018-01-01 to 2022-02-29. Could someone enlighten me?
select count(distinct customername) from table
where billingdate between "2018-01-01" and "2022-01-30";
currently, I only get the result for first month.
result
I think you are expecting cumulative customer count month wise,
example: in jan 2018 the customer count is 10 and in feb 2018 count is 20
jan 2018 - 10
feb 2018 - 20
what you need is
jan 2018 - 10
feb 2018 - 30 <--
In this case, group the dates and use 'over' clause, to get the cumulative count
select year_month_date,sum(customer_count) over(ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) as cumulative_customer_count_from_jan_2018 from (select year_month_date, count(distinct customername) as customer_count from (select date(extract(year from billingdate),extract(month from billingdate),1) as year_month_date, customername from table) as table group by year_month_date order by year_month_date) where year_month_date >= date(2018,1,1)

Can I calculate an aggregate duration over multiple rows with a single row per day?

I'm creating an Absence Report for HR. The Absence Data is stored in the database as a single row per day (the columns are EmployeeId, Absence Date, Duration). So if I'm off work from Tuesday 11 February 2020 to Friday 21 February 2020 inclusive, there will be 9 rows in the table:
11 February 2020 - 1 day
12 February 2020 - 1 day
13 February 2020 - 1 day
14 February 2020 - 1 day
17 February 2020 - 1 day
18 February 2020 - 1 day
19 February 2020 - 1 day
20 February 2020 - 1 day
21 February 2020 - 1 day
(see screenshot below)
HR would like to see a single entry in the report for a contiguous period of absence:
My question is - without using a cursor, how can I calculate the is in SQL (even more complicated because I have to do this using Linq to SQL, but I might be able to swap this out for a stored procedure. Note that the criterion for contiguous data is adjacent working days EXCLUDING weekends and bank holidays. I hope I've made myself clear ... apologies if not.
This is a form of gaps-and-islands. In this case, use lag() to see if two vacations overlap and then a cumulative sum:
select employee, min(absent_from), max(absent_to)
from (select t.*,
sum(case when prev_absent_to = dateadd(day, -1, absent_from) then 0 else 1
end) over (partition by employee order by absent_to) as grp
from (select t.*,
lag(absent_to) over (partition by employee order by absent_from) as prev_absent_to
from t
) t
) t
group by employee, grp;
If you need to deal with holidays and weekends, then you need a calendar table.

Percent of change by year and month

I have code that distinctly counts authorizations grouped by month and year.
I added a calculated field to show the percent of change but my issue is I only want to get this percentage between the years by month.
My code calculates the percent for each previous row. which when pulled into SSRS displays the incorrect value after the for column.
Select D.Month
,D.Year
,count( distinct D.authorization_number) [Admission Events]
,CAST(lag(Count(distinct D.authorization_number), 1) over (order by D.month) - Count(distinct D.authorization_number) as FLOAT) / CAST(Count(distinct D.authorization_number)as FLOAT) [Admission Events Pct]
From #Detail D
Group BY D.Month
,D.Year
In these results I would like to only display the pct for year 2018 in SSRS.
Month Year Admission Events Admission Events Pct
1 2017 5919 NULL
1 2018 6057 -0.0227835562159485
2 2017 5302 0.142399094681252
2 2018 5234 0.0129919755445166
3 2017 5548 -0.0565969718817592
3 2018 5389 0.0295045462980145
4 2017 5128 0.0508970358814353
4 2018 5503 -0.0681446483736144
5 2017 5768 -0.0459431345353675
5 2018 5708 0.0105115627189909
6 2017 5461 0.0452298113898553
6 2018 2606 1.09554873369148
Is this what you want?
select t.*
from (<your query here>) t
where year = 2018;
You need a subquery or CTE so the where doesn't interfere with the lag().

Getting Monthly Data

I want to extract all budget entries charged to the current year and cumulated over each month after .In January, taking the total over January, February take accumulated of January plus accumulated February...
I started with this query :
IF OBJECT_ID('tempdb..#BudgetTransTmp') IS NOT NULL
DROP TABLE #BudgetTransTmp
Select
Row_number() over(ORDER BY YEAR(BTLine.DATE),MONTH(BTLine.DATE)) as RowNumber,
COMBINATION.DISPLAYVALUE,
BTLine.LedgerDimension AS LedgerDimension,
MIN(BTLine.TransactionCurrencyAmount) AS Amount,
SUM(BTLine.TransactionCurrencyAmount)
OVER (ORDER BY YEAR(BTLine.DATE),MONTH(BTLine.DATE),BTLine.LedgerDimension,COMBINATION.DISPLAYVALUE ) AS SUM,
YEAR(BTLine.DATE) AS Year ,
MONTH(BTLine.DATE) AS MONTH
INTO #BudgetTransTmp
FROM MicrosoftDynamicsAX.dbo.BudgetTransactionLine AS BTLine
--Get Display value
INNER JOIN MicrosoftDynamicsAX.dbo.DIMENSIONATTRIBUTEVALUECOMBINATION AS COMBINATION
ON COMBINATION.RECID = BTLine.LEDGERDIMENSION
GROUP BY
BTLine.LedgerDimension,
YEAR(BTLine.DATE),
MONTH(BTLine.DATE)
ORDER BY RowNumber
The result is :
LedgerDimension Amount SUM Year Month Display
1 22565448266 850.00 850.00 2012 8 601200-001-027--
2 22565448265 1700.00 2550.0 2012 12 601200-002-027--
3 22565448266 2700.00 5250.00 2012 12 601200-001-027--
4 22565448267 650.00 5900.00 2012 12 601400-002-027--
5 22565448268 1100.00 7000.00 2012 12 601400-001-027--
But i want to get
LedgerDimension Amount SUM Year Month Display
1 22565448266 850.00 850.00 2012 8 601200-001-027--
2 22565448265 1700.00 1700.0 2012 12 601200-002-027--
3 22565448266 2700.00 3350.00 2012 12 601200-001-027--
4 22565448267 650.00 650.00 2012 12 601400-002-027--
5 22565448268 1100.00 1100.00 2012 12 601400-001-027--
I think my COMBINATION of ORDER by (primary key) must be betwwen LedgerDimension ,Year , Month , Display
Any help in this regards
I think what you need to do is:
SUM(BTLine.TransactionCurrencyAmount)
OVER (PARTITION BY BTLine.LedgerDimension ORDER BY YEAR(BTLine.DATE),MONTH(BTLine.DATE),BTLine.LedgerDimension,COMBINATION.DISPLAYVALUE ) AS SUM
let me know if this works.

Getting a variable end of year date and value from MS Access table using SQL

I have some data is that is daily (day on day) closing figures for a tracked supply and is in one MS Access table that has 2 columns - Dates (the date), PXLast(the day's closing figure)).
I have daily data from Jan 1991 to Aug 2013 and I wanted to get the percentage change of PXLast at every year end compared to last year year end as follows:
Year | Percentage Change of PXLast(Year on Year)
1991 | 15.2%
1992 | 9.2%
The year end date varies (not always 31st ) and I am going about getting the last PXLast value by:
1.Get the max date in Dec every year: results in MyYear, MyMonth, MyDay
2.Combine it using DateSerial(MyYear, MyMonth, MyDay)
3.Join the resulting query to the table and inner join on the date column
4.Get the PXLast value
SELECT EndDates.EndDates, NSE20.PX_LAST AS LookPoint
FROM NSE20 INNER JOIN
(SELECT DateSerial([MyYear],[MyMonth],[MyDay])
AS EndDates FROM (SELECT 12 AS MyMonth, MyDay, MyYear FROM
(SELECT Max(Day([Dates])) AS MyDay, Year([Dates]) AS MyYear
FROM NSE20 WHERE (((Month([Dates]))=12))
GROUP BY Year([Dates])) AS EndYearValues)
AS EndValueDates)
AS EndDates ON NSE20.Dates = EndDates.EndDates;
Could anyone assist me get the corresponding value using a query for previous year end
eg for 29 Dec 2006, it should show the current value and show the value for 31 Dec 2005
in the same row ie
Year | Current Year End| Previous Year End
2005 | 3449.00 | 4611.19
2006 | 9.2% |3449.00
Any help is appreciated.
Any suggestions to a better way of doing this is very very welcome....
Let's assume that you have some test data in a table named [NSE20] that looks like this
Dates PXLast
---------- ------
2010-07-01 131
2010-12-31 130
2011-11-12 123
2011-12-30 125
2012-01-03 127
2012-12-31 129
I'd start by creating a saved query in Access named [NSE20_year_ends] that identifies the year-end dates by (calendar) year:
SELECT Year(Dates) AS CalendarYear, Max(Dates) AS YearEndDate
FROM NSE20
GROUP BY Year(Dates)
That will produce
CalendarYear YearEndDate
------------ -----------
2010 2010-12-31
2011 2011-12-30
2012 2012-12-31
Then I'd create another saved query named [NSE20_year_end_balances] to extract the closing balances for each year:
SELECT NSE20_year_ends.CalendarYear, NSE20.PXLast
FROM
NSE20
INNER JOIN
NSE20_year_ends
ON NSE20.Dates = NSE20_year_ends.YearEndDate
That will give us
CalendarYear PXLast
------------ ------
2010 130
2011 125
2012 129
Now we can do a self-join on that query to calculate the percentage change
SELECT
y1.CalendarYear,
(y1.PXLast - y0.PXLast) / y0.PXLast * 100 AS PctChange
FROM
NSE20_year_end_balances y1
INNER JOIN
NSE20_year_end_balances y0
ON y0.CalendarYear = y1.CalendarYear - 1
resulting in
CalendarYear PctChange
------------ -----------------
2011 -3.84615384615385
2012 3.2