У меня есть система хранения почтовой информации в 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
Я хочу, чтобы этот запрос возвращал каждую страну, идентификатор оператора связи, если он соответствует тому, который мы хотим вместе с идентификатор зоны, но с моим запросом, если мы вставим карту для оператора, то в возвращаемых результатах не будет этой страны. Где я ошибаюсь в своем запросе? Кроме того, есть ли лучший способ достичь этого сопоставления? Я пошел по этому пути, чтобы избежать необходимости динамически добавлять столбцы или иметь массивы.
Большое спасибо
Для справки, вот определение других таблиц:
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
)