Postgresql
在 PostgreSQL 中加入多個沒有重複結果且沒有 UNION 的表
假設我們在 PostgreSQL 中有兩個表 A 和 B:
一種
乙
我想得到以下結果:
如果我查詢如下內容 - 我將得到 6 行而不是 5 行,因為 B0 中的所有行都將與 B1 中的所有行混合,如果 B0 或 B1 有更多行,結果行數將逐漸增加:
SELECT A.title, B0.element_name, B1.element_name LEFT JOIN B B0 ON A.first_group_id = B0.group_id LEFT JOIN B B1 ON A.second_group_id = B1.group_id FROM A;
我可以通過使用 UNION 來實現所需的行為,但我想知道是否有更有效的方法來做到這一點?特別是當需要以相同的方式進行兩個以上的 JOIN 時。
可能有更快的方法。適用於您的最小展示:
SELECT a.title , CASE WHEN b.group_id = a.first_group_id THEN b.element_name END AS first_group , CASE WHEN b.group_id = a.second_group_id THEN b.element_name END AS second_group FROM a, b;
基本上,加入一次以避免重複。
但是你的問題留下了很大的解釋空間。
很有可能,你有額外的限制。這可能是您真正需要的:
SELECT a.title , CASE WHEN b.group_id = a.first_group_id THEN b.element_name END AS first_group , CASE WHEN b.group_id = a.second_group_id THEN b.element_name END AS second_group FROM a LEFT JOIN b ON b.group_id IN (a.first_group_id, a.second_group_id) ORDER BY a.title, b.group_id, element_name;
db<>在這裡擺弄
另外,您可能需要一個額外的列來定義 table 中的 order
B
。並且
UNION ALL
可能仍然更快,具體取決於未公開的細節。
LEFT JOIN
在範例中獲得 2x 的 6 行的原因:這只是任務的錯誤方法。
避免兩次查詢表的一個巧妙選擇是首先取消透視
A
。您需要一些
CASE
表達式,因為您還想拆分element_name
回不同的列。不太擅長 Postgres,我的語法可能略有偏差
SELECT A.title, CASE WHEN A.first_group_id = v.group_id THEN B.element_name END AS element_name0, CASE WHEN A.second_group_id = v.group_id THEN B.element_name END AS element_name1 FROM A INNER JOIN LATERAL (VALUES (A.first_group_id), (A.second_group_id) ) AS v(group_id) LEFT JOIN B ON v.group_id = B.group_id;