PostgreSQL:具有多个条件的多个 LEFT JOIN
PostgreSQL: multiple LEFT JOIN with multiple conditions
这是我的数据模型的摘录(包括 tables 内容的摘录)。
我需要强制计算 2015 年类型 1 的操作次数。我还希望结果中包含完整的城镇列表,而不仅仅是 operation
table 中引用的城镇(与对于没有注册业务的城镇,数字等于零)。然后我需要指定几个条件,但是 WHERE
子句将我的 LEFT JOIN
变成了 INNER JOIN
(参见 ),所以我必须在 [=17] 中指定条件=] 子句。
SELECT
town.town_code,
count(operation.*) AS nb
FROM town
LEFT JOIN operation ON town.town_code = operation.ope_town AND operation.ope_year = 2015
LEFT JOIN intervention ON operation.ope_id = intervention.int_ope_id
LEFT JOIN nature ON intervention.int_id = nature.int_id AND nature.type_id = 1
GROUP BY town.town_code ORDER BY town.town_code ;
我得到以下结果:
town_code | nb
------------+-----
86000 | 1
86001 | 0
86002 | 1
86003 | 1
86004 | 0
86005 | 0
城镇代码 86003 有问题,它应该是 0。这个城镇代码指的是一项操作 (#5
),它指的是一项干预 (#16
),它指的是 nature type = 3
。所以有一个条件没填...
如何处理 ON
子句中的多个条件?
编辑: 这是创建 table 和测试的脚本。
CREATE TABLE town (town_code INTEGER, town_name CHARACTER VARING(255)) ;
CREATE TABLE operation (ope_id INTEGER, ope_year INTEGER, ope_town INTEGER) ;
CREATE TABLE intervention (int_id INTEGER, int_ope_id INTEGER) ;
CREATE TABLE nature (int_id INTEGER, type_id INTEGER) ;
INSERT INTO town VALUES (86000, 'Lille'), (86001, 'Paris'), (86002, 'Nantes'), (86003, 'Rennes'), (86004, 'Marseille'), (86005, 'Londres') ;
INSERT INTO operation VALUES (1, 2014, 86000), (2, 2015, 86000), (3, 2012, 86001), (4, 2015, 86002), (5, 2015, 86003) ;
INSERT INTO intervention VALUES (12, 1), (13, 2), (14, 3), (15, 4), (16, 5) ;
INSERT INTO nature VALUES (12, 1), (13, 1), (14, 3), (15, 1), (16, 3) ;
那是因为你select先离开了加入。例如你可以使用:
SELECT t.town_code, count(j.*) AS nb FROM town t
LEFT JOIN (SELECT o.ope_town cd, o.ope_year yr FROM operation o, intervention i, nature n
WHERE o.ope_year = 2015
AND o.ope_id = i.int_ope_id AND n.type_id = 1
AND i.int_id = n.int_id) j
ON j.cd = t.town_code
GROUP BY t.town_code ORDER BY t.town_code;
这是我的数据模型的摘录(包括 tables 内容的摘录)。
我需要强制计算 2015 年类型 1 的操作次数。我还希望结果中包含完整的城镇列表,而不仅仅是 operation
table 中引用的城镇(与对于没有注册业务的城镇,数字等于零)。然后我需要指定几个条件,但是 WHERE
子句将我的 LEFT JOIN
变成了 INNER JOIN
(参见
SELECT
town.town_code,
count(operation.*) AS nb
FROM town
LEFT JOIN operation ON town.town_code = operation.ope_town AND operation.ope_year = 2015
LEFT JOIN intervention ON operation.ope_id = intervention.int_ope_id
LEFT JOIN nature ON intervention.int_id = nature.int_id AND nature.type_id = 1
GROUP BY town.town_code ORDER BY town.town_code ;
我得到以下结果:
town_code | nb
------------+-----
86000 | 1
86001 | 0
86002 | 1
86003 | 1
86004 | 0
86005 | 0
城镇代码 86003 有问题,它应该是 0。这个城镇代码指的是一项操作 (#5
),它指的是一项干预 (#16
),它指的是 nature type = 3
。所以有一个条件没填...
如何处理 ON
子句中的多个条件?
编辑: 这是创建 table 和测试的脚本。
CREATE TABLE town (town_code INTEGER, town_name CHARACTER VARING(255)) ;
CREATE TABLE operation (ope_id INTEGER, ope_year INTEGER, ope_town INTEGER) ;
CREATE TABLE intervention (int_id INTEGER, int_ope_id INTEGER) ;
CREATE TABLE nature (int_id INTEGER, type_id INTEGER) ;
INSERT INTO town VALUES (86000, 'Lille'), (86001, 'Paris'), (86002, 'Nantes'), (86003, 'Rennes'), (86004, 'Marseille'), (86005, 'Londres') ;
INSERT INTO operation VALUES (1, 2014, 86000), (2, 2015, 86000), (3, 2012, 86001), (4, 2015, 86002), (5, 2015, 86003) ;
INSERT INTO intervention VALUES (12, 1), (13, 2), (14, 3), (15, 4), (16, 5) ;
INSERT INTO nature VALUES (12, 1), (13, 1), (14, 3), (15, 1), (16, 3) ;
那是因为你select先离开了加入。例如你可以使用:
SELECT t.town_code, count(j.*) AS nb FROM town t
LEFT JOIN (SELECT o.ope_town cd, o.ope_year yr FROM operation o, intervention i, nature n
WHERE o.ope_year = 2015
AND o.ope_id = i.int_ope_id AND n.type_id = 1
AND i.int_id = n.int_id) j
ON j.cd = t.town_code
GROUP BY t.town_code ORDER BY t.town_code;