【发布时间】:2021-11-24 23:39:38
【问题描述】:
这个问题的标题感觉有点奇怪,所以如果你能想象出更好的标题,请随时提供帮助。
你好,
想象一下这样的情况 - 有一个包含 3 列的“Sales”表:date、store 和 sale_price,每一行表示单个项目销售:
date | store | sale_price
---------------+---------+------------
2021-09-01 | foo | 15
2021-09-01 | foo | 10
2021-09-01 | foo | 10
2021-09-01 | bar | 5
2021-09-02 | foo | 30
2021-09-02 | bar | 40
2021-09-02 | bar | 20
etc...
我要做的是创建一个按date 和store 分组的查询,并计算每家商店每天售出的商品数量(因此,不考虑价格)。到目前为止,这很容易,但出于可视化目的,我还尝试添加一个额外的行,该行每天还包括销售总数。
这是我正在寻找的最终结果:
date | store | sales_count
---------------+-------------+------------
2021-09-01 | foo | 3
2021-09-01 | bar | 1
2021-09-01 | aggregate | 4
2021-09-02 | foo | 1
2021-09-02 | bar | 2
2021-09-02 | aggregate | 3
etc...
我知道我可以通过 UNION ALL 来创建它,但它不是超级高效,因为它会扫描原始表两次:
SELECT date,
store,
count(sale_price) AS sales_count
FROM sales
GROUP BY 1, 2
UNION ALL
SELECT date,
'aggregate' AS store,
count(sale_price) AS sales_count
FROM sales
GROUP BY 1
我也知道我可以使用over() 子句创建一个额外的列,并避免两次扫描“销售”,但是我会有两个不同的列,而不是像我正在寻找的那样:
SELECT date,
store,
count(sale_price) AS sales_count,
sum(count(sale_price)) over(PARTITION BY date) AS sales_per_day
FROM sales
GROUP BY 1, 2
--->
date | store | sales_count | sales_per_day
---------------+-------------+--------------+-----------------
2021-09-01 | foo | 3 | 4
2021-09-01 | bar | 1 | 4
2021-09-02 | foo | 1 | 3
2021-09-02 | bar | 2 | 3
etc...
是否有可能在不扫描两次的情况下实现我想要做的事情?最后两列(sales_count 和sales_per_day)可以以某种方式合并吗?
提前感谢您的帮助。
【问题讨论】:
-
我认为您需要 GROUP BY GROUPING SETS 语法。这是一个很好的例子,一目了然,我认为:sqlservertutorial.net/sql-server-basics/…
-
@JS 有意思,我去看看谢谢
-
@JS 天哪,太棒了!我已经在 presto 中写了大约 2 年的查询,但我不知道这个东西存在。您应该将其设为答案,以便我将其标记为已接受。