PostgreSQL查询聚合和RIGHT JOIN不过滤

时间:2015-12-17 22:04:23

标签: sql postgresql outer-join

我在一对多的地图,库存和批次上有两个表,在批次表上我有一个名为deleted的布尔字段,所以我不会删除行,但是要更改要忽略的行并且不要计数查询,我正在尝试合并一个查询的视图,但如果我添加删除的字段,然后查询的右边连接行为像INNER JOIN,我希望下面的示例中的所有FROM库存工作正常,但不排除表jap.lots上的任何删除记录。

    CREATE VIEW view_inventory_lots AS 
SELECT count(lots.*) AS lots,
sum(lots.qty_available) AS available,
sum(lots.qty_received) AS received,
sum(lots.qty_on_hand) AS onhand,
sum(lots.qty_allocated) AS allocated,
inventories.* 
FROM jap.lots RIGHT JOIN jap.inventories
 ON jap.lots.inventory_id = jap.inventories.inventory_id
  GROUP BY inventories.inventory_id;

如果我尝试修改此视图以使用以下查询添加lot.deleted字段进行过滤:

SELECT count(lots.*) AS lots,
sum(lots.qty_available) AS available,
sum(lots.qty_received) AS received,
sum(lots.qty_on_hand) AS onhand,
sum(lots.qty_allocated) AS allocated,
lots.deleted,
inventories.* 
FROM jap.lots RIGHT JOIN jap.inventories
 ON jap.lots.inventory_id = jap.inventories.inventory_id
 WHERE lots.deleted = false
  GROUP BY inventories.inventory_id, lots.deleted;

结果只是在批次表上有记录的库存行,因此忽略了RIGHT JOIN的用途,表现为INNER JOIN

有什么想法吗? 提前致谢

2 个答案:

答案 0 :(得分:5)

使用where子句中“outer”表中的列将外部联接转换为内部联接。将该表上的条件移动到join条件:

FROM jap.lots 
  RIGHT JOIN jap.inventories 
     ON jap.lots.inventory_id = ap.inventories.inventory_id
    AND lots.deleted = false
GROUP BY ...

答案 1 :(得分:2)

我发现left join更容易理解 - 保留第一个表中的所有行,并在其余行中匹配行。您的问题是where子句中的条件撤消了外连接。

我会把它写成:

SELECT count(l.*) AS lots,
       sum(l.qty_available) AS available,
       sum(l.qty_received) AS received,
       sum(l.qty_on_hand) AS onhand,
       sum(l.qty_allocated) AS allocated,
       l.deleted,
       i.* 
FROM jap.inventories i LEFT JOIN
     jap.lots l LEFT JOIN 
     ON l.inventory_id = i.inventory_id AND
        l.deleted = false
GROUP BY i.inventory_id, l.deleted;

还要注意表别名和限定列名的使用。这些使查询更容易编写和阅读。此外,它们使它更加一致:在整个查询过程中,您对表名的使用不一致。