Я создаю оператор выбора, который сочетает в себе две таблицы, zone
и output
, на основе ссылочного device
таблицы и на отображение zone_number
- output_type_id
. Отображение zone_number
до output_type_id
не отображается в любой точке базы данных, и я хотел бы создать его «на лету» в выписке . Ниже моя схема:Как создать «на лету» таблицу сопоставления в ЗЕЬЕСТ в Postgresql
CREATE TABLE output_type (
id INTEGER NOT NULL,
name TEXT,
PRIMARY KEY (id)
);
CREATE TABLE device (
id INTEGER NOT NULL,
name TEXT,
PRIMARY KEY (id)
);
CREATE TABLE zone (
id SERIAL NOT NULL,
device_id INTEGER NOT NULL REFERENCES device(id),
zone_number INTEGER NOT NULL,
PRIMARY KEY (id),
UNIQUE (zone_number)
);
CREATE TABLE output (
id SERIAL NOT NULL,
device_id INTEGER NOT NULL REFERENCES device(id),
output_type_id INTEGER NOT NULL REFERENCES output_type(id),
enabled BOOLEAN NOT NULL,
PRIMARY KEY (id)
);
А вот некоторые примеры данные:
INSERT INTO output_type (id, name) VALUES
(101, 'Output 1'),
(202, 'Output 2'),
(303, 'Output 3'),
(404, 'Output 4');
INSERT INTO device (id, name) VALUES
(1, 'Test Device');
INSERT INTO zone (device_id, zone_number) VALUES
(1, 1),
(1, 2),
(1, 3),
(1, 4);
INSERT INTO output (device_id, output_type_id, enabled) VALUES
(1, 101, TRUE),
(1, 202, FALSE),
(1, 303, FALSE),
(1, 404, TRUE);
мне нужно получить соответствующую enabled
поля из таблицы выходных данных для каждой зоны для данного устройства. Каждый zone_number
соответствует output_type_id
. Для этого примера:
zone_number | output_type_id
----------------------------
1 | 101
2 | 202
3 | 303
4 | 404
Один способ справиться с отображением было бы создать новую таблицу
CREATE TABLE zone_output_type_map (
zone_number INTEGER,
output_type_id INTEGER NOT NULL REFERENCES output_type(id)
);
INSERT INTO zone_output_type_map (zone_number, output_type_id) VALUES
(1, 101),
(2, 202),
(3, 303),
(4, 404);
и использовать следующий SQL, чтобы получить все зоны, плюс enabled
флаг, для устройства 1:
SELECT zone.*, output.enabled
FROM zone
JOIN output
ON output.device_id = zone.device_id
JOIN zone_output_type_map map
ON map.zone_number = zone.zone_number
AND map.output_type_id = output.output_type_id
AND zone.device_id = 1
Однако, я ищу способ, чтобы создать отображение зоны nunbers для вывода типов без создания новой таблицы и без склеивания кучи A ND/OR . Есть ли элегантный способ создания сопоставления между двумя полями внутри оператора select? Что-то вроде:
SELECT zone.*, output.enabled
FROM zone
JOIN output
ON output.device_id = zone.device_id
JOIN (
SELECT (
1 => 101,
2 => 202,
3 => 303,
4 => 404
) (zone_number, output_type_id)
) as map
ON map.zone_number = zone.zone_number
AND map.output_type_id = output.output_type_id
AND zone.device_id = 1
Отказ от ответственности: Я знаю, что в идеале enabled
поле будет существовать в таблице zone
. Однако у меня нет контроля над этой штукой. Я просто ищу самое элегантное решение со стороны приложения. Благодаря!
Возможно, вы могли бы воспользоваться VIEW? –
Я был бы в порядке с этим, но базовое сопоставление все равно нужно было бы определить внутри оператора select (внутри представления), и именно там оно ломается для меня. Похоже, что должен быть простой способ создания ключа/значения «хэш», который может использоваться в инструкции select для соединения двух таблиц. – Divey
Данные образца 'output_type' не соответствуют вашему' output. output_type_id', первый использует 101, 102, 103 и 104, тогда как второй использует 101, 202, 303 и 404; hooray для FKs для указания на это мне :) –