如何在Postgres中跨多个表汇总出现次数?

3

我有两个表,分别是:

  • UK_OrderUK_Order_Item
  • F_OrderF_Order_Item

UK_Order(和F_Order)拥有以下字段:IdorderStatusUK_Order_Item(和F_Order_Item)拥有以下字段:orderIdmodelorder_quantity

我正在尝试编写SQL以返回在英国和F中售出的不同模型的总数,但是无法实现。到目前为止,我想到的是:

SELECT model, SUM(order_quantity) AS quantityOrdered 
FROM uk_order_item 
WHERE orderId 
IN
(
    SELECT Id FROM uk_order WHERE orderStatus = 'Incomplete'
)
GROUP BY model

并且
SELECT model, SUM(order_quantity) AS quantitySold
FROM f_order_item 
WHERE orderId 
IN
(
    SELECT Id FROM f_order WHERE orderStatus = 'Incomplete'
)
GROUP BY model

返回示例:

Model, QuantityOrdered
Volkswagen, 3
Ford, 2
Citroen, 4
...

为了找到在英国和法国销售的大众汽车总数量,我需要进行一些计算(即volkswagenCount = 英国的大众汽车数量已售出 + 法国的大众汽车数量已售出)。

换句话说,我的单独查询返回了英国和法国销售的总模型数 - 我会重复这个查询以获取德国、西班牙等地的数据。但是有没有一种方法可以返回整个欧洲(英国、法国、德国等地)每个销售的模型总数?


1
你能否包含“CREATE TABLE”语句?这样比描述它们要好得多。 - vyegorov
1个回答

4

数据库设计

我建议重新考虑您的数据库设计。将所有国家统一到一个表中可能是一个更好的想法。因此,您可以为所有国家使用单个表:

order_item 
order

只需要在order表中添加一个country_id

更简单的查询语句

IN这个条件太过复杂了,而且效率低下。更简单、更快速的方法:

SELECT oi.model, sum(oi.order_quantity) AS quantity_ordered 
FROM   uk_order      o
JOIN   uk_order_item oi ON oi.orderid = o.id
WHERE  o.orderstatus = 'Incomplete'
GROUP  BY 1;

虽然你有单独的表格,但是将它们分别计数会更加简单、快速:

SELECT model, sum(quantity_ordered) AS total_quantity_ordered
FROM  (
   SELECT model, sum(order_quantity) AS quantity_ordered
   FROM   uk_order      o
   JOIN   uk_order_item oi ON oi.orderid = o.id
   WHERE  o.orderstatus = 'Incomplete'
   GROUP  BY 1

   UNION  ALL
   SELECT model, sum(order_quantity) AS quantity_ordered
   FROM   f_order       o
   JOIN   f_order_item  oi ON oi.orderid = o.id
   WHERE  o.orderstatus = 'Incomplete'
   GROUP  BY 1
   ) sub
GROUP  BY 1;

您可以将行合并到一个派生表中,然后再使用UNION ALL进行求和:

SELECT model, sum(quantity_ordered) AS total_quantity_ordered
FROM  (
   SELECT model, order_quantity AS quantity_ordered
   FROM   uk_order      o
   JOIN   uk_order_item oi ON oi.orderid = o.id
   WHERE  o.orderstatus = 'Incomplete'

   UNION  ALL
   SELECT model, order_quantity AS quantity_ordered
   FROM   f_order       o
   JOIN   f_order_item  oi ON oi.orderid = o.id
   WHERE  o.orderstatus = 'Incomplete'
   ) sub
GROUP  BY 1;

但我怀疑它不会更快。

而我的经验建议是不要在Postgres中使用驼峰式标识符,无论是否带引号。这样可以让你的生活变得更加轻松。


谢谢Erwin。不幸的是,我被现有的表所困住了。至于CaMel,没关系,这只是为了举例子,但你说得对。我不是SQL专家,但你的答案看起来非常简单明了(差点想让我把头撞在墙上,大声说出:“当然!”):D - err1
@user3801108:我的查询缺少表别名。同时添加了一个简单的替代方案,可能更快。 - Erwin Brandstetter
Erwin,非常好的回答。由于声望不足(15),无法点赞?是的,我是 Stack 的新手...再次感谢您的快速回复。Sai。 - err1
@Sai-LeungLee:作为新用户,您无法进行点赞(请参见此处),但如果回答确实解决了您的问题,您可以随时接受该回答。 - Erwin Brandstetter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接