Postgres SUM和GROUP BY

时间:2016-03-24 19:10:44

标签: sql postgresql group-by

我对Postgres来说比较新。我正在使用PostgreSQL 9.5.1。

我创建了一个简单的表来说明我面临的问题。

CREATE TABLE orders (
    order_id integer NOT NULL,
    order_id_parent integer,
    order_date date,
    item_id integer,
    item_qty integer
);

以下是样本数据。

order_id | order_id_parent |order_date | item_id | item_qty
1           0               2016-03-24      0       0
2           1               NULL            1       2
3           1               NULL            2       2
4           0               2016-03-24      0       0
5           4               NULL            1       5

我想从2016-03-24中选择所有订单,将数量相加并按 sub.item_id 对结果进行分组,以获得不同订单中每个商品的数量。我的问题是GROUP,因为它强迫我按 sub.order_id 进行分组,但我没有得到所需的结果,因为我希望结果只按 sub.item_id 。这是我的疑问:

SELECT sub.order_id, sub.item_id, SUM(sub.item_qty) AS qty
FROM orders sub
LEFT JOIN orders par ON sub.order_id_parent = par.order_id
WHERE TRUE AND par.order_date = '2016-03-24'
GROUP BY sub.item_id, sub.order_id

提前致谢。

更新

@ fqhv,@ Gordon Linoff和@alxgrh的答案很有帮助,并向我展示了解决问题的不同方法。

我想要实现的是一个输出不同结果的查询。最终用户需要具有按sub.order_id或sub.item_id对结果进行分组的选项。在第一个查询中,qty将显示每行的数量。第二个查询将按sub.item_id对结果进行分组,并显示每个sub.item_id的所有数量的总和。我来自MYSQL世界,这是完全可行的,结果是查询/代码的简单性。似乎我需要有两个不同的查询来获得正确的结果。我将以我期望的方式发布在MYSQL中工作的查询。

SELECT sub.order_id, sub.item_id, SUM(sub.item_qty) AS qty
FROM orders sub JOIN orders par ON sub.order_id_parent = par.order_id
WHERE par.order_date = '2016-03-24'
GROUP BY sub.order_id

请注意" GROUP BY sub.order_id "

SELECT sub.order_id, sub.item_id, SUM(sub.item_qty) AS qty
FROM orders sub JOIN orders par ON sub.order_id_parent = par.order_id
WHERE par.order_date = '2016-03-24'
GROUP BY sub.item_id

唯一的区别是" GROUP BY sub.item_id " 我知道 sub.order_id 不再代表该行的ID,因为结果按 sub.item_id 分组

要在Postgres中获得相同的结果,我需要从选择中删除 sub.order_id ,以避免按 sub.order_id 进行分组,这显然不会产生预期的结果。我在Postgre的查询是:

SELECT sub.item_id, SUM(sub.item_qty) AS qty 
FROM orders sub 
  LEFT JOIN orders par ON sub.order_id_parent = par.order_id 
WHERE TRUE AND par.order_date = '2016-03-24' 
GROUP BY sub.item_id

3 个答案:

答案 0 :(得分:0)

这是你想要的吗?

SELECT sub.item_id, SUM(sub.item_qty) AS qty
FROM orders sub JOIN
     orders par
     ON sub.order_id_parent = par.order_id
WHERE par.order_date = '2016-03-24'
GROUP BY sub.item_id;

您不需要LEFT JOIN,因为日期测试需要匹配。

具有讽刺意味的是,删除父母似乎是一个非常小的变化。原始查询非常先进。

答案 1 :(得分:0)

我认为这会为您提供所需的输出。要选择您未聚合或包含在组中的值,您需要使用子查询。

SELECT sub.order_id, items.item_id, items.qty
FROM orders sub
INNER JOIN orders par ON sub.order_id_parent = par.order_id
INNER JOIN
(
    SELECT sub.item_id, sum(sub.item_qty) AS qty
    FROM orders sub
    INNER JOIN orders par ON sub.order_id_parent = par.order_id
    WHERE par.order_date = '2016-03-24'
    GROUP BY sub.item_id
) AS items ON sub.item_id = items.item_id
WHERE par.order_date = '2016-03-24'
我改变了主意。我不确定你想要什么。如果您希望按父项和项目分组的订单,请使用此项。

SELECT sub.order_id_parent, sub.item_id, sum(sub.item_qty) AS qty
FROM orders sub
INNER JOIN orders par ON sub.order_id_parent = par.order_id
WHERE par.order_date = '2016-03-24'
GROUP BY sub.order_id_parent, sub.item_id

答案 2 :(得分:0)

如果您只想获得与特定订单无关的订购商品数量,请不要在SELECT

之后使用sub.order_id
test=# SELECT sub.item_id, sum(sub.item_qty) AS qty
FROM orders sub
JOIN orders par ON sub.order_id_parent = par.order_id
WHERE par.order_date = '2016-03-24'
GROUP BY  sub.item_id;
 item_id | qty 
---------+-----
       1 |   7
       2 |   2
(2 rows)