簡體   English   中英

Postgresql:替代多次連接同一張表

[英]Postgresql : Alternative to joining the same table multiple times

如果我有兩個表entryentry_metadata ,其中entry_metadata作為由entry_id和變量引用的條目的描述表。

如果我有這個:

條目

id | name   |
-------------
1  | entry1 |
2  | entry2 |
3  | entry3 |

entry_metadata

id | entry_id | variable | value
1  |    1     | width    | 10
2  |    1     | height   | 5
3  |    2     | width    | 8
4  |    2     | height   | 7
5  |   ...    |  ....    | ..

我正在桌子上:

id | name   | width | height| ...  | ...
-----------------------------------------
1  | entry1 |  10   |  5    |
2  | entry2 |  8    |  7    |
3  | entry3 |  ..   |  ..   |

通過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'

上面的查詢有效。 但是隨着我添加更多變量以從條目元數據中獲取值(entry_metadata表包含多種變量)。 查詢真的真的很慢。 我執行的每個聯接都會大大降低執行速度。 有辦法解決這個問題嗎?

您也可以使用條件聚合來做到這一點:

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;

添加其他列只是添加更多的聚合功能。

只需為此使用子選擇:

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

因此,對於每個新變量,您只需要再添加一個子選擇。

有辦法解決這個問題嗎?

是的,更換entry_metadata在addtional列的表entry (可能的解決方案是hstorejsonb )與關鍵-項元數據的值存儲。

順便說一句。 您的表代表了眾所周知的有爭議的數據庫設計模式,稱為“實體屬性值”。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM