如何解决数据库统计时的会计年度和会计月份问题

原文链接:http://www.cnblogs.com/JoeDZ/archive/2008/06/30/1232713.html

在数据库中进行数据统计时,通常以会计月份、会计年度作为统计的时间段,例如下面的 SQL 语句:

SELECT Year(f_date) AS Y, Month(f_date) AS M, SUM(f_money) AS totalMoney GROUP BY Year(f_date), Month(f_date);

但是世界各国的会计年度不尽相同,比如中、俄、德等国采用的是 1 月 - 12 月,日、英、加拿大、印度等国采用的是 4 月 至次年 3 月,
美、泰、缅甸等国采用的是 10 月至次年 9 月等等,至于会计月份则更多样,甚至不同的公司会计月份都是不同的。如果使用上面的方法
统计显然不行。比如这样的日期 2008-11-08,对于美国这样的国家实际上应该统计到 2009 年的会计年度中,用上面的语句却会将其统
计到 2008 年,月份是一样的道理。解决办法之一是在数据库中增加计算字段,根据实际的日期计算出其会计年份和月份,不过有时候可能
是在处理一个已有的数据库系统,不允许修改数据库的表结构,此时可以通过 SQL 语句来实现:

例如一个公司的会计年度是 10 月至次年 9 月,会计月份是 23 号至下个月 22 号:

SELECT CASE WHEN (table_2.M > 9) THEN table_2.Y - 1 
       ELSE table_2.Y END AS Y,table_2.M,table_2.totalMoney
FROM
(
 SELECT CASE WHEN (CASE WHEN DAY(f_date) > 22 
                   THEN (MONTH(f_date) + 1) % 13 
                   ELSE MONTH(f_date) END > 9)   
        THEN YEAR(f_date) + 1 
        ELSE YEAR(f_date) END AS Y, 
        
        CASE WHEN DAY(f_date) > 22 
        THEN (MONTH(f_date) + 1) % 13 
        ELSE MONTH(f_date) END AS M, 
        
        SUM(f_money) AS totalMoney
 FROM table_1
 GROUP BY CASE WHEN (CASE WHEN DAY(f_date) > 22 
                    THEN (MONTH(f_date) + 13) % 12 
                    ELSE MONTH(f_date) END > 9)
         THEN YEAR(f_date) + 1 ELSE YEAR(f_date) END,
               
         CASE WHEN DAY(f_date) > 22 
         THEN (MONTH(f_date) + 1) % 13 
         ELSE MONTH(f_date) END
 WITH ROLLUP
)AS table_2

当然这计算会降低查询的速度。
举例:
table_1
f_date          f_money

2008-09-22      1
2008-09-23      3
2008-10-22     5
2008-10-23     7
2009-09-22     11
结果:
Y           M    totalMoney
2008     9         1
2008     NULL    1
2009     9         11
2008     10       8
2008     11       7
2009     NULL   26
NULL NULL 27

转载于:https://www.cnblogs.com/JoeDZ/archive/2008/06/30/1232713.html

上一篇:轻量级爬虫+全文检索解决方案项目——NukeLite(2008-11-14 更新r24版 引入新线程机制)


下一篇:App Widget简单应用