【发布时间】:2013-07-06 03:18:03
【问题描述】:
我正在创建一个组合两个表 zone 和 output 的 select 语句,
基于引用的device 表和zone_number 到output_type_id 的映射。
zone_number 到 output_type_id 的映射没有出现
数据库中的任何位置,我想在选择中“即时”创建它
陈述。以下是我的架构:
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 获取设备 1 的所有区域以及 enabled 标志:
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
但是,我正在寻找一种方法来创建区域编号到输出的映射 在不创建新表且不拼凑一堆 AND/OR 的情况下键入 陈述。有没有一种优雅的方式来创建两个字段之间的映射 在选择语句中?类似的东西:
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
桌子。但是,我无法控制那件作品。我只是在寻找
应用程序方面最优雅的解决方案。谢谢!
【问题讨论】:
-
也许你可以使用视图?
-
我可以接受,但是底层映射仍然需要在 select 语句中(在视图中)定义,这就是我崩溃的地方。似乎应该有一种简单的方法来创建键/值“哈希”,可以在 select 语句中使用它来连接两个表。
-
您的
output_type样本数据与您的output. output_type_id不匹配,第一个使用101、102、103 和104,而第二个使用101、202、303 和404;万岁 FK 向我指出这一点 :) -
感谢@mu 的收获!我在我的问题中解决了这个问题。
标签: sql postgresql postgresql-8.4