21

IN リストで必要な項目だけを選択するにはどうすればよいでしょうか。例えば

select * from pagetags where TagID in (1,2,4)

ここで、上記の 3 つの ID (1、2、4) が​​すべて割り当てられているすべてのページが必要です。

方法はありますか?その他のオペレーター?私はすでに試しましたが、運が= Anyあり= Allません。

4

4 に答える 4

32

このタイプの問題の用語は関係分割です。下は片道。

SELECT PageID
FROM   pagetags
WHERE  TagID IN ( 1, 2, 4 )
GROUP  BY PageID
HAVING Count(DISTINCT TagID) = 3
于 2012-09-24T11:21:19.667 に答える
0

次のようなことを試すことができます:

SELECT id, Tag FROM (
SELECT id, Tag, COUNT(*) OVER(partition by id) as cnt
FROM pagetags
WHERE Tag in(1,2,4)
GROUP BY id, tag
) a WHERE a.cnt = 3
于 2012-09-24T11:35:56.083 に答える
0
SELECT distinct(PageID)
FROM   pagetags
WHERE  TagID IN (1,2,4)
and PageID in
(select distinct(PageID) from pagetags group by PageID having count(TagID)=3)
group by PageID
于 2014-01-06T11:02:37.437 に答える
0

マーティン・スミスからの選択された回答

SELECT PageID
FROM   pagetags
WHERE  TagID IN ( 1, 2, 4 )
GROUP  BY PageID
HAVING Count(DISTINCT TagID) = 3

は正しいですが、速度が問題になる場合は、これらを試してください。

私は同じことをしている大きなテーブルを持っており、次のようにして10倍優れたパフォーマンスを得ました.
300 万行のテーブルから 272 を返すクエリの 2.0 秒に対して 0.2 秒。
また、5 つのタグと同じ 10x の大きなテーブルでテストしましたが、現在は 0.5 対 5.0 です。
インデックスは PageID、数百万の PageID と数百の TagID を持つ TagID です。
多くのオブジェクトが複数値プロパティにタグ付けされている一般的なシナリオ。

    SELECT distinct(p1.PageID)
    FROM   pagetags p1
    JOIN   pagetags p2
      ON   p2.PageID = p1.PageID
      AND  p2.TagID = 2 
    JOIN   pagetags p3
      ON   p3.PageID = p1.PageID
      AND  p3.TagID = 4
    WHERE  p1.PageID = 1
 ORDER BY  p1.PageID

また

   SELECT  distinct(PageID)
    FROM   pagetags
    WHERE  TagID = 1
   INTERSECT
   SELECT  distinct(PageID)
    FROM   pagetags
    WHERE  TagID = 2 
   INTERSECT
   SELECT  distinct(PageID)
    FROM   pagetags
    WHERE  TagID = 4 
 ORDER BY  PageID

結合が 5 つを超えると、クエリ オプティマイザーが不適切な決定を下すことが多いため、最後の結合を優先します。
これにより、別の集計に必要な場合でも Group By を使い果たしません。

于 2012-09-24T12:24:57.730 に答える