【问题标题】:SQL SUM, COUNT for only unique idSQL SUM, COUNT 仅用于唯一 ID
【发布时间】:2014-02-28 00:38:11
【问题描述】:

我只想计算唯一 ID 的总和和计数。

SELECT COUNT(orders.id), SUM(orders.total), SUM(orders.shipping) FROM "orders"
INNER JOIN "designer_orders" ON "designer_orders"."order_id" = "orders"."id" 
WHERE (designer_orders.state = 'pending' OR
       designer_orders.state = 'dispatched' OR
       designer_orders.state = 'completed')
  • 仅对唯一的订单 ID 执行此操作。
  • 仅当orders.id 唯一时才添加orders.total。运输也是如此。
  • 避免添加重复项。

例如,orders 表内连接designer_orders 表:

OrderId Total Some designer order column
 1       1000  2
 1       1000  3
 1       1000  5
 2       100   7
 3       133   8
 4       1000  10
 4       1000  20

在这种情况下:

  • 订单数应为 4。
  • 订单总数应为 2233。

架构:

  • 一个订单有多个设计师订单。
  • 一个设计师订单只有一个订单。

【问题讨论】:

  • 到目前为止,您提供的信息无法回答您的问题
  • @Alexander 还需要什么。请说明
  • CREATE for your tables and sample INSERT`s
  • 这仍然很不清楚,IMO。你能创建一个 SQLfiddle 来演示你的场景吗?
  • @ChrisFarmer 只需检查更新。如果您仍然觉得您需要小提琴,请告诉我

标签: sql postgresql join aggregate-functions exists


【解决方案1】:

试试这个方法

SELECT COUNT(o.id) no_of_orders, 
       SUM(o.total) total, 
       SUM(o.shipping) shipping 
  FROM orders o JOIN 
(
    SELECT DISTINCT order_id
      FROM designer_orders
     WHERE state IN('pending', 'dispatched', 'completed')
) d 
    ON o.id = d.order_id

这里是SQLFiddle演示

【讨论】:

  • 帮个忙,请您解释一下 join 关键字在子查询中的作用
  • 它的工作方式与普通表格相同。从派生表(您称为子查询)中,我们返回感兴趣的order_ids(具有正确的状态),然后我们加入它orders,有效地过滤掉所有不匹配。
  • 那么它作为 where 子句起作用。说出order_ids = 无论子查询返回什么
  • WHERE 子句中,您必须使用INEXISTS 才能执行相同操作。 JOINs 通常优化得更好。
【解决方案2】:

由于您只关心designer_orders 表中是否有任何行符合条件status存在,因此最明显的查询样式是EXISTS semi -加入。通常最快,在 n 表中可能有许多重复行:

SELECT COUNT(o.id)     AS no_of_orders
      ,SUM(o.total)    AS total
      ,SUM(o.shipping) AS shipping
FROM   orders o
WHERE  EXISTS (
   SELECT 1
   FROM   designer_orders d
   WHERE  d.state = ANY('{pending, dispatched, completed}')
   AND    d.order_id = o.id
   );

-> SQLfiddle demo

对于具有更大表的快速SELECT 查询(并且以一定的写入性能为代价),您将拥有partial index 之类的:

CREATE INDEX designer_orders_order_id_idx ON designer_orders (order_id)
WHERE state = ANY('{pending, dispatched, completed}');

索引条件必须与查询的WHERE 条件相匹配,才能让查询规划器实际使用索引。

部分索引特别有吸引力,如果有很多行的status 不符合 条件。否则,总体而言,没有条件的索引可能是更好的选择。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-30
    • 1970-01-01
    • 1970-01-01
    • 2013-10-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多