首页 > 解决方案 > 在没有 DISTINCT 的 Postgres 中使用 LEFT JOIN 时防止重复行

问题描述

我有 4 张桌子:

在这些表中,Purchase Discount 有两个条目,所有其他的只有一个条目。但是当我查询它们时,由于LEFT JOIN,我得到了重复的条目。

此查询将在大型数据库中运行,我听说使用DISTINCT会降低性能。有没有其他方法可以在不使用的情况下删除重复项DISTINCT

这是SQL 小提琴

结果显示:

[{"item_id":1,"purchase_items_ids":[1234,1234],"total_sold":2}]

但结果应该是:

[{"item_id":1,"purchase_items_ids":[1234],"total_sold":1}]

标签: sqljsonpostgresqlmany-to-manyleft-join

解决方案


首先,我建议INNER JOIN items i ON i.id = t.item_id从没有理由存在的查询中删除。

然后左加入 Purchase_Discounts 表使用子查询来获取 Discount_amount (如 Lukasz Szozda 的回答中所述)

如果任何产品没有折扣,Discount_amount则将显示列NULL。如果你想避免它,那么你可以使用COALESCE()如下代替:

COALESCE(SUM((select sum(discount_amount) from purchase_discounts 
                 where purchase_discounts.purchase_id = purchase.id)),0) as discount_amount

Db小提琴:

  SELECT array_to_json(array_agg(p_values)) FROM 
     ( 
       SELECT t.item_id, t.purchase_items_ids, t.total_sold, t.discount_amount FROM 
         ( 
           SELECT purchase_items.item_id AS item_id,
                  ARRAY_AGG(purchase_items.id) AS purchase_items_ids,
                  SUM(purchase_items.sold) as total_sold,
                  SUM((select sum(discount_amount) from purchase_discounts 
                      where purchase_discounts.purchase_id = purchase.id)) as discount_amount
                   FROM items
                   INNER JOIN purchase_items ON purchase_items.item_id = items.id
                   INNER JOIN purchase ON purchase.id = purchase_items.purchase_id              
                  WHERE 
                   purchase.id = 200
                  GROUP by 
                   purchase_items.item_id
         ) as t 
       
     ) AS p_values;

输出:

array_to_json
[{"item_id":1,"purchase_items_ids":[1234],"total_sold":1,"discount_amount":12}]

db<>在这里摆弄


推荐阅读