SQL group by fiscal/financial year - sql

Quick question, using the code below I just want to create a field displaying the records fiscal year and then group the results by the year.
The code to retrieve the results works however it does not want to group them by the fiscal year. I just get errors. I have tried multiple combinations using the forums but I can't get it to work. It is doing my head in!
This could be simple to resolve but I can't see it. Could anyone help?
Thanks!
Select m.jobno, m.premid, m.address,m.COMPDATE,
year(dateadd(month, -3, m.COMPDATE)) as FiscalYear
FROM miscvisit m
----- GROUP BY year(dateadd(month, -3, m.COMPDATE))

Try the below query..
SELECT m.jobno
,m.premid
,m.address
,m.COMPDATE
,YEAR(DATEADD(MONTH, - 3, m.COMPDATE)) AS FiscalYear
FROM miscvisit m
GROUP BY m.jobno
,m.premid
,m.address
,m.COMPDATE
,YEAR(DATEADD(MONTH, - 3, m.COMPDATE))

Try this:
Select m.jobno, m.premid, m.address,
year(dateadd(month, -3, m.COMPDATE)) as FiscalYear, sum([SalesField]) as Sales
FROM miscvisit m
GROUP BY
m.jobno, m.premid, m.address,
year(dateadd(month, -3, m.COMPDATE))

Given that you seem to want to return the entire record, perhaps you really want an ORDER BY clause here:
SELECT
jobno,
premid,
address,
COMPDATE,
YEAR(DATEADD(month, -3, COMPDATE)) AS FiscalYear
FROM miscvisit
GROUP BY
YEAR(DATEADD(month, -3, COMPDATE))
ORDER BY
FiscalYear;

Related

I want to get a previous year and month as id from my data but the result is not not correct

select
(year(dt)*100)+month(dt) as month_id,
(year(dt)*100)+month(dt)-1 as month_id_LM,
Level_6 as Model_Name,
max(Unit_PriceOTR) as OTR_Highest,
min(Unit_PriceOTR) as OTR_Lowest
from
edw.[eview].[TB_R_CARPRICEOTR_APM]
where Level_6 = 'TOYOTA YARIS'
group by
(year(dt)*100)+month(dt),
Level_6
order by month_id
--month_id_LM shows month 0 which does not make sense.
You can group by DATEFROMPARTS which will give you the first day in that month. Then you can just subtract a month:
select
v.month_id,
dateadd(month, -1, v.month_id) as month_id_LM,
Level_6 as Model_Name,
max(Unit_PriceOTR) as OTR_Highest,
min(Unit_PriceOTR) as OTR_Lowest
from
edw.[eview].[TB_R_CARPRICEOTR_APM]
cross apply (values
(datefromparts(year(dt), month(dt), 1))
) v(month_id)
where Level_6 = 'TOYOTA YARIS'
group by
v.month_id,
Level_6
Level_6
order by
month_id;
I am pretty sure there are functions to help you. On a quick search, I could find the DATEADD function.
You can read about it here: https://www.w3schools.com/sql/func_sqlserver_dateadd.asp
One of the examples is this one:
Subtract two months from a date, then return the date:
SELECT DATEADD(month, -2, '2017/08/25') AS DateAdd;

How can I add months onto a given date in a SQL Table

I'm trying to write a function to represent when an employees (agents) 6 month review will take place, using date arithmetic by adding on 6 months to their hire date and I can't seem to get it right
SELECT EmpFirstName, EmpLastName,
CAST(DateHired, + 6 MONTH) AS ReviewDate
From Employees
SELECT EmpFirstName, EmpLastName,DATEADD(month, 6, DateHired) DateHired From Employees
With SET you can mutate the value (change the value) but what you really need is a condition to check. The SQL keyword for that is WHERE.
SELECT .... WHERE your conditon FROM ....
If you want a list of all employees who are due for their 6 month review in the current month, you can try this:
SELECT
EmpFirstName,
EmpLastName,
DateHired
FROM Employees
WHERE
DATEADD(month, DATEDIFF(month, 0, DateHired), 0) =
DATEADD(month, DATEDIFF(month, 0, DATEADD(month, -6, GETDATE())), 0)
You can use DATEADD()
SELECT EmpFirstName, EmpLastName, DateHired, DATEADD(month, 6, DateHired) AS Review_Date
From Employees
The idea of updating the DateHired column is not that good. Because if you run the query at two different times, for example be when some new employees joins, it will affect the records of all employees.
Either add a new column for ReviewDate in the table or use some query like the one above to find the ReviewDate
Try this query
SELECT EmpFirstName
,EmpLastName
,DateHired
SET Datehired = DATE_ADD(DateHired, INTERVAL + 6 MONTH)
FROM Employees
https://www.w3schools.com/sql/func_mysql_date_add.asp

How to sum sales by months and compare them

I have a table called SOITEM. In that table the column TOTALPRICE has to be summed and result in the total sales by month, where the column with the dates is called DATELASTFULFILLMENT.
I want to compare sales form Jan 2014 with Jan 2015, then Feb 2014 with Feb 2015 and so forth.
I got this so far, but I'm not sure how continue.
Select SUM(SOITEM.TOTALPRICE)
FROM SOITEM
WHERE DATELASTFULFILLMENT>='2014-01-31' AND DATELASTFULFILLMENT<='2014-01-31'
but it only results in totals from Jan 2014....
Thank you.
You could consider grouping your results using the Month/Year from your date field and then using calculating the SUM() for each of those groups :
SELECT DATEPART(Year, DATELASTFULFILLMENT) AS [Year],
DATEPART(Month, DATELASTFULFILLMENT) AS [Month],
SUM(TOTALPRICE) AS Total
FROM SOITEM
GROUP BY DATEPART(Year, DATELASTFULFILLMENT), DATEPART(Month, DATELASTFULFILLMENT)
ORDER BY [Year], [Month]
You can see an interactive example of this here and results demonstrated below :
This works for MySQL. I assume should be the same for MS SQL.
Select SUM(SOITEM.TOTALPRICE)
FROM SOITEM
WHERE DATELASTFULFILLMENT>='2014-01-31' AND DATELASTFULFILLMENT<='2014-01-31'
UNION
Select SUM(SOITEM.TOTALPRICE)
FROM SOITEM
WHERE DATELASTFULFILLMENT>='2015-01-31' AND DATELASTFULFILLMENT<='2015-01-31'
UNION
Select SUM(SOITEM.TOTALPRICE)
FROM SOITEM
WHERE DATELASTFULFILLMENT>='2014-02-31' AND DATELASTFULFILLMENT<='2014-02-31'
UNION
Select SUM(SOITEM.TOTALPRICE)
FROM SOITEM
WHERE DATELASTFULFILLMENT>='2014-02-31' AND DATELASTFULFILLMENT<='2015-02-31'
Use a nested query within your select statement -- notice the subtraction from the YEAR within the nested query to pull back the previous year's summary:
SELECT MONTH(so2.DATELASTFULFILLMENT) AS MonthFulfilled,
YEAR(so2.DATELASTFULFILLMENT) AS YearFulfilled,
SUM(so2.TOTALPRICE),
(SELECT SUM(SOITEM.TOTALPRICE) FROM SOITEM WHERE MONTH(DATELASTFULFILLMENT) = MONTH(so2.DATELASTFULFILLMENT) AND YEAR(DATELASTFULFILLMENT) = (YEAR(so2.DATELASTFULFILLMENT)-1)) AS LastYearTotal
FROM SOITEM AS so2
GROUP BY MONTH(so2.DATELASTFULFILLMENT), YEAR(so2.DATELASTFULFILLMENT)
Or you could do it like this.
WITH MonthTotal AS
(
SELECT
DATEADD(MONTH, DATEDIFF(MONTH, 0, DATELASTFULFILLMENT), 0) AS MonthDate
, SUM(TOTALPRICE) AS Total
FROM
SOITEM
GROUP BY
DATEADD(MONTH, DATEDIFF(MONTH, 0, DATELASTFULFILLMENT), 0)
)
SELECT
MonthTotal.MonthDate
, MonthTotal.Total
, PreviousYear.Total AS PreviousYearTotal
FROM
MonthTotal
LEFT JOIN MonthTotal AS PreviousYear
ON DATEADD(YEAR, -1, MonthTotal.MonthDate) = PreviousYear.MonthDatee) = PreviousYear.MonthDate
You first group the results based on themonth date, the calculation converts a date to the 1st of the month the date drops in. We then use these results and join back to it getting last years result as well.

How to order by column not in select clause?

Is there a method to work around not being able to sort by a column not in the select clause? I am using datename to grabe month and year, but i need it to be sorted by actual date not alphabetically.
select datename(month, dbo.ITR.ITR_TransDate) as MonthDt,
DATENAME(year, dbo.itr.ITR_TransDate) as YearDt, COUNT(distinct dbo.ITR.ITR_Reason) AS WKCount, COUNT(dbo.itr.itr_reason) AS LineCt
from dbo.ITR
where (ITR_EmployeeID IN (N'robra', N'lewer', N'petam', N'whike', N'mclch', N'ricju')) AND (dbo.ITR.ITR_TransDate >= '1/1/13' AND dbo.itr.ITR_TransDate <= '1/31/14') AND
(dbo.itr.ITR_Reason LIKE 'WO%' OR dbo.itr.ITR_Reason LIKE 'RW%')
group by DATENAME(year, dbo.itr.ITR_TransDate), datename(month, dbo.ITR.ITR_TransDate), MONTH(dbo.itr.itr_transdate)
order by dbo.ITR.ITR_TransDate
the order by i have is failing b/c it isn't in the group by or an aggregate. i can't add it to either b/c there are many many dates that it would return.
You can just use an aggregation function in the order by:
order by min(dbo.ITR.ITR_TransDate)
This should work for your case.
try this
select datename(month, dbo.ITR.ITR_TransDate) as MonthDt,
DATENAME(year, dbo.itr.ITR_TransDate) as YearDt, COUNT(distinct dbo.ITR.ITR_Reason) AS WKCount, COUNT(dbo.itr.itr_reason) AS LineCt
from dbo.ITR
where (ITR_EmployeeID IN (N'robra', N'lewer', N'petam', N'whike', N'mclch', N'ricju')) AND (dbo.ITR.ITR_TransDate >= '1/1/13' AND dbo.itr.ITR_TransDate <= '1/31/14') AND
(dbo.itr.ITR_Reason LIKE 'WO%' OR dbo.itr.ITR_Reason LIKE 'RW%')
group by DATENAME(year, dbo.itr.ITR_TransDate), datename(month, dbo.ITR.ITR_TransDate), MONTH(dbo.itr.itr_transdate)
order by DATENAME(year, dbo.itr.ITR_TransDate), MONTH(dbo.itr.itr_transdate)

How to count number of records per month over a time period

Is there a way to run a query for a specified amount of time, say the last 5 months, and to be able to return how many records were created each month? Here's what my table looks like:
SELECT rID, dateOn FROM claims
SELECT COUNT(rID) AS ClaimsPerMonth,
MONTH(dateOn) AS inMonth,
YEAR(dateOn) AS inYear FROM claims
WHERE dateOn >= DATEADD(month, -5, GETDATE())
GROUP BY MONTH(dateOn), YEAR(dateOn)
ORDER BY inYear, inMonth
In this query the WHERE dateOn >= DATEADD(month, -5, GETDATE()) ensures that it's for the past 5 months, the GROUP BY MONTH(dateOn) then allows it to count per month.
And to appease the community, here is a SQL Fiddle to prove it.
Unlike the other two answers, this will return all 5 months, even when the count is 0. It will also use an index on the onDate column, if a suitable one exists (the other two answers so far are non-sargeable).
DECLARE #nMonths INT = 5;
;WITH m(m) AS
(
SELECT TOP (#nMonths) DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE())-number, 0)
FROM master.dbo.spt_values WHERE [type] = N'P' ORDER BY number
)
SELECT m.m, num_claims = COUNT(c.rID)
FROM m LEFT OUTER JOIN dbo.claims AS c
ON c.onDate >= m.m AND c.onDate < DATEADD(MONTH, 1, m.m)
GROUP BY m.m
ORDER BY m.m;
You also don't have to use a variable in the TOP clause, but this might make the code more reusable (e.g. you could pass the number of months as a parameter).
SELECT
count(rID) as Cnt,
DatePart(Month, dateOn) as MonthNumber,
Max(DateName(Month, dateOn)) as MonthName
FROM claims
WHERE dateOn >= DateAdd(Month, -5, getdate())
GROUP BY DatePart(Month, dateOn)