aCa*_*lla 1 sql postgresql group-by subquery aggregate-functions
我有一个 PostgreSQL 查询,它产生以下结果:
SELECT o.order || '-' || osh.ordinal_number AS order,
o.company,
o.order_total,
SUM(osh.items) AS order_shipment_total,
o.order_type
FROM orders o
JOIN order_shipments osh ON o.order_id = osh.order_id
WHERE o.order = [some order number]
GROUP BY o.order,
o.company,
o.order_total,
o.order_type;
order | company | order_total | order_shipment_total | order_type
-------------------------------------------------------------------
123-1 | A corp. | null | 125.00 | new
123-2 | B corp. | null | 100.00 | new
Run Code Online (Sandbox Code Playgroud)
我需要替换o.order_total(它不能正常工作)并总结 order_shipment_total 列的总和,这样,对于上面的例子,每一行都说 225.00。我需要上面的结果如下所示:
order | company | order_total | order_shipment_total | order_type
-------------------------------------------------------------------
123-1 | A corp. | 225.00 | 125.00 | new
123-2 | B corp. | 225.00 | 100.00 | new
Run Code Online (Sandbox Code Playgroud)
我试过的
1.) 要替换o.order_total,我已经尝试过,SUM(SUM(osh.items))但收到错误消息,提示您不能嵌套聚合函数。
2.) 我试图将整个查询作为子查询并对order_shipment_total列求和,但是当我这样做时,它只是重复列本身。见下文:
SELECT order,
company,
SUM(order_shipment_total) AS order_shipment_total,
order_shipment_total,
order_type
FROM (
SELECT o.order || '-' || osh.ordinal_number AS order,
o.company,
o.order_total,
SUM(osh.items) AS order_shipment_total,
o.order_type
FROM orders o
JOIN order_shipments osh ON o.order_id = osh.order_id
WHERE o.order = [some order number]
GROUP BY o.order,
o.company,
o.order_total,
o.order_type
) subquery
GROUP BY order,
company,
order_shipment_total,
order_type;
order | company | order_total | order_shipment_total | order_type
-------------------------------------------------------------------
123-1 | A corp. | 125.00 | 125.00 | new
123-2 | B corp. | 100.00 | 100.00 | new
Run Code Online (Sandbox Code Playgroud)
3.) 我试图在上面的子查询/查询示例中只包含我实际想要分组的行,因为我觉得我能够在 Oracle SQL 中做到这一点。但是当我这样做时,我收到一条错误消息,提示“列 [名称] 必须出现在 GROUP BY 子句中或用于聚合函数中”。
...
GROUP BY order,
company,
order_type;
ERROR: column "[a column name]" must appear in the GROUP BY clause or be used in an aggregate function.
Run Code Online (Sandbox Code Playgroud)
我该如何实现?我确信子查询将是答案,但我很困惑为什么这种方法不起作用。
您对查询/方法不太了解的事情是,您实际上想要在同一查询行结果中进行两个不同级别的分组。子查询方法对了一半,但是当您执行分组的子查询时,在另一个分组的查询中,您只能使用您已经获得的数据(来自子查询),并且您只能选择将其保留在聚合级别详细信息已经是,或者您可以选择失去精度以支持更多分组。你不能为了进一步总结而保留细节而失去细节。因此,子查询查询(实际上)相对毫无意义,因为您不妨在一次点击中分组到您想要的级别:
SELECT groupkey1, sum(y) FROM
(SELECT groupkey1, groupkey2, sum(x) as y FROM table GROUP BY groupkey1, groupkey2)
GROUP BY groupkey1
Run Code Online (Sandbox Code Playgroud)
是相同的:
SELECT groupkey1, sum(x) FROM
table
GROUP BY groupky1
Run Code Online (Sandbox Code Playgroud)
戈登的答案可能会奏效(除了您展示的相同错误,因为分组集错误/未涵盖所有列)但它可能对您的理解没有多大帮助,因为它是仅代码答案. 以下是您需要如何解决这个问题的细分,但使用更简单的数据和前面的窗口函数以支持您已经知道的内容。
假设库存中有不同类型的苹果和甜瓜。无论购买日期如何,您都需要一个提供每种特定水果总数的查询。您还需要为每种水果整体类型的总计列:
细节:
fruit | type | purchasedate | count
apple | golden delicious | 2017-01-01 | 3
apple | golden delicious | 2017-01-02 | 4
apple | granny smith | 2017-01-04 ! 2
melon | honeydew | 2017-01-01 | 1
melon | cantaloupe | 2017-01-05 | 4
melon | cantaloupe | 2017-01-06 | 2
Run Code Online (Sandbox Code Playgroud)
所以那是 7 个黄金美味,2 个史密斯奶奶,1 个蜜露,6 个哈密瓜,还有 9 个苹果和 7 个甜瓜
您不能将其作为一个查询*来执行,因为您需要两个不同级别的分组。您必须将其作为两个查询来执行,然后(关键理解点)您必须将不太精确的(苹果/甜瓜)结果连接回更精确的(史密斯奶奶/黄金美味/蜜露/哈密瓜):
SELECT * FROM
(
SELECT fruit, type, sum(count) as fruittypecount
FROM fruit
GROUP BY fruit, type
) fruittypesum
INNER JOIN
(
SELECT fruit, sum(count) as fruitcount
FROM fruit
GROUP BY fruit
) fruitsum
ON
fruittypesum.fruit = fruitsum.fruit
Run Code Online (Sandbox Code Playgroud)
你会得到这个:
fruit | type | fruittypecount | fruit | fruitcount
apple | golden delicious | 7 | apple | 9
apple | granny smith | 2 | apple | 9
melon | honeydew | 1 | melon | 7
melon | cantaloupe | 6 | melon | 7
Run Code Online (Sandbox Code Playgroud)
因此,对于您的查询、不同的组、详细信息和摘要:
SELECT
detail.order || '-' || detail.ordinal_number as order,
detail.company,
summary.order_total,
detail.order_shipment_total,
detail.order_type
FROM (
SELECT o.order,
osh.ordinal_number,
o.company,
SUM(osh.items) AS order_shipment_total,
o.order_type
FROM orders o
JOIN order_shipments osh ON o.order_id = osh.order_id
WHERE o.order = [some order number]
GROUP BY o.order,
o.company,
o.order_type
) detail
INNER JOIN
(
SELECT o.order,
SUM(osh.items) AS order_total
FROM orders o
JOIN order_shipments osh ON o.order_id = osh.order_id
--don't need the where clause; we'll join on order number
GROUP BY o.order,
o.company,
o.order_type
) summary
ON
summary.order = detail.order
Run Code Online (Sandbox Code Playgroud)
Gordon 的查询使用一个窗口函数达到同样的效果;窗口函数在分组完成后运行,它建立了另一个级别的分组(PARTITION BY ordernumber),它是GROUP BY ordernumber摘要中 my 的有效等价物。窗函数汇总数据通过订单号与明细数据有内在的联系;查询说:
SELECT
ordernumber,
lineitemnumber,
SUM(amount) linetotal
sum(SUM(amount)) over(PARTITION BY ordernumber) ordertotal
GROUP BY
ordernumber,
lineitemnumber
Run Code Online (Sandbox Code Playgroud)
.. 将有一个ordertotal是linetotal订单中所有的总数:GROUP BY 将数据准备到行级别详细信息,窗口函数将数据准备到订单级别,并根据需要重复总计次数填写每个订单项。我用大写写了SUM属于 GROUP BY 操作的 ..sum小写属于分区操作。它必须sum(SUM())也不能简单地说,sum(amount)因为数量作为一列本身是不允许的 - 它不在 group by 中。因为数量本身是不允许的,必须对 group by 求和才能工作,所以我们必须让sum(SUM())分区运行(它在 group by 完成后运行)
它的行为与分组到两个不同的级别并连接在一起完全相同,实际上我选择了这种方式来解释它,因为它使您更清楚地了解它如何与您已经了解的组和连接相关联
请记住:JOINS 使数据集横向增长,UNIONS 使它们向下增长。当您有一些详细数据并且想要通过更多数据(摘要)横向增长时,请加入它。(如果您希望总数位于每列的底部,则将其合并)
*您可以将其作为一个查询来执行(没有窗口函数),但它会变得非常混乱,因为它需要各种最终不值得的技巧,因为它太难维护了
| 归档时间: |
|
| 查看次数: |
2566 次 |
| 最近记录: |