0

私はこれらのテーブルを持っています

places(place_id, place_name)
places_criteria(place_id, criterion_id)
criteria(criterion_id, criterion_name)

「places_criteria」には、「places」および「criteria」への外部キーがあります。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 >

複数の基準で多くの場所を取得するにはどうすればよいですか?

:ディズニーランドは場所(place_id = 1)であり、「良い」(criterion_id = 1)および「興味深い」(criterion_id = 2)です。

Places_criteriaのデータ:

place_id   criterion_id
1            1
1            2

今、私は「良い」そして「面白い」場所を手に入れたいと思っています。

4

4 に答える 4

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

これは効率的ですが、動的な数のcriteria_idsをクエリする場合は、動的SQLが必要です。

別の方法は、を使用してIN (1,2) (または結合などを使用して同様の機能を実行し)、に対する答えを取得してから、句をPlaces with criterion 1 <OR> 2使用して2つの異なる基準を持つ場所のみを含めることです。HAVING

SELECT
  place_id
FROM
  places_criteria
WHERE
  criterion_id IN (1,2)
GROUP BY
  place_id
HAVING
  COUNT(DISTINCT criterion_id) = 2
于 2012-06-12T07:01:01.450 に答える
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テーブルを見せますか?

于 2012-06-12T06:37:33.617 に答える
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 */
于 2012-06-12T06:40:12.293 に答える
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 >
于 2012-06-12T06:41:17.437 に答える