SQL-запрос, который выдает различные результаты, соответствующие нескольким столбцам

StackOverflow https://stackoverflow.com/questions/1202668

  •  05-07-2019
  •  | 
  •  

Вопрос

Извините, я не смог придумать лучшего названия для своей проблемы, поскольку я совсем новичок в SQL.Я ищу строку SQL-запроса, которая решает приведенную ниже проблему.

Давайте предположим, что следующая таблица:

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

Теперь я хочу выбрать все отдельные идентификаторы документа, которые содержат один или несколько тегов (но они должны содержать все указанные теги).Например:Выберите все document_id с tag1, и tag2 вернет 1 и 3 (но не 4, например, поскольку у него нет tag2).

Каков был бы наилучший способ сделать это?

С уважением, Кай

Это было полезно?

Решение

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

Редактировать:

Обновлено из-за отсутствия ограничений...

Другие советы

Это предполагает, что documentId и Tag являются первичным ключом.

Редактировать:Изменено предложение 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
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

КОНЕЦ

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top