Jof*_*ams 5 mysql sql-match-all
我在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)
Run Code Online (Sandbox Code Playgroud)
因此,每个位置都可以使用多个标记字进行标记,并且每个标记字都可以标记为多个位置.
我想要做的是只选择标有所有提供的标签名称的位置.例如:
我想要所有标有"树"和"秋千"的地点.应选择位置"公园",但不应选择位置"森林".
任何见解将不胜感激.谢谢!
有两种方法可以做到这一点.我更喜欢第一种方式,即为每个标签自我加入:
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 = ?;
Run Code Online (Sandbox Code Playgroud)
另一种方式也有效,但GROUP BY在MySQL中使用往往会产生临时表并且性能很慢:
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;
Run Code Online (Sandbox Code Playgroud)