如何根据各种条件进行汇总

时间:2019-12-26 23:07:42

标签: sql oracle aggregate-functions

让我说我有一个表,存储一段时间内的itemID,Date和total_shipped:

ItemID | Date      | Total_shipped
__________________________________
  1    | 1/20/2000 |   2
  2    | 1/20/2000 |   3
  1    | 1/21/2000 |   5
  2    | 1/21/2000 |   4
  1    | 1/22/2000 |   1
  2    | 1/22/2000 |   7
  1    | 1/23/2000 |   5
  2    | 1/23/2000 |   6

现在,我想基于多个时间段进行汇总。例如,我想知道每两天总共寄出了多少个物品。因此,所需的输出应类似于:

ItemID | Jan20-Jan21 | Jan22-Jan23 | Jan20-Jan23
_____________________________________________
  1    |  7          |  6          |  13
  2    |  7          |  13         |  20

如何以最有效的方式做到这一点 我知道我可以进行三个不同的子查询,但是我认为应该有更好的方法。我的真实数据很大,因此需要考虑几个不同的时间段。 e。在我真正的问题中,我想要current_week,last_week,two_weeks_ago,three_weeks_ago,last_month,two_months_ago,Three_months_ago的已发货商品,所以我认为编写7个不同的子查询不是一个好主意。 这是我已经可以运行但对于数据库来说非常昂贵的一般想法

WITH 
sq1 as (
SELECT ItemID, sum(Total_shipped) sum1
FROM table
WHERE Date BETWEEN '1/20/2000' and '1/21/2000'
GROUP BY ItemID),
sq2 as (
SELECT ItemID, sum(Total_Shipped) sum2
FROM table
WHERE Date BETWEEN '1/22/2000' and '1/23/2000'
GROUP BY ItemID),
sq3 as(
SELECT ItemID, sum(Total_Shipped) sum3
FROM Table
GROUP BY ItemID)
SELECT ItemID, sq1.sum1, sq2.sum2, sq3.sum3
FROM Table 
JOIN sq1 on Table.ItemID = sq1.ItemID
JOIN sq2 on Table.ItemID = sq2.ItemID
JOIN sq3 on Table.ItemID = sq3.ItemID

2 个答案:

答案 0 :(得分:2)

我不知道您为什么用多个数据库标记了这个问题。

无论如何,您可以在 oracle 中使用conditional aggregation,如下所示:

select
    item_id, 
    sum(case when "date" between date'2000-01-20' and date'2000-01-21' then total_shipped end) as "Jan20-Jan21",
    sum(case when "date" between date'2000-01-22' and date'2000-01-23' then total_shipped end) as "Jan22-Jan23",
    sum(case when "date" between date'2000-01-20' and date'2000-01-23' then total_shipped end) as "Jan20-Jan23"
from my_table
group by item_id

干杯!

答案 1 :(得分:1)

使用FILTER:

select
    item_id, 
    sum(total_shipped) filter (where date between '2000-01-20' and '2000-01-21') as "Jan20-Jan21",
    sum(total_shipped) filter (where date between '2000-01-22' and '2000-01-23') as "Jan22-Jan23",
    sum(total_shipped) filter (where date between '2000-01-20' and '2000-01-23') as "Jan20-Jan23"
from my_table
group by 1

 item_id | Jan20-Jan21 | Jan22-Jan23 | Jan20-Jan23
---------+-------------+-------------+-------------
       1 |           7 |           6 |          13
       2 |           7 |          13 |          20
(2 rows)

Db<>fiddle.