SQL 按财政年度分组数据

SQL group data by financial year

我有一个 table,其中包含年、月、日、项目和收入列。每个条目都会在每个月的第一天添加。

我必须能够获得每个财政年度特定项目的总收入。到目前为止我所得到的(我认为每年都有效?)是这样的:

SELECT year, SUM(TotalIncome)
FROM myTable
WHERE ((date Between #1/1/2007# And #31/12/2015#) AND (project='aproject'))
GROUP BY year;

本质上,我不想按年份分组数据,而是按财政年度对结果进行分组。我用过DatePart('yyyy', date),结果是一样的.

我将 运行 从 excel 到数据库的查询。我需要能够 select 年数(例如 2009 年到 2014 年,或 2008 年到 2010 年等)。我将从 excel 中的用户输入中获取年份(取两个日期,即 startYear、endYear)。

当前查询的结果给我,每年都是同年1月1日到12月31日的数据:

Year           |  Income
2009           |  3.12
2010           |  1.42
2011           |  1.31
2012           |  6.37

我希望结果看起来像这样,其中每个财政年度都是 下一个 年的 7 月 1 日到 6 月 30 日:

FinancialYear  |  Income
2009-10        |  3.12
2010-11        |  1.42
2011-12        |  1.31
2012-13        |  6.37

如果可以的话,我也希望每个季度都能做到。

Also, if it matters, I have read-only access so I can't make any modifications to the database.

您需要创建一个 financial_year table

financial_year_id int primary key
period            varchar
startDate         date
endDate           date

有了这个数据

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#

然后与您的原始 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

季度:

 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)

注意

我不确定你的 datedate 还是 datetime 所以我选择了最安全的方式

如果只是 date 你可以使用

1  |  2009-10  |  #1/1/2009#  | #31/12/2009#
2  |  2010-11  |  #1/1/2010#  | #31/12/2010#

ON YT.date BETWEEN  FY.startDate AND  FY.endDate

使用 DateAdd 移动六个月非常简单:

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") 

这还没有经过测试,但逻辑与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;

进一步扩展,您还可以每季度获得:

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;

由于您无法创建新表(只读访问),您可以在 select 之前使用 with 语句来创建可从查询中使用的财政年度 "table"。

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

这将适用于 MS SQL 服务器和 Oracle(稍作修改),但我不确定您的数据库是什么。