[英]Select in a many-to-many relationship in MySQL
我在MySQL數據庫中有兩個表,Locations和Tags,以及第三個表LocationsTagsAssoc,它們將兩個表關聯起來並將它們視為多對多關系。
表結構如下:
Locations
---------
ID int (Primary Key)
Name varchar(128)
LocationsTagsAssoc
------------------
ID int (Primary Key)
LocationID int (Foreign Key)
TagID int (Foreign Key)
Tags
----
ID int (Primary Key)
Name varchar(128)
因此,每個位置都可以使用多個標記字進行標記,並且每個標記字都可以標記為多個位置。
我想要做的是只選擇標有所有提供的標簽名稱的位置 。 例如:
我想要所有標有“樹”和“秋千”的地點。 應選擇位置“公園”,但不應選擇位置“森林”。
任何見解將不勝感激。 謝謝!
有兩種方法可以做到這一點。 我更喜歡第一種方式,即為每個標簽自我加入:
SELECT l.*
FROM Locations l
JOIN LocationsTagsAssoc a1 ON a1.LocationID = l.ID
JOIN Tags t1 ON a1.TagID = t1.ID AND t1.Name = ?
JOIN LocationsTagsAssoc a2 ON a2.LocationID = l.ID
JOIN Tags t2 ON a2.TagID = t2.ID AND t2.Name = ?
JOIN LocationsTagsAssoc a3 ON a3.LocationID = l.ID
JOIN Tags t3 ON a3.TagID = t3.ID AND t3.Name = ?;
另一種方式也有效,但在MySQL中使用GROUP BY
往往會產生臨時表並且性能很慢:
SELECT l.*
FROM Locations l
JOIN LocationsTagsAssoc a ON a.LocationID = l.ID
JOIN Tags t ON a.TagID = t.ID
WHERE t.Name IN (?, ?, ?)
GROUP BY l.ID
HAVING COUNT(*) = 3;
您需要的位置不存在LocationsTagsAssoc表中未顯示給定標記的位置。
您可以使用IN()指定給定標記,如下所示,或者通過連接到包含它們的另一個表。
即
SELECT l.*
FROM Locations AS l
WHERE NOT EXISTS (
SELECT NULL FROM Tags AS t
WHERE NOT EXISTS (
SELECT NULL FROM LocationsTagsAssoc AS lt
WHERE lt.LocationId = l.ID
AND lt.TagID = t.ID
)
AND t.ID IN (1, 2, 3,...)
)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.