oracle一个时间段内,分组统计数据。自然月下的统计很简单,但是如果按照绩效的考核月来计算呢?

计算一个时间段内,以自然月来分组统计的话很简单,直接group by to_char(exportDate,'yyyy-mm') 就行了。
但如果是用考核月,比如说从9月27日到10月26算是一个考核月。要一口气统计一年以内的数据,分成12个考核月,如果不想一次次分开统计,统计12次,那么有什么好的办法能一口气统计了?

第1个回答  2016-08-05

直接写sql的话我能想到的就是直接group by case when

ALTER session SET nls_date_format = 'yyyy-mm-dd';
WITH tmp_sleest AS
  ( SELECT to_date('2016-01-26','yyyy-mm-dd') AS my_date FROM dual
  UNION
  SELECT to_date('2016-02-25','yyyy-mm-dd') FROM dual
  UNION
  SELECT to_date('2016-02-02','yyyy-mm-dd') FROM dual
  UNION
  SELECT to_date('2016-03-07','yyyy-mm-dd') FROM dual
  UNION
  SELECT to_date('2016-01-27','yyyy-mm-dd') FROM dual
  UNION
  SELECT to_date('2015-12-27','yyyy-mm-dd') FROM dual
  UNION
  SELECT to_date('2016-11-29','yyyy-mm-dd') FROM dual
  UNION
  SELECT to_date('2015-12-26','yyyy-mm-dd') FROM dual
  UNION
  SELECT to_date('2017-01-25','yyyy-mm-dd') FROM dual
  UNION
  SELECT to_date('2017-01-31','yyyy-mm-dd') FROM dual
  )
--select * from tmp_sleest;
SELECT
  CASE
    WHEN TO_CHAR(t.my_date, 'mm-dd') BETWEEN '01-27' AND '02-26' THEN '02'
    WHEN TO_CHAR(t.my_date, 'mm-dd') BETWEEN '02-27' AND '03-26' THEN '03'
    WHEN TO_CHAR(t.my_date, 'mm-dd') BETWEEN '03-27' AND '04-26' THEN '04'
    WHEN TO_CHAR(t.my_date, 'mm-dd') BETWEEN '04-27' AND '05-26' THEN '05'
    WHEN TO_CHAR(t.my_date, 'mm-dd') BETWEEN '05-27' AND '06-26' THEN '06'
    WHEN TO_CHAR(t.my_date, 'mm-dd') BETWEEN '06-27' AND '07-26' THEN '07'
    WHEN TO_CHAR(t.my_date, 'mm-dd') BETWEEN '07-27' AND '08-26' THEN '08'
    WHEN TO_CHAR(t.my_date, 'mm-dd') BETWEEN '08-27' AND '09-26' THEN '09'
    WHEN TO_CHAR(t.my_date, 'mm-dd') BETWEEN '09-27' AND '10-26' THEN '10'
    WHEN TO_CHAR(t.my_date, 'mm-dd') BETWEEN '10-27' AND '11-26' THEN '11'
    WHEN TO_CHAR(t.my_date, 'mm-dd') BETWEEN '11-27' AND '12-26' THEN '12'
    WHEN TO_CHAR(t.my_date, 'yyyy-mm-dd') BETWEEN (2016-1)||'-12-27' AND (2016)||'-01-26' THEN '01'
    ELSE '-1' END AS effect_month,
  COUNT(1) AS num
  FROM tmp_sleest t
 WHERE t.my_date BETWEEN to_date((2016-1)||'-12-27') AND to_date((2016)||'-12-26')
 GROUP BY CASE
            WHEN TO_CHAR(t.my_date, 'mm-dd') BETWEEN '01-27' AND '02-26' THEN '02'
            WHEN TO_CHAR(t.my_date, 'mm-dd') BETWEEN '02-27' AND '03-26' THEN '03'
            WHEN TO_CHAR(t.my_date, 'mm-dd') BETWEEN '03-27' AND '04-26' THEN '04'
            WHEN TO_CHAR(t.my_date, 'mm-dd') BETWEEN '04-27' AND '05-26' THEN '05'
            WHEN TO_CHAR(t.my_date, 'mm-dd') BETWEEN '05-27' AND '06-26' THEN '06'
            WHEN TO_CHAR(t.my_date, 'mm-dd') BETWEEN '06-27' AND '07-26' THEN '07'
            WHEN TO_CHAR(t.my_date, 'mm-dd') BETWEEN '07-27' AND '08-26' THEN '08'
            WHEN TO_CHAR(t.my_date, 'mm-dd') BETWEEN '08-27' AND '09-26' THEN '09'
            WHEN TO_CHAR(t.my_date, 'mm-dd') BETWEEN '09-27' AND '10-26' THEN '10'
            WHEN TO_CHAR(t.my_date, 'mm-dd') BETWEEN '10-27' AND '11-26' THEN '11'
            WHEN TO_CHAR(t.my_date, 'mm-dd') BETWEEN '11-27' AND '12-26' THEN '12'
            WHEN TO_CHAR(t.my_date, 'yyyy-mm-dd') BETWEEN (2016-1)||'-12-27' AND (2016)||'-01-26' THEN '01'
          ELSE '-1'
        END
 ORDER BY EFFECT_MONTH;


换个思路, 可以考虑做一张常量表, 来存取这种区间, 然后用现有业务和该常量表关联起来做group by更方便些.

本回答被提问者采纳
相似回答