Reputation: 43
I have a table with year, month, date, project and income columns. Each entry is added on the first of every month.
I have to be able to get the total income for a particular project for every financial year. What I've got so far (which I think kind of works for yearly?) is something like this:
SELECT year, SUM(TotalIncome)
FROM myTable
WHERE ((date Between #1/1/2007# And #31/12/2015#) AND (project='aproject'))
GROUP BY year;
Essentially, rather than grouping the data by year, I would like to group the results by financial year. I have used DatePart('yyyy', date)
and the results are the same.
I'll be running the query from excel to a database. I need to be able to select the number of years (e.g. 2009 to 2014, or 2008 to 2010, etc). I'll be taking the years from user input in excel (taking two dates, i.e. startYear, endYear).
The results from the current query give me, each year would be data from 1st January to 31st December of the same year:
Year | Income
2009 | $123.12
2010 | $321.42
2011 | $231.31
2012 | $426.37
I want the results to look something like this, where each financial year would be 1st July to 30th June of the following year:
FinancialYear | Income
2009-10 | $123.12
2010-11 | $321.42
2011-12 | $231.31
2012-13 | $426.37
If possible, I'd also like to be able to do it per quarter.
Also, if it matters, I have read-only access so I can't make any modifications to the database.
Upvotes: 4
Views: 4907
Reputation: 1422
Since you can't create new tables (read-only access) you can use with
statement before your select to create a financial years "table" usable from your query.
with financial_year as
(
select '2009' as year, '1/1/2009' as start_date, '31/12/2009' as end_date
union
select '2010' as year, '1/1/2010' as start_date, '31/12/2010' as end_date
...
)
SELECT FY.year, SUM (YT.TotalIncome)
FROM YourTable YT
INNER JOIN financial_year FY
ON YT.date >= FY.start_date
and YT.date <= FY.end_date
GROUP BY FY.year
This will work (with minor modifications) with both MS SQL server and Oracle, i'm not sure whats your database tho.
Upvotes: 1
Reputation: 2332
This hasn't been tested but the logic is the same as the answer from SQL query to retrieve financial year data grouped by the year.
SELECT fy.FinancialYear, SUM(fy.TotalIncome)
FROM
(
SELECT
IIF( MONTH(date) >= 7,
YEAR(date) & "-" & YEAR(date)+1,
YEAR(date)-1 & "-" & YEAR(date) ) AS FinancialYear,
TotalIncome
FROM myTable
WHERE date BETWEEN #1/1/2007# AND #31/12/2015#
AND project = 'aproject'
) AS fy
GROUP BY fy.FinancialYear;
Extending this further you can get per quarter as well:
SELECT fy.FinancialQuarter, SUM(fy.TotalIncome)
FROM
(
SELECT
IIF( MONTH(date) >= 10,
"Q2-" & YEAR(date) & "-" & YEAR(date)+1,
IIF( MONTH(date) >= 7,
"Q1-" & YEAR(date) & "-" & YEAR(date)+1,
IIF( MONTH(date) >= 4,
"Q4-" & YEAR(date)-1 & "-" & YEAR(date),
"Q3-" & YEAR(date)-1 & "-" & YEAR(date)
)
)
) AS FinancialQuarter,
TotalIncome
FROM myTable
WHERE date BETWEEN #1/1/2007# AND #31/12/2015#
AND project = 'aproject'
) AS fy
GROUP BY fy.FinancialQuarter;
Upvotes: 5
Reputation: 55816
This is very simple using DateAdd to shift by six months:
SELECT
Format(DateAdd("m", 6, [Date]), "yyyy") & Format(DateAdd("m", 18, [Date]), "\-yy") As FinancialYear,
SUM(TotalIncome) As Income
FROM
myTable
WHERE
([date] Between #1/1/2007# And #31/12/2015#) AND (project="aproject")
GROUP BY
DateAdd("m", 6, [Date]),
Format(DateAdd("m", 6, [Date]), "yyyy") & Format(DateAdd("m", 18, [Date]), "\-yy")
Upvotes: 0
Reputation: 48197
You need create a financial_year
table
financial_year_id int primary key
period varchar
startDate date
endDate date
with this data
1 | 2009-10 | #1/1/2009# | #1/1/2010#
2 | 2010-11 | #1/1/2010# | #1/1/2011#
3 | 2011-12 | #1/1/2011# | #1/1/2012#
4 | 2012-13 | #1/1/2012# | #1/1/2013#
then perfom a join with your original table
SELECT FY.period, SUM (YT.TotalIncome)
FROM YourTable YT
INNER JOIN financial_year FY
ON YT.date >= FY.startDate
and YT.date < FY.endDate
GROUP BY FY.period
For Quarter:
SELECT FY.period, DatePart ('q', date) as quarter, SUM (YT.TotalIncome)
FROM YourTable YT
INNER JOIN financial_year FY
ON YT.date >= FY.startDate
and YT.date < FY.endDate
GROUP BY FY.period, DatePart ('q', date)
NOTE
I wasnt sure if your date
is just date
or datetime
so I went the safest way
if is just date
you could use
1 | 2009-10 | #1/1/2009# | #31/12/2009#
2 | 2010-11 | #1/1/2010# | #31/12/2010#
AND
ON YT.date BETWEEN FY.startDate AND FY.endDate
Upvotes: 4