我有一个用于在PostgreSQL中存储邮政信息的系统。我们有一个postal_carriers
表,其中详细列出了运营商信息。我们有一个postal_zones
表,其中包含postal_carriers
的区域。我们有一个countries
表,其中包含国家/地区信息。现在,我创建了一个postal_zone_mapping
表,该表将国家/地区映射到不同运营商的区域。这是它的定义。
CREATE TABLE shopman.postal_zone_mapping
(
postal_zone_id integer,
postal_carrier_id integer,
country_id integer,
CONSTRAINT pzm_key UNIQUE (country_id, postal_carrier_id),
CONSTRAINT pzm_fkey FOREIGN KEY (country_id)
REFERENCES shopman.countries (country_id) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE NO ACTION,
CONSTRAINT postal_zone_mapping_postal_carrier_id_fkey FOREIGN KEY (postal_carrier_id)
REFERENCES shopman.postal_carriers (postal_carrier_id) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE NO ACTION,
CONSTRAINT postal_zone_mapping_postal_zone_id_fkey FOREIGN KEY (postal_zone_id)
REFERENCES shopman.postal_zones (postal_zone_id) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE NO ACTION
)
这是我用来选择数据的语句,选择country
表上带有左连接的postal_zone_mapping
表,因为我希望列出所有承运商所在的国家/地区,无论它们是重新映射到特定的载波和区域。
SELECT c.country_id,
COALESCE(postal_zone_id,-1) AS postal_zone_id,
COALESCE(postal_carrier_id,-1) AS postal_carrier_id,
country_name
FROM shopman.countries c
LEFT JOIN shopman.postal_zone_mapping p
ON c.country_id=p.country_id
WHERE postal_carrier_id=1
OR postal_carrier_id IS NULL
ORDER BY country_name ASC
OFFSET 0 ROWS FETCH FIRST 50 ROWS ONLY
我希望此查询返回每个国家/地区,如果运营商ID与我们想要的国家/地区ID匹配,则返回运营商ID,但是对于我的查询,如果我们为运营商插入地图,则返回的结果不包含该国家/地区。我的查询哪里出问题了?另外,是否有更好的方法来实现此映射?我走了这条路,以避免必须动态添加列或拥有数组。
非常感谢
作为参考,以下是其他表的定义:
CREATE TABLE shopman.postal_carriers
(
postal_carrier_id serial,
postal_carrier_name text,
description text,
CONSTRAINT postal_carriers_pkey PRIMARY KEY (postal_carrier_id),
CONSTRAINT postal_carriers_postal_carrier_name_key UNIQUE (postal_carrier_name)
)
CREATE TABLE shopman.postal_zones
(
postal_zone_id serial,
postal_carrier_id integer,
postal_zone_name text,
CONSTRAINT postal_zones_pkey PRIMARY KEY (postal_zone_id),
CONSTRAINT postal_zones_postal_zones_name_key UNIQUE (postal_carrier_id, postal_zone_name),
CONSTRAINT postal_zones_postal_carrier_id_fkey FOREIGN KEY (postal_carrier_id)
REFERENCES shopman.postal_carriers (postal_carrier_id) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE NO ACTION
)
CREATE TABLE shopman.countries
(
country_id serial,
country_name text,
code_2 text",
code_3 text,
region_id integer,
CONSTRAINT countries_pkey PRIMARY KEY (country_id),
CONSTRAINT countries_code_2_key UNIQUE (code_2),
CONSTRAINT countries_code_3_key UNIQUE (code_3),
CONSTRAINT countries_name_key UNIQUE (country_name),
CONSTRAINT countries_region_id_fkey FOREIGN KEY (region_id)
REFERENCES shopman.regions (region_id) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE NO ACTION
)
答案 0 :(得分:3)
将 second 表上的条件移到ON
子句中:
SELECT c.country_id,
COALESCE(p.postal_zone_id, -1) AS postal_zone_id,
COALESCE(p.postal_carrier_id,-1) AS postal_carrier_id,
c.country_name
FROM shopman.countries c LEFT JOIN
shopman.postal_zone_mapping p
ON c.country_id = p.country_id AND p.postal_carrier_id = 1
ORDER BY c.country_name ASC
OFFSET 0 ROWS FETCH FIRST 50 ROWS ONLY