[英]How to Query A Hierarchy of Tables in SQL
我有一張桌子, meeting
。 在這些meeting
之間存在着等級制度。 其中一些是年度會議,大多數只是定期會議。
所有定期meetings
都將與至少一個連接表相關聯, meeting_yearly_meeting
。 一個meeting_yearly_meeting
有兩列: meeting_id
和yearly_meeting_id
。
下面是這兩個表的樣子:
會議:
id SERIAL PRIMARY KEY,
title VARCHAR(255),
mappable BOOLEAN,
phone VARCHAR(255),
email VARCHAR(255),
city VARCHAR(255),
address VARCHAR(255),
zip VARCHAR(255),
latitude NUMERIC,
longitude NUMERIC,
description VARCHAR(255),
worship_time TIME,
state VARCHAR(255),
website VARCHAR(255),
lgbt_affirming BOOLEAN,
created TIMESTAMP default current_timestamp,
updated TIMESTAMP default current_timestamp
meeting_yearly_meeting:
id SERIAL PRIMARY KEY,
meeting_id SMALLINT,
yearly_meeting_id SMALLINT,
created TIMESTAMP default current_timestamp,
updated TIMESTAMP default current_timestamp
因此,從我的/meetings
端點,我想返回所有會議的集合 - 定期會議和年度會議。 我想返回會議及其所有列,以及一個附加列: yearly_meeting
。
對於具有一個或多個關聯meeting_yearly_meeting
記錄的meeting
記錄, yearly_meeting
將是指定為該meeting
的年度會議的meeting
記錄title
的逗號分隔列表。 對於那些沒有任何關聯的meeting_yearly_meeting
記錄的會議(因此它們本身就是年度會議),我希望yearly_meeting field to be
NULL`。
在我追求這個目標的路上,我嘗試了這樣的事情:
SELECT t1.*, t2.meeting_yearly_meeting AS yearly_meeting
FROM (
SELECT * FROM meeting
FULL JOIN meeting_yearly_meeting ON meeting.id = meeting_yearly_meeting.yearly_meeting_id;
) as t1,
(
SELECT CASE WHEN (meeting_yearly_meeting.id IS NOT NULL)
THEN (SELECT title FROM meeting WHERE meeting.id = meeting_yearly_meeting.yearly_meeting_id)
ELSE NULL
END
FROM (
SELECT meeting_yearly_meeting.* FROM meeting
FULL JOIN meeting_yearly_meeting ON meeting.id = meeting_yearly_meeting.meeting_id
) as meeting_yearly_meeting;
) as t2;
但這會引發語法錯誤。
我很欣賞其他人可能有的任何見解。 如果您需要任何其他上下文或說明,請告訴我!
更新:
示例meeting
數據: https : //gist.github.com/micahbales/4013399c3fd23a0caf108124dab827c8
樣本meeting_yearly_meeting
數據: https : meeting_yearly_meeting
預期返回值示例: https : //gist.github.com/micahbales/13d2aafdc5d43c4b948dc39c2df51569
您可以嘗試離開參加年度會議,然后使用string_agg()
獲取逗號分隔的列表。
SELECT m1.id,
m1.title,
m1.mappable,
m1.phone,
m1.email,
m1.city,
m1.address,
m1.zip,
m1.latitude,
m1.longitude,
m1.description,
m1.worship_time,
m1.state,
m1.website,
m1.lgbt_affirming,
m1.created,
m1.updated,
string_agg(m2.title, ', ') yearly_meeting
FROM meeting m1
LEFT JOIN meeting_yearly_meeting mym1
ON mym1.meeting_id = m1.id
LEFT JOIN meeting m2
ON m2.id = mym1.yearly_meeting_id
GROUP BY m1.id,
m1.title,
m1.mappable,
m1.phone,
m1.email,
m1.city,
m1.address,
m1.zip,
m1.latitude,
m1.longitude,
m1.description,
m1.worship_time,
m1.state,
m1.website,
m1.lgbt_affirming,
m1.created,
m1.updated;
編輯:
更“緊湊”的解決方案可能是使用相關子查詢。
SELECT m1.*,
(SELECT string_agg(m2.title, ', ')
FROM meeting_yearly_meeting mym1
LEFT JOIN meeting m2
ON m2.id = mym1.yearly_meeting_id
WHERE mym1.meeting_id = m1.id) yearly_meeting
FROM meeting m1;
但請注意,雖然代碼較少,但不一定更快。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.