4

申し訳ありませんが、私は SQL にまったく慣れていないため、問題に適切なタイトルを付けることができませんでした。以下の問題を解決する SQL クエリ文字列を探しています。

次の表があるとします。

DOCUMENT_ID | 鬼ごっこ
----------------------------
   1 | タグ1
   1 | タグ2
   1 | tag3
   2 | タグ2
   3 | タグ1
   3 | タグ2
   4 | タグ1
   5 | tag3

ここで、1 つ以上のタグを含むすべての個別のドキュメント ID を選択したいと考えています (ただし、指定されたすべてのタグを提供する必要があります)。例: tag1 と tag2 を持つすべての document_id を選択すると、1 と 3 が返されます (ただし、tag2 がないため、たとえば 4 は返されません)。

それを行う最善の方法は何ですか?

よろしく、カイ

4

4 に答える 4

14
SELECT document_id
FROM table
WHERE tag = 'tag1' OR tag = 'tag2'
GROUP BY document_id
HAVING COUNT(DISTINCT tag) = 2

編集:

制約がないために更新されました...

于 2009-07-29T20:00:42.797 に答える
7

これは、DocumentID と Tag が主キーであることを前提としています。

編集: DISTINCT タグをカウントするように HAVING 句を変更しました。そうすれば、主キーが何であるかは関係ありません。

テストデータ

-- Populate Test Data
CREATE TABLE #table (
  DocumentID varchar(8) NOT NULL, 
  Tag varchar(8) NOT NULL
)

INSERT INTO #table VALUES ('1','tag1')
INSERT INTO #table VALUES ('1','tag2')
INSERT INTO #table VALUES ('1','tag3')
INSERT INTO #table VALUES ('2','tag2')
INSERT INTO #table VALUES ('3','tag1')
INSERT INTO #table VALUES ('3','tag2')
INSERT INTO #table VALUES ('4','tag1')
INSERT INTO #table VALUES ('5','tag3')

INSERT INTO #table VALUES ('3','tag2')  -- Edit: test duplicate tags

クエリ

-- Return Results
SELECT DocumentID FROM #table
WHERE Tag IN ('tag1','tag2')
GROUP BY DocumentID
HAVING COUNT(DISTINCT Tag) = 2

結果

DocumentID
----------
1
3
于 2009-07-29T20:06:53.923 に答える
1
select DOCUMENT_ID
      TAG in ("tag1", "tag2", ... "tagN")
   group by DOCUMENT_ID
   having count(*) > N and 

必要に応じて N とタグ リストを調整します。

于 2009-07-29T20:03:29.670 に答える
-1
Select distinct document_id 
from {TABLE} 
where tag in ('tag1','tag2')
group by id 
having count(tag) >=2 

where 句でタグのリストを生成する方法は、アプリケーションの構造によって異なります。コードの一部としてクエリを動的に生成している場合は、動的に生成された大きな文字列としてクエリを単純に作成できます。

データのクエリには常にストアド プロシージャを使用しました。その場合、タグのリストを XML ドキュメントとして渡します。- そのようなプロシージャは、入力引数が次のいずれかのようになります

<tags>
   <tag>tag1</tag>
   <tag>tag2</tag>
</tags>


CREATE PROCEDURE [dbo].[GetDocumentIdsByTag]
@tagList xml
AS
BEGIN

declare @tagCount int
select @tagCount = count(distinct *) from @tagList.nodes('tags/tag') R(tags)


SELECT DISTINCT documentid
FROM {TABLE}
JOIN @tagList.nodes('tags/tag') R(tags) ON {TABLE}.tag = tags.value('.','varchar(20)')
group by id 
having count(distict tag) >= @tagCount 

END

また

CREATE PROCEDURE [dbo].[GetDocumentIdsByTag]
@tagList xml
AS
BEGIN

declare @tagCount int
select @tagCount = count(*) from @tagList.nodes('tags/tag') R(tags)


SELECT DISTINCT documentid
FROM {TABLE}
WHERE tag in
(
SELECT tags.value('.','varchar(20)') 
FROM @tagList.nodes('tags/tag') R(tags)
}
group by id 
having count( distinct tag) >= @tagCount 
END

終わり

于 2009-07-29T20:02:00.627 に答える