SQL SUM,COUNT仅用于唯一ID

时间:2014-02-04 06:50:55

标签: sql postgresql join aggregate-functions exists

我想仅计算唯一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。

架构:

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

2 个答案:

答案 0 :(得分:2)

以这种方式试试

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 演示

答案 1 :(得分:0)

由于您只对表status中是否存在符合条件designer_orders 任何行感兴趣,因此最明显的查询样式是EXISTS半连接。通常最快,n-table中可能有许多重复行:

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符合条件。否则,没有条件的指数可能是更好的选择。