Tworzę select, która łączy dwie tabele, zone
i output
, oparciu o odwołanie device
stole i na odwzorowaniu zone_number
do output_type_id
. Mapowanie zone_number
do output_type_id
nie pojawia się w dowolnym miejscu w bazie danych, a ja chciałbym utworzyć go "w locie" w ramach wybranego oświadczenia . Poniżej jest mój schemat:Jak utworzyć tabelę mapowania „on-the-fly” w SELECT w 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)
);
I Oto przykład dane:
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);
muszę pobrać powiązany enabled
pole z tabeli wyjściowej dla każdej strefy dla danego urządzenia. Każdy zone_number
mapuje na output_type_id
. Na tym przykładzie:
zone_number | output_type_id
----------------------------
1 | 101
2 | 202
3 | 303
4 | 404
jeden sposób, aby obsłużyć mapowanie byłoby utworzyć nową tabelę
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);
i używać następujące SQL, aby uzyskać wszystkie strefy, oraz flag enabled
dla urządzenia 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
Jednakże szukam sposób, aby utworzyć odwzorowanie nunbers strefy do wyjścia typy bez tworzenia nowej tabeli i bez zszywania pęczek a Instrukcje ND/OR . Czy istnieje elegancki sposób tworzenia mapowania między dwoma polami w instrukcji select? Coś jak:
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
Disclaimer: wiem, że idealnie pole enabled
istniałby w tabeli zone
. Jednak nie mam kontroli nad tym kawałkiem. Po prostu szukam najbardziej eleganckiego rozwiązania od strony aplikacji. Dzięki!
Może mógłbyś użyć WIDOKU? –
Byłbym w porządku z tym, ale podstawowe mapowanie nadal będzie musiało być zdefiniowane w instrukcji select (w widoku), i to tam się dla mnie załamuje. Wygląda na to, że powinien istnieć prosty sposób tworzenia klucza "hash", który może być użyty w instrukcji select do dołączenia do dwóch tabel. – Divey
Twoje przykładowe dane 'output_type' nie pasują do twojego' wyjścia. output_type_id', pierwszy używa 101, 102, 103 i 104, podczas gdy drugi używa 101, 202, 303 i 404; wuj dla FK za wskazanie mi tego :) –