[英]Postgresql : Alternative to joining the same table multiple times
If i have two tables entry and entry_metadata , with the entry_metadata as a description table for the entry referenced by entry_id and a variable. 如果我有两个表entry和entry_metadata ,其中entry_metadata作为由entry_id和变量引用的条目的描述表。
If i have this : 如果我有这个:
entry 条目
id | name |
-------------
1 | entry1 |
2 | entry2 |
3 | entry3 |
entry_metadata entry_metadata
id | entry_id | variable | value
1 | 1 | width | 10
2 | 1 | height | 5
3 | 2 | width | 8
4 | 2 | height | 7
5 | ... | .... | ..
and i'm getting the table : 我正在桌子上:
id | name | width | height| ... | ...
-----------------------------------------
1 | entry1 | 10 | 5 |
2 | entry2 | 8 | 7 |
3 | entry3 | .. | .. |
by the sql : 通过sql:
select e.name, em.width, emr.height
from
public.entry e
left join
public.entry_metadata em
on
em.entry_id = e.id and em.variable = 'width'
left join
public.entry_metadata emr
on
emr.entry_id = e.id and emr.variable = 'height'
The query above works. 上面的查询有效。 But as I add more variables to get the values (the entry_metadata table includes a large variety of variables) from the entry metadata.
但是随着我添加更多变量以从条目元数据中获取值(entry_metadata表包含多种变量)。 The query gets really really slow.
查询真的真的很慢。 every join I do slows down the execution greatly.
我执行的每个联接都会大大降低执行速度。 Is there a way to get around this?
有办法解决这个问题吗?
You can also do this with conditional aggregation: 您也可以使用条件聚合来做到这一点:
select id, name,
max(case when variable = 'width' then value end) as width,
max(case when variable = 'height' then value end) as height
from public.entry_metadata em
group by id, name;
Adding additional columns is just adding more aggregation functions. 添加其他列只是添加更多的聚合功能。
Just use subselects for this: 只需为此使用子选择:
SELECT
e.id,
e.name,
(SELECT em.value FROM public.entry_metadata em WHERE em.entry_id = e.id AND em.variable = 'width') AS width,
(SELECT em.value FROM public.entry_metadata em WHERE em.entry_id = e.id AND em.variable = 'height') AS height
FROM
public.entry e
So for each new variable you just need to add one more subselect. 因此,对于每个新变量,您只需要再添加一个子选择。
Is there a way to get around this?
有办法解决这个问题吗?
Yes, replace entry_metadata
table with addtional column in entry
(possible solutions are hstore
or jsonb
) with key - value storage of entry metadata. 是的,更换
entry_metadata
在addtional列的表entry
(可能的解决方案是hstore
或jsonb
)与关键-项元数据的值存储。
Btw. 顺便说一句。 your tables represents well known controversial database desing pattern known as "Entity Attribute Value".
您的表代表了众所周知的有争议的数据库设计模式,称为“实体属性值”。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.