PostgreSQL总和儿童用品数量

时间:2016-01-07 20:07:56

标签: sql postgresql

我有一个订阅服务,可以提供很多项目 订户通过在delivery_items中创建一行来向交货添加商品 直到最近,订阅者才能将每个项目中的1个添加到交付中。但是现在我已经在我的delivery_items表中添加了一个数量列。

鉴于this schema, and an outdated query(在SQL小提琴上),如何选择每天交付所需物品的总量?

这提供了一个天数表,当天交付的物品但没有说明数量:

SELECT
  d.date, 
  sum((di.item_id = 1)::int) as "Bread",
  sum((di.item_id = 2)::int) as "Eggs",
  sum((di.item_id = 3)::int) as "Coffee"
FROM deliveries d
JOIN users u ON u.id = d.user_id
JOIN delivery_items di ON di.delivery_id = d.id
GROUP BY d.date
ORDER BY d.date

理想情况下,我的查询与项目的细节无关,例如id / name。

由于

编辑以添加架构:

deliveries (TABLE)
 id int4(10)
 date timestamp(29)
 user_id int4(10)
delivery_items (TABLE)
 delivery_id int4(10)
 item_id int4(10)
 quantity int4(10)
items (TABLE)
 id int4(10)
 name varchar(10)
users (TABLE)
 id int4(10)
 name varchar(10)

1 个答案:

答案 0 :(得分:2)

您无需加入users表,因为您既没有从中获取任何数据,也没有将其用作您的加入条件。

这是您编辑过的 SQL Fiddle

使用条件sum()函数将检索为特定日期交付的所需商品的值。

SELECT
  d.date, 
  sum(CASE WHEN di.item_id = 1 THEN di.quantity ELSE 0 END) as "Bread",
  sum(CASE WHEN di.item_id = 2 THEN di.quantity ELSE 0 END) as "Eggs",
  sum(CASE WHEN di.item_id = 3 THEN di.quantity ELSE 0 END) as "Coffee"
FROM deliveries d
JOIN delivery_items di ON di.delivery_id = d.id
GROUP BY d.date
ORDER BY d.date

您还可以查看crosstab(text, text)功能。结果将是相同的,但您也可以指定生成类别集的查询。

但是,如果您希望在items表有其他行时获得动态结果,则需要将其包装在函数中并构建输出列和类型定义,因为:

  

声明交叉表函数返回setof记录,因此必须在调用SELECT状态的FROM子句中定义输出列的实际名称和类型