我有这些表
places(place_id, place_name)
places_criteria(place_id, criterion_id)
criteria(criterion_id, criterion_name)
“places_criteria”具有“地点”和“标准”的外键。我可以按一个标准获得许多地方。
SELECT p.place_id, p.place_name
FROM places p INNER JOIN places_criteria pc ON p.place_id = pc.place_id
WHERE pc.criterion_id = < some_id >
如何按多个条件获得多个地方?
例如:迪斯尼乐园是一个地方(place_id = 1),它是“好”(criterion_id = 1)和“有趣”(criterion_id = 2)。
places_criteria的数据:
place_id criterion_id
1 1
1 2
现在我想得到“好”和“有趣”的地方。
答案 0 :(得分:3)
硬编码版本是根据您需要的每个标准自行加入表格。
SELECT
c1.place_id
FROM
places_criteria AS c1
INNER JOIN
places_criteria AS c2
ON c2.place_id = c1.place_id
WHERE
c1.criterion_id = 1
AND c2.criterion_id = 2
这是有效的,但如果要查询动态数量的criterion_ids,则需要动态SQL。
另一种方法是使用IN (1,2)
(或连接等来执行类似的功能)来获得Places with criterion 1 <OR> 2
的答案,然后使用{{1 }}子句只包含两个不同标准的地方。
HAVING
答案 1 :(得分:2)
你可以这样做:
SELECT p.place_id, p.place_name
FROM places p, places_criteria pc1, places_criteria pc2, places_criteria pc3
WHERE p.place_id = pc2.place_id and pc1.criterion_id = < some_id >
and p.place_id = pc2.place_id and pc2.criterion_id = < some_id >
and p.place_id = pc3.place_id and pc3.criterion_id = < some_id >
但我对我对你的问题的理解有疑问:你为什么要向我们展示criteria
表?
答案 2 :(得分:1)
使用in
从一个集合中进行选择。您可以使用子选择来获取正确的位置ID,或者您可以像我一样使用distinct
,这在MySQL中可能稍快一些。
select distinct
p.place_id,
p.place
from
places p
inner join places_criteria pc on pc.place_id = p.place_id
inner join criteria c on c.criterion_id = pc.criterion_id
where
/* Either by name */
c.criterion_name in ('crit A', 'crit B', 'crit C')
/* Or by id */
OR c.criterion_id in (1, 2, 3, 4, 5)
解决方案2.匹配所有条件。通过检查计数来做到这一点。
select
p.place_id,
p.place
from
places p
inner join places_criteria pc on pc.place_id = p.place_id
inner join criteria c on c.criterion_id = pc.criterion_id
where
c.criterion_name in ('crit A', 'crit B', 'crit C')
group by
p.place_id,
p.place
having
count(*) = 3 /* the number of criteria */
答案 3 :(得分:1)
如果您想要满足以下几个标准之一的所有地方:
SELECT p.place_id, p.place_name
FROM places p
INNER JOIN places_criteria pc ON p.place_id = pc.place_id
WHERE pc.criterion_id = < some_id >
OR pc.criterion_id = < some_id2 >
OR pc.criterion_id = < some_id3 >
GROUP BY p.place_id, p.place_name
如果您想要满足所有条件的所有地方:
SELECT p.place_id, p.place_name
FROM places p
INNER JOIN places_criteria pc1 ON p.place_id = pc1.place_id
INNER JOIN places_criteria pc2 ON p.place_id = pc2.place_id
INNER JOIN places_criteria pc3 ON p.place_id = pc3.place_id
WHERE pc1.criterion_id = < some_id >
AND pc2.criterion_id = < some_id2 >
AND pc3.criterion_id = < some_id3 >