【问题标题】:Oracle SQL To Select Month-Wise Products Count For Last 6 MonthsOracle SQL 选择过去 6 个月的按月计算的产品计数
【发布时间】:2016-06-13 10:40:43
【问题描述】:

要求

如何为每个产品选择/获取月-年 (MON-YY) 明智的结果? 我尝试将查询编写为:

SELECT * FROM
(
    SELECT  PRODUCT_CODE AS PRODUCT
    ,       EXTRACT (MONTH FROM (UPDATED_DATE))  AS month_num
    ,       PRODUCT_CODE
    FROM    Test_Pivot
)
PIVOT     (    COUNT (PRODUCT_CODE)
          FOR  month_num  IN (  1 AS jan,  2 AS feb,  3 AS mar,  4 As apr,  5 as may,  6 AS jun,
                                7 AS jul,  8 AS aug,  9 AS sep,  10 As oct,  11 as nov,  12 AS dec
                             )                             
          );

我得到了结果,但无论年份如何,它都会给出完整的计数。我不知道如何修改 SQL 以限制从当前月份到最后 6 个月的计数。我希望将 Months 列动态显示为“MON-YY”,而不仅仅是下面示例格式中描述的“MON”

   PRODUCT  JAN-16  FEB-16  MAR-16  APR-16  MAY-16  JUN-16
-------------------------------------------------------------
      D        1       0       1       0       0       2
      A        1       0       2       0       4       1
      B        1       0       2       1       1       0
      C        0       0       1       0       4       1
  • 以上示例中的数据仅用于描述,(6-16 为当前月份)

示例表

CREATE TABLE Test_Pivot (
  id            NUMBER,
  customer_id   NUMBER,
  product_code  VARCHAR2(5),
  quantity      NUMBER,
  Updated_date          date
);

样本数据

INSERT INTO Test_Pivot VALUES (1, 1, 'A', 10, sysdate);
INSERT INTO Test_Pivot VALUES (2, 1, 'B', 20, sysdate-50);
INSERT INTO Test_Pivot VALUES (3, 1, 'C', 30, sysdate-90);
INSERT INTO Test_Pivot VALUES (4, 2, 'A', 40, sysdate-75);
INSERT INTO Test_Pivot VALUES (5, 2, 'C', 50, sysdate-25);
INSERT INTO Test_Pivot VALUES (6, 3, 'A', 60, sysdate-20);
INSERT INTO Test_Pivot VALUES (7, 3, 'B', 70, sysdate-80);
INSERT INTO Test_Pivot VALUES (8, 3, 'C', 80, sysdate-40);
INSERT INTO Test_Pivot VALUES (9, 3, 'D', 90, sysdate-5);
INSERT INTO Test_Pivot VALUES (10, 4, 'A', 100, sysdate-35);
INSERT INTO Test_Pivot VALUES (11, 2, 'A', 40, sysdate-75);
INSERT INTO Test_Pivot VALUES (12, 2, 'C', 50, sysdate-25);
INSERT INTO Test_Pivot VALUES (13, 3, 'A', 60, sysdate-20);
INSERT INTO Test_Pivot VALUES (14, 3, 'B', 70, sysdate-80);
INSERT INTO Test_Pivot VALUES (15, 3, 'C', 80, sysdate-40);
INSERT INTO Test_Pivot VALUES (16, 3, 'D', 90, sysdate-5);
INSERT INTO Test_Pivot VALUES (17, 4, 'A', 100, sysdate-35);
INSERT INTO Test_Pivot VALUES (18, 3, 'B', 60, sysdate-400);
INSERT INTO Test_Pivot VALUES (19, 3, 'C', 70, sysdate-365);
INSERT INTO Test_Pivot VALUES (20, 3, 'D', 80, sysdate-450);
INSERT INTO Test_Pivot VALUES (21, 3, 'A', 90, sysdate-500);
INSERT INTO Test_Pivot VALUES (22, 4, 'A', 100, sysdate-555);
INSERT INTO Test_Pivot VALUES (23, 2, 'B', 40, sysdate-543);
INSERT INTO Test_Pivot VALUES (24, 2, 'B', 50, sysdate-150);
INSERT INTO Test_Pivot VALUES (25, 3, 'D', 60, sysdate-151);

【问题讨论】:

    标签: sql oracle oracle11g pivot


    【解决方案1】:

    试试:

    SELECT * FROM
    (
        SELECT  PRODUCT_CODE AS PRODUCT
        ,       EXTRACT (YEAR FROM (UPDATED_DATE))  AS year_num
        ,       EXTRACT (MONTH FROM (UPDATED_DATE))  AS month_num
        ,       PRODUCT_CODE
        FROM    Test_Pivot
    )
    PIVOT     (    
              COUNT (PRODUCT_CODE)
              FOR  (year_num, month_num)  IN (  
                   (2016,1) AS jan_16, (2016,2) AS feb_16, (2016,3) AS mar_16,
                   (2016,4) AS apr_16, (2016,5) AS may_16, (2016,6) AS jun_16,
                   (2016,7) AS jul_16, (2016,8) AS aug_16, (2016,9) AS sep_16,
                   (2016,10) AS oct_16, (2016,11) AS nov_16, (2016,12) AS dev_16
              )
    );
    

    您不能在静态 SQL 中使年份和月份“动态显示”和“自动调整为仅显示最后 6 个月”,PIVOT 子句不是动态的,您必须列出所有值对:(2014,1) ...... (2027,12) in它。
    但是,您可以进行动态查询(使用动态 SQL),但这是此答案之外的单独主题。

    ====== 编辑 =============
    如果您只需要最近 6 个月的结果,并且不希望将确切的月份名称作为列名(Feb、Apr 等),那么您可以使用如下查询:

    SELECT * FROM
    (
        SELECT  PRODUCT_CODE AS PRODUCT
    
        ,       EXTRACT (MONTH FROM (sysdate)) - EXTRACT (MONTH FROM (UPDATED_DATE))  AS month_num
        ,       PRODUCT_CODE
        FROM    Test_Pivot
        WHERE UPDATED_DATE >= trunc( sysdate, 'MM' )  - interval '6' month
    )
    PIVOT     (    
              COUNT (PRODUCT_CODE)
              FOR  (month_num)  IN (  
                 0 as current_month, 
                 1 as previous_month, 
                 2 as two_months_bef_curr_month, 
                 3  as three_months_bef_curr_month,
                 4 as four_months_bef_curr_month, 
                 5 as five_months_bef_curr_month
                                 )                             
              );
    

    【讨论】:

    • 我确实意识到 Pivot 子句不是动态的。有什么方法可以在不使用 Pivot 的情况下实现要求?我能够像下面的 SQL 一样获得最后一个 Month_Year 的结果,但是很难使用它。 select to_char( add_months( start_date, level-1 ), 'MON-YY' ) Month_Year from (select add_months(trunc(sysdate, 'MON'), -5) start_date, trunc(sysdate, 'MON') END_DATE from dual) connect by level <= months_between( trunc(end_date,'MM'), trunc(start_date,'MM') ) + 1;
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-23
    • 2021-02-18
    • 1970-01-01
    • 2021-10-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多