【问题标题】:Oracle : sum this and this and this in a single queryOracle:在一个查询中总结这个和这个和这个
【发布时间】:2013-01-30 23:53:10
【问题描述】:

我的订单表上有上周的订单以及送货司机的 ID。它看起来有点像这样:

ORDERDATE,    ORDERNO,    DRIVER
23/01/2013,    901398503,    1
23/01/2013,    901332159,    1
23/01/2013,    901334158,    2
24/01/2013,    901338455,    1
25/01/2013,    902907513,    1
25/01/2013,    902338553,    2
25/01/2013,    903936533,    2
27/01/2013,    903944523,    1
27/01/2013,    903981522,    2
27/01/2013,    911334951,    1
28/01/2013,    911338851,    1
28/01/2013,    911339259,    1
28/01/2013,    912332555,    2
28/01/2013,    912336650,    2
29/01/2013,    912337655,    1
29/01/2013,    913969582,    1
29/01/2013,    913973583,    1
29/01/2013,    913982552,    1
29/01/2013,    916379158,    1

我想选择 ORDERDATE、ORDERCOUNT、DRIVER_1_COUNT、DRIVER_2_COUNT。

所以,日期 |总订单 |司机 1 的总订单 |司机 2 的总订单

另外,如果 ORDERDATE、ORDERCOUNT、DRIVER_1_COUNT 或 DRIVER_2_COUNT 为 0(或 null),我需要零。

(在 oracle 中)我可以为上周的每一天选择日期,并为每一天选择零订单计数(占位符),如下所示:

select 
 TRUNC(NEXT_DAY(sysdate,'SUNDAY')-7 +i) ORDERDATE,
 0 as ORDERCOUNT   
from
 (select rownum i from all_objects where rownum < 8)

我应该能够使用此输出来确保最终结果中没有缺少日期(本例中 26 日没有订单)

ORDERDATE,ORDERCOUNT
23/01/2013,0
24/01/2013,0
25/01/2013,0
26/01/2013,0
27/01/2013,0
28/01/2013,0
29/01/2013,0

我需要这个输出:

ORDERDATE,ORDERCOUNT,DRIVER_1_COUNT,DRIVER_2_COUNT
23/01/2013,3,2,1
24/01/2013,1,1,0
25/01/2013,3,1,2
26/01/2013,0,0,0
27/01/2013,3,2,1
28/01/2013,4,2,2
29/01/2013,5,5,0

我可以得到 ORDERDATE & ORDERCOUNT(simple sum) 并与其他查询联合以避免丢失天数,但我也不知道如何为每个驱动程序求和。

提前感谢您的帮助。

埃德

【问题讨论】:

  • 查看sum(case when ...

标签: sql oracle


【解决方案1】:

在 Oracle 11g 中,您可以这样做:-

SELECT *
FROM orders
PIVOT (
  COUNT( ORDERNO )
  FOR DRIVER IN (1,2,3)
)

更多解释见pivot and unpivot queries in 11g

【讨论】:

    【解决方案2】:

    首先你需要总结和交叉表结果:

    SELECT ORDERDATE, SUM(ORDERCOUNT) ORDERCOUNT, 
    SUM(DECODE(DRIVER,1,ORDERCOUNT,0)) DRIVER_1_COUNT, 
    SUM(DECODE(DRIVER,2,ORDERCOUNT,0)) DRIVER_2_COUNT
    FROM (
        SELECT ORDERDATE, DRIVER, COUNT(*) ORDERCOUNT
        FROM YourTable
        GROUP BY ORDERDATE, DRIVER
    ) S
    GROUP BY  ORDERDATE
    

    在 Oracle 中可能有更聪明的方法来做到这一点

    然后你需要通过外部连接到你的日期来填写空白:

    (请注意,上面的查询在此查询中别名为“T”:)

    SELECT D.ORDERDATE, 
    NVL(T.ORDERCOUNT,0) ORDERCOUNT, 
    NVL(T.DRIVER_1_COUNT,0) DRIVER_1_COUNT, 
    NVL(T.DRIVER_1_COUNT,0) DRIVER_2_COUNT
    FROM 
    (
    SELECT ORDERDATE, SUM(ORDERCOUNT) ORDERCOUNT, 
    SUM(DECODE(DRIVER,1,ORDERCOUNT,0)) DRIVER_1_COUNT, 
    SUM(DECODE(DRIVER,2,ORDERCOUNT,0)) DRIVER_2_COUNT
    FROM 
        (
        SELECT ORDERDATE, DRIVER, COUNT(*) ORDERCOUNT
        FROM YourTable
        GROUP BY ORDERDATE, DRIVER
        ) S
    GROUP BY  ORDERDATE
    ) T
    RIGHT OUTER JOIN
    (
    SELECT
    TRUNC(NEXT_DAY(sysdate,'SUNDAY')-7 +i) ORDERDATE
    FROM (select rownum i from all_objects where rownum < 8)
    ) D
    ON D.ORDERDATE = T.ORDERDATE
    

    【讨论】:

      【解决方案3】:

      您必须从子查询中进行选择。这样的事情应该可以工作。

      select orderdate, ordercount, sum(driver1) driver1count, sum(driver2) driver2count
      from (
      select orderdate
      , case when driver = 1 then 1 else 0 end driver1
      , case when driver = 2 then 1 else 0 end driver2
      , count(*) ordercount
      
      from yourtable
      
      where whatever
      
      group by orderdate
      , case when driver = 1 then 1 else 0 end driver1
      , case when driver = 2 then 1 else 0 end driver2
      
      ) you_need_an_alias_here
      
      group by orderdate, ordercount
      
      order by orderdate
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-13
        • 2020-03-19
        • 1970-01-01
        • 1970-01-01
        • 2013-06-04
        • 2020-04-18
        相关资源
        最近更新 更多