[英]SQL Query With Multiple Sub-queries
構建基於標簽的內部電話簿並創建了鏈接表,但看不到如何加入所有來自阿伯丁和曼徹斯特的經理兼總監的人。
用戶數
ID | Name | etc
1 | Frank
2 | Bob
3 | Bert
標簽
ID | TagName | Tag Order
1 | Aberdeen | 1
2 | Manchester | 1
3 | Staff | 2
4 | Manager | 2
5 | Director | 2
鏈接表
ID | UsersId | TagsId
1 | 1 | 1
2 | 2 | 1
3 | 3 | 2
如果選擇了標簽Aberdeen,則將顯示Frank和Bob。如果選擇了標簽Manchester,則將顯示Bert。我想選擇Tag Aberdeen和Tag Manchester,以向所有人顯示。然后,我想選擇所有來自Aberdeen和Manchester的經理和總監的人。
嘗試編寫SQL是一項艱苦的工作,任何想法,請先感謝。
您需要兩個聯接。 例如,這將顯示所有來自阿伯丁或曼徹斯特的人:
select
u.ID,
u.Name
from
Users as u
inner join LinkingTable as l on t.UsersID=u.ID
inner join Tags as t on t.ID=l.TagsID
where
t.TagName in ('Aberdeen', 'Manchester')
這將選擇所有經理和董事:
select
u.ID,
u.Name
from
Users as u
inner join LinkingTable as l on t.UsersID=u.ID
inner join Tags as t on t.ID=l.TagsID
where
t.TagName in ('Manager', 'Director')
如果要從阿伯丁或曼徹斯特選擇經理和董事,則需要選擇在這兩個表中都出現的行。 這可以使用intersect
來完成
select
u.ID,
u.Name
from
Users as u
inner join LinkingTable as l on t.UsersID=u.ID
inner join Tags as t on t.ID=l.TagsID
where
t.TagName in ('Aberdeen', 'Manchester')
intersect
select
u.ID,
u.Name
from
Users as u
inner join LinkingTable as l on t.UsersID=u.ID
inner join Tags as t on t.ID=l.TagsID
where
t.TagName in ('Manager', 'Director')
您創建的是一個實體屬性值表。
這些非常靈活,可以在不更改數據結構的情況下將其他雜項數據存儲到實體。 如何開始記錄最喜歡的巧克力品牌和新的標簽類型,然后將數據添加到鏈接表...
但是,他們非常不擅長的是在該數據中搜索符合特定條件的實體(在您的情況下為用戶) 。
當然有可能,這是執行此操作的通用方法,但是不要期望對大量數據有良好的性能。 (在網上搜索EAV表,優化和替代方法。)
SELECT
*
FROM
users
INNER JOIN
links
ON links.UsersId = users.id
INNER JOIN
tags
ON tags.id = links.TagsId
WHERE
tags.TagNames IN ('Aberdeen', 'Manchester', 'Manager', 'Director')
GROUP BY
users.id
HAVING
COUNT(DISTINCT CASE WHEN tags.TagOrder = 1 THEN tags.id END) >= 1
AND COUNT(DISTINCT CASE WHEN tags.TagOrder = 2 THEN tags.id END) >= 1
這只是選擇每個匹配的搜索條件的任何一行 ,然后通過用戶他們聚集到所有檢查每個標准“類型”中的至少一個被匹配(至少一個位置,至少一工作角色)。
使用此方法意味着您可以相對輕松地增加搜索條件的數量和復雜性。 在WHERE
子句中包括所有可能的相關標記,然后在HAVING
子句中分析行的組,以確保已匹配足夠的條件集 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.