[英]SQL query - Joining a many-to-many relationship, filtering/joining selectively
我發現自己在使用SQL查詢時處於無法工作的狀況,並且希望自己缺少某些東西或可能學習一些新知識。 我正在使用的DB2數據庫的結構並非完全針對此類查詢而構建,但是我要承擔的任務是...
假設我們有表格人員和表格組。 組可以包含多個人,一個人可以屬於多個組。 是的,已經很亂了。 無論如何,都有兩個將兩者鏈接的中間表。 問題是,我需要從一組列表開始,獲取這些組中的所有人員,然后獲取與該人員相關的所有組,這將是初始組的超集。 這將意味着從小組開始,加入人們的行列,然后返回並再次加入小組。 我也需要結果集中的兩個表中的信息,以便排除許多技術。
我必須將其與許多其他表結合起來以獲取更多信息,並且查詢變得越來越龐大,繁瑣且緩慢。 我想知道是否可以通過某種方式從“人”開始,將其加入“組”,然后指定如果一個人具有提供的一組組中的一個組(通過子查詢完成),那么所有組因為那個人應該被遣返。 我不知道實現此目標的方法,但我在想(希望)在SQL中實現此目標的方法相對干凈。
一個簡單而骯臟的例子:
SELECT ...
FROM GROUPS g
JOIN LINKING_A a
ON g.GROUPID = a.GROUPID
AND GROUPID IN (subquery)
JOIN LINKING_B b
ON a.GROUPLIST = b.GROUPLIST
JOIN PEOPLE p
ON b.PERSONID = p.PERSONID
--This gets me all people affiliated with groups,
-- but now I need all groups affiliated with those people...
JOIN LINKING_B b2
ON p.PERSONID = b2.PERSONID
JOIN LINKING_A a2
ON b2.GROUPLIST = a.GROUPLIST
JOIN GROUPS g2
ON a2.GROUPID = g.GROUPID
然后我可以從結果集中的p和g2返回信息。 您可以看到我遇到的麻煩。 在一些大表上有很多聯接,更不用說在此查詢中執行的許多其他聯接。 我需要能夠通過將PEOPLE加入GROUPS進行查詢,然后指定是否有人在子查詢中具有關聯的組,則它應該返回PEOPLE中與該條目相關的所有組。 我以為GROUP BY可能只是問題,但我還沒有真正使用過它。 因此,如果Bill是A,B和C組的一部分,並且我們的子查詢返回一個包含Group A的集合,則結果集應包括Bill和A,B和C組。
以下是獲取提供的群組列表中的人員所在的所有群組的一種較短方法。這有幫助嗎?
Select g.*
From Linking_B b
Join Linking_B b2
On b2.PersonId = b.PersonId
Join Group g
On g.GroupId = b2.GroupId
Where b.Groupid in (SubQuery)
我不清楚您為什么同時擁有Linking_A和Linking_B。 通常,代表兩個主表之間的多對多關系所需的所有操作就是具有GroupID和PersonId的單個關聯表。
我經常建議使用“公用表表達式” [CTE],以幫助您將問題分解為一些易於理解的塊。 使用WITH子句指定CTE,在開始主SELECT查詢之前,該子句可以包含多個CTE。
我將假定您要開始的組列表是由您的子查詢指定的,因此它將是第一個CTE。 下一個選擇那些人。 然后,查詢的最后一部分選擇這些人所屬的組,並從兩個主表中返回列。
WITH g1 as
(subquery)
, p1 as
(SELECT p.*
from g1
join Linking a1 on g1.groupID=a1.groupID
join People p on p.personID=a1.personID )
SELECT p1.*, g2.*
from p1
join Linking a2 on p2.personID=a2.personID
join Groups g2 on g2.groupID=a2.groupID
我想我會先建立要提取記錄的人員列表,然后使用該列表查詢這些人員的所有組。 在添加了適當聯接的情況下,這將可在任意數量的鏈接表中使用:
with persons_wanted as
(
--figure out which people are in a group you want to include
select p.person_key
from person p
join link l1
on p.person_key = l1.person_key
join groups g
on l1.group_key = g.group_key
where g.group name in ('GROUP_I_WANT_PEOPLE_FROM', 'THIS_ONE_TOO')
group by p.person_key --we only want each person_key once
)
--now pull all the groups for the list of people in at least one group we want
select p.name as person_name, g.name as group_name, ...
from person p
join link l1
on p.person_key = l1.person_key
join groups g
on l1.group_key = g.group_key
where p.person_key in (select person_key from persons_wanted);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.