Postgresql 如何在连接表时避免子查询?
--我是这里的新手,觉得这要么是琐碎的,要么是错误的数据库建模-- 在以下情况下:Postgresql 如何在连接表时避免子查询?,postgresql,Postgresql,--我是这里的新手,觉得这要么是琐碎的,要么是错误的数据库建模-- 在以下情况下: create TABLE objects ( id BIGSERIAL NOT NULL UNIQUE PRIMARY KEY, name text unique ); create TABLE features ( id BIGSERIAL NOT NULL UNIQUE PRIMARY KEY, name text ); create TABLE features_map ( id BIGSERIAL N
create TABLE objects (
id BIGSERIAL NOT NULL UNIQUE PRIMARY KEY,
name text unique
);
create TABLE features (
id BIGSERIAL NOT NULL UNIQUE PRIMARY KEY,
name text
);
create TABLE features_map (
id BIGSERIAL NOT NULL UNIQUE PRIMARY KEY,
o_id BIGINT REFERENCES objects ON DELETE restrict,
f_id BIGINT REFERENCES features ON DELETE restrict,
value text
);
insert into features(id, name) values
(1, 'length'),
(2, 'wheels');
insert into objects(id, name) values
(1, 'car'),
(2, 'bike');
insert into features_map(o_id,f_id,value) values
(1,1,'4.5m'),
(1,2,'4'),
(2,1,'2.3m'),
(2,2,'2');
我希望获得所需的输出,即左连接但合并具有不同列的单行结果:
select o.id, o.name,
(select value from features_map fm join features f on fm.f_id=f.id where fm.o_id=o.id and f.name='length') as length,
(select value from features_map fm join features f on fm.f_id=f.id where fm.o_id=o.id and f.name='wheels') as wheels
from objects o;
id|name|length|wheels|
--|----|------|------|
1|car |4.5m |4 |
2|bike|2.3m |2 |
随着表大小的增加,这种类型的查询变得太慢,例如对象数>10000和要素图数>40000
使用join
查询速度相当快,但结果(显然)显示在多行上:
select *
from objects o
join features_map fm on o.id=fm.o_id
join features f on f.id=fm.f_id;
id|name|id|o_id|f_id|value|id|name |
--|----|--|----|----|-----|--|------|
1|car | 1| 1| 1|4.5m | 1|length|
1|car | 2| 1| 2|4 | 2|wheels|
2|bike| 3| 2| 1|2.3m | 1|length|
2|bike| 4| 2| 2|2 | 2|wheels|
如何以join
方法的速度获得所需的输出
再见,
aaWnSd
你需要一张透视表。这可以通过对数据集进行分组,然后使用过滤后的值进行聚合来实现
在这种情况下,使用了MIN()
函数,但这并不重要。您也可以使用MAX()
或SUM()
,因为您只有一个值。因此,单个值的MIN()
值==MAX()
值==SUM()
SELECT
o.id,
o.name,
MIN(value) FILTER (WHERE f.name = 'length') AS length,
MIN(value) FILTER (WHERE f.name = 'wheels') AS wheels
FROM objects o
JOIN features_map fm ON o.id=fm.o_id
JOIN features f ON f.id=fm.f_id
GROUP BY o.id, o.name
ORDER BY o.id
Hi可能重复,不确定是否解决。太复杂了,我无法理解和验证。无论如何谢谢你的帮助!我知道当你第一次看它的时候并不是那么容易,但是试一下,因为这是做它的方法。