SQL:如何用两个表分组?

时间:2018-11-06 14:02:42

标签: sql postgresql join group-by sum

我有表格产品历史记录,我需要按名称分组:

产品=( id_product ,名称)

历史记录=( id_history ,id_product,金额)

我尝试了此SQL查询,但未按名称分组:

SELECT
      products.name,
      sum(history.amount)
FROM history
INNER JOIN products ON history.id_product = products.id_product
GROUP BY
      products.name,
      history.amount,
      history.id_history;

这是结果:

SQL result

2 个答案:

答案 0 :(得分:2)

您应该仅按需要聚合的属性进行分组。在这种情况下,您只需要IsDate()

products.name

如果您需要包括没有历史记录的产品(在这种情况下,假设总和应为0而不是SELECT products.name, sum(history.amount) AS [Amount] FROM history INNER JOIN products ON history.id_product = products.id_product GROUP BY products.name; ),则可以使用null而不是OUTER JOIN来包含所有产品:

INNER JOIN

答案 1 :(得分:0)

这是没有答案,但是评论太久了。

出于可读性考虑,产品表应位于第一位。毕竟是我们可以选择的产品,再加上历史数据,我们可以通过[left] join history ...,然后通过聚合或[left] join (<history aggregation query>)或select子句中的子选择来访问。

提高可读性的另一步骤是使用别名。

加入表格,然后汇总

select p.name, coalesce(sum(h.amount), 0) as total
from products p
left join history h on h.id_product = p.id_product
group by p.name
order by p.name;

先汇总再加入

select p.name, coalesce(h.sum_amount, 0) as total
from products p
left join
(
  select sum(h.amount) as sum_amount
  from history 
  group by id_product
) h on h.id_product = p.id_product
order by p.name;

在select子句中获取总和

select
  name,
  (select sum(amount) from history h where h.id_product = p.id_product) as total
from products p
order by p.name;

当您对如何使用GROUP BY感到困惑时,这里有一个解释:GROUP BY ___表示您希望每个___有一个结果行。在您的原始查询中,您有GROUP BY products.name, history.amount, history.id_history说您想要每个名称,金额和ID的结果行,而实际上只希望每个名称(即GROUP BY products.name的行)。