将维度添加到从临时表中查询的非规范化连接列

时间:2018-03-12 15:40:53

标签: sql oracle plsql denormalization

我从oracle数据库查询两个表。 POS.SNAPSHOT_SUMMARY_LOG包含从今天到未来的所有预订订单的每日快照。 POS.SALES_SUMMARY_LOG包含截至昨天的最终销售历史记录。我正在尝试创建一个非规范化表,其中包含一个在不同时间点(即WINDOWS)具有销售数字的列。下面的查询运行良好,速度很快。我为每个窗口的每个总和得到一列。查看2/26 / 18-3 / 26/18 windows_query的结果。 (PREVIOUS_YEAR__DATE列是与上一年最相似的工作日,与上一年的日历日期不同) 但是,我无法弄清楚如何将PRODUCT_CATEGORY,CUSTOMER_CATEGORY,SALES_CHANNEL的维度分组到结果中,以便查询快速运行。

    WITH SNAP AS( SELECT 
    TRUNC(SYSDATE,'DDD')-SNAPSHOT_DATE AS WINDOW, CURRENT_YEAR_DATE, PREVIOUS_YEAR__DATE, PRODUCT_CATEGORY, CUSTOMER_CATEGORY, SALES_CHANNEL, QUANTITY, REVENUE 
    FROM POS.SNAPSHOT_SUMMARY_LOG
    WHERE (SNAPSHOT_DATE IN (TRUNC(SYSDATE,'DDD'), TRUNC(SYSDATE,'DDD')-7, TRUNC(SYSDATE,'DDD')-365,TRUNC(SYSDATE,'DDD')-372))),

    HIST AS  (SELECT CURRENT_YEAR_DATE, PREVIOUS_YEAR__DATE, PRODUCT_CATEGORY, CUSTOMER_CATEGORY, SALES_CHANNEL, QUANTITY, REVENUE 
    FROM POS.SALES_SUMMARY_LOG)

    SELECT DISTINCT SNAP.CURRENT_YEAR_DATE, SNAP.PREVIOUS_YEAR__DATE,

    CONCAT(SNAP0.REVENUE,HIST0.REVENUE)+0 AS REVENUE0,
    CONCAT(SNAP7.REVENUE,HIST7.REVENUE)+0 AS REVENUE7,
    CONCAT(SNAP365.REVENUE,HIST365.REVENUE)+0 AS REVENUE365,
    CONCAT(SNAP372.REVENUE,HIST372.REVENUE)+0 AS REVENUE372,

    CONCAT(SNAP0.QUANTITY,HIST0.QUANTITY)+0 AS QUANTITY0,
    CONCAT(SNAP7.QUANTITY,HIST7.QUANTITY)+0 AS QUANTITY7,
    CONCAT(SNAP365.QUANTITY,HIST365.QUANTITY)+0 AS QUANTITY365,
    CONCAT(SNAP372.QUANTITY,HIST372.QUANTITY)+0 AS QUANTITY372

    FROM SNAP
    LEFT OUTER JOIN (SELECT CURRENT_YEAR_DATE, sum(REVENUE) AS REVENUE, sum(QUANTITY) AS QUANTITY FROM SNAP WHERE WINDOW=0 GROUP BY CURRENT_YEAR_DATE) SNAP0 ON SNAP.CURRENT_YEAR_DATE=SNAP0.CURRENT_YEAR_DATE 
    LEFT OUTER JOIN (SELECT CURRENT_YEAR_DATE, sum(REVENUE) AS REVENUE, sum(QUANTITY) AS QUANTITY FROM SNAP WHERE WINDOW=7 GROUP BY CURRENT_YEAR_DATE) SNAP7 ON SNAP.CURRENT_YEAR_DATE=SNAP7.CURRENT_YEAR_DATE
    LEFT OUTER JOIN (SELECT CURRENT_YEAR_DATE, sum(REVENUE) AS REVENUE, sum(QUANTITY) AS QUANTITY FROM SNAP WHERE WINDOW=365 GROUP BY CURRENT_YEAR_DATE ) SNAP365 ON SNAP.PREVIOUS_YEAR_DATE=SNAP365.CURRENT_YEAR_DATE
    LEFT OUTER JOIN (SELECT CURRENT_YEAR_DATE, sum(REVENUE) AS REVENUE, sum(QUANTITY) AS QUANTITY FROM SNAP WHERE WINDOW=372  GROUP BY CURRENT_YEAR_DATE) SNAP372 ON SNAP.PREVIOUS_YEAR_DATE=SNAP372.CURRENT_YEAR_DATE
    LEFT OUTER JOIN (SELECT CURRENT_YEAR_DATE, sum(REVENUE) AS REVENUE, sum(QUANTITY) AS QUANTITY FROM HIST WHERE CURRENT_YEAR_DATE<TRUNC(SYSDATE,'DDD')-0 GROUP BY CURRENT_YEAR_DATE) HIST0 ON SNAP.CURRENT_YEAR_DATE=HIST0.CURRENT_YEAR_DATE
    LEFT OUTER JOIN (SELECT CURRENT_YEAR_DATE, sum(REVENUE) AS REVENUE, sum(QUANTITY) AS QUANTITY FROM HIST WHERE CURRENT_YEAR_DATE<TRUNC(SYSDATE,'DDD')-7 GROUP BY CURRENT_YEAR_DATE) HIST7 ON SNAP.CURRENT_YEAR_DATE=HIST7.CURRENT_YEAR_DATE
    LEFT OUTER JOIN (SELECT CURRENT_YEAR_DATE, sum(REVENUE) AS REVENUE, sum(QUANTITY) AS QUANTITY FROM HIST WHERE CURRENT_YEAR_DATE<TRUNC(SYSDATE,'DDD')-365 GROUP BY CURRENT_YEAR_DATE) HIST365 ON SNAP.PREVIOUS_YEAR_DATE=HIST365.CURRENT_YEAR_DATE
    LEFT OUTER JOIN (SELECT CURRENT_YEAR_DATE, sum(REVENUE) AS REVENUE, sum(QUANTITY) AS QUANTITY FROM HIST WHERE CURRENT_YEAR_DATE<TRUNC(SYSDATE,'DDD')-372 GROUP BY CURRENT_YEAR_DATE) HIST372 ON SNAP.PREVIOUS_YEAR_DATE=HIST372.CURRENT_YEAR_DATE
WHERE SNAP.CURRENT_YEAR_DATE BETWEEN TRUNC(SysDate,'YEAR') AND ADD_MONTHS(TRUNC(TRUNC(SysDate,'YEAR'),'Y'),15)

1 个答案:

答案 0 :(得分:0)

我认为你可以使用条件聚合重写你的查询,它应该比你当前的查询更高效。

E.g。我想你可以把它重写为:

SELECT current_year_date,
       previous_year__date,
       SUM(CASE WHEN trunc(sysdate) - snapshot_date = 0 THEN revenue END) snap_revenue0,
       SUM(CASE WHEN trunc(sysdate) - snapshot_date = 7 THEN revenue END) snap_revenue7,
       SUM(CASE WHEN trunc(sysdate) - snapshot_date = 365 THEN revenue END) snap_revenue365,
       SUM(CASE WHEN trunc(sysdate) - snapshot_date = 372 THEN revenue END) snap_revenue372,
       SUM(CASE WHEN CURRENT_YEAR_DATE < (trunc(sysdate) - 0 THEN revenue END) hist_revenue0,
       SUM(CASE WHEN CURRENT_YEAR_DATE < (trunc(sysdate) - 7 THEN revenue END) hist_revenue7,
       SUM(CASE WHEN CURRENT_YEAR_DATE < (trunc(sysdate) - 365 THEN revenue END) hist_revenue365,
       SUM(CASE WHEN CURRENT_YEAR_DATE < (trunc(sysdate) - 372 THEN revenue END) hist_revenue372,
       SUM(CASE WHEN trunc(sysdate) - snapshot_date = 0 THEN quantity END) snap_quantity0,
       SUM(CASE WHEN trunc(sysdate) - snapshot_date = 7 THEN quantity END) snap_quantity7,
       SUM(CASE WHEN trunc(sysdate) - snapshot_date = 365 THEN quantity END) snap_quantity365,
       SUM(CASE WHEN trunc(sysdate) - snapshot_date = 372 THEN quantity END) snap_quantity372,
       SUM(CASE WHEN CURRENT_YEAR_DATE < (trunc(sysdate) - 0 THEN quantity END) hist_quantity0,
       SUM(CASE WHEN CURRENT_YEAR_DATE < (trunc(sysdate) - 7 THEN quantity END) hist_quantity7,
       SUM(CASE WHEN CURRENT_YEAR_DATE < (trunc(sysdate) - 365 THEN quantity END) hist_quantity365,
       SUM(CASE WHEN CURRENT_YEAR_DATE < (trunc(sysdate) - 372 THEN quantity END) hist_quantity372
FROM   pos.snapshot_summary_log
GROUP BY current_year_date,
         previous_year__date;

我不太明白你的意思&#34;添加PRODUCT_CATEGORY,CUSTOMER_CATEGORY,SALES_CHANNEL&#34;的尺寸;如果您的意思是希望将结果与这些附加列分组,那么只需将它们添加到上面的选择列中并按列表分组,例如:

SELECT current_year_date,
       previous_year__date,
       product_category,
       customer_category,
       sales_channel,
       <SUM columns>
FROM   pos.snapshot_summary_log
GROUP BY current_year_date,
         previous_year__date,
         product_category,
         customer_category,
         sales_channel;

我没有对列做过任何事情;你可能想要在其周围抛出一个外部查询,将snap和hist列添加到一起,或者可能是COALESCEs,但是我会把它留给你决定。