使用多个条件加入查询

时间:2012-06-12 06:32:52

标签: mysql sql

我有这些表

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

现在我想得到“好”和“有趣”的地方。

4 个答案:

答案 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 >