带有聚合和 RIGHT JOIN 的 PostgreSQL 查询不过滤
PostgreSQL Query with aggregates and RIGHT JOIN not filtering
我在一对多地图上有两个 tables,库存和地块,在地块上 table 我有一个名为 deleted 的布尔字段,所以我真的不删除行,但是更改要忽略的标志并且不计入查询,我正在尝试合并一个视图的查询,但是如果我添加已删除的字段,则查询的 RIGHT JOIN 表现得像 INNER JOIN 并且我想要 ALL FROM下面示例中的清单工作正常,但不排除 table 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;
结果只有在批次 table 上有记录的库存行,因此 RIGHT JOIN 的目的被忽略,表现为 INNER JOIN
有什么想法吗?
提前致谢
在 where
子句中使用 "outer" table 中的列将外连接转换为内连接。将 table 的条件移动到 join
条件:
FROM jap.lots
RIGHT JOIN jap.inventories
ON jap.lots.inventory_id = ap.inventories.inventory_id
AND lots.deleted = false
GROUP BY ...
我发现 left join
s 更容易遵循 -- 将所有行保留在 第一个 table 中,匹配行放在其余部分。您的问题是 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;
另请注意 table 别名和限定列名的使用。这些使查询更易于编写和阅读。此外,它们使它更加一致:您对 table 名称的使用在整个查询过程中不一致。
我在一对多地图上有两个 tables,库存和地块,在地块上 table 我有一个名为 deleted 的布尔字段,所以我真的不删除行,但是更改要忽略的标志并且不计入查询,我正在尝试合并一个视图的查询,但是如果我添加已删除的字段,则查询的 RIGHT JOIN 表现得像 INNER JOIN 并且我想要 ALL FROM下面示例中的清单工作正常,但不排除 table 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;
结果只有在批次 table 上有记录的库存行,因此 RIGHT JOIN 的目的被忽略,表现为 INNER JOIN
有什么想法吗? 提前致谢
在 where
子句中使用 "outer" table 中的列将外连接转换为内连接。将 table 的条件移动到 join
条件:
FROM jap.lots
RIGHT JOIN jap.inventories
ON jap.lots.inventory_id = ap.inventories.inventory_id
AND lots.deleted = false
GROUP BY ...
我发现 left join
s 更容易遵循 -- 将所有行保留在 第一个 table 中,匹配行放在其余部分。您的问题是 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;
另请注意 table 别名和限定列名的使用。这些使查询更易于编写和阅读。此外,它们使它更加一致:您对 table 名称的使用在整个查询过程中不一致。