Requête SQL donnant des résultats distincts correspondant à plusieurs colonnes

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

  •  05-07-2019
  •  | 
  •  

Question

Désolé, je ne pourrais pas donner un meilleur titre à mon problème car je suis assez nouveau en SQL. Je recherche une chaîne de requête SQL qui résout le problème ci-dessous.

Supposons le tableau suivant:

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

Je souhaite maintenant sélectionner tous les identifiants de document distincts contenant une ou plusieurs balises (mais celles-ci doivent fournir toutes les balises spécifiées). Par exemple: Sélectionnez tous les document_id avec tag1 et tag2 renverra 1 et 3 (mais pas 4 par exemple car il n'a pas tag2).

Quel serait le meilleur moyen de le faire?

Cordialement, Kai

Était-ce utile?

La solution

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

Modifier:

Mis à jour par manque de contraintes ...

Autres conseils

Cela suppose que DocumentID et Tag sont la clé primaire.

Edit : La clause HAVING a été modifiée pour compter les balises DISTINCT. Ainsi, la clé primaire n'a pas d'importance.

Données de test

-- 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

Requête

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

Résultats

DocumentID
----------
1
3
select DOCUMENT_ID
      TAG in ("tag1", "tag2", ... "tagN")
   group by DOCUMENT_ID
   having count(*) > N and 

Ajustez N et la liste de balises si nécessaire.

Select distinct document_id 
from {TABLE} 
where tag in ('tag1','tag2')
group by id 
having count(tag) >=2 

La manière dont vous générez la liste des balises dans la clause where dépend de la structure de votre application. Si vous générez dynamiquement la requête dans votre code, vous pouvez simplement la construire sous la forme d'une grosse chaîne générée dynamiquement.

Nous avons toujours utilisé des procédures stockées pour interroger les données. Dans ce cas, nous transmettons la liste des balises sous forme de document XML. - une procédure comme celle-ci pourrait ressembler à l'une d'elles où l'argument d'entrée serait

<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

OU

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

FIN

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top