質問

申し訳ありませんが、私はSQLを初めて使用するため、問題のタイトルをより良く提供できませんでした。 以下の問題を解決するSQLクエリ文字列を探しています。

次の表を想定してみましょう:

DOCUMENT_ID |     TAG
----------------------------
   1        |   tag1
   1        |   tag2
   1        |   tag3
   2        |   tag2
   3        |   tag1
   3        |   tag2
   4        |   tag1
   5        |   tag3

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

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

よろしく、 カイ

役に立ちましたか?

解決

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

編集:

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

他のヒント

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

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

テストデータ

-- 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
select DOCUMENT_ID
      TAG in ("tag1", "tag2", ... "tagN")
   group by DOCUMENT_ID
   having count(*) > N and 

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

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

END

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top