SQL-Abfrage, die unterschiedliche Ergebnisse liefert, die mehrere Spalten übereinstimmen

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

  •  05-07-2019
  •  | 
  •  

Frage

Sorry, ich hätte keinen besseren Titel für mein Problem bieten, wie ich zu SQL ganz neu bin. Ich suche nach einem SQL-Abfrage-String, die unten Problem löst.

Lassen Sie uns die folgende Tabelle übernehmen:

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

Jetzt möchte ich alle verschiedene Dokument-IDs auszuwählen, die ein oder mehrere Tags enthalten (aber diejenigen, müssen alle angegebenen Tags zur Verfügung stellen). Zum Beispiel: Wählen Sie alle document_id die mit tag1 und tag2 zurückkehren würde 1 und 3 (aber nicht 4 zum Beispiel, da es nicht tag2 hat).

Was wäre der beste Weg, das zu tun?

Viele Grüße, Kai

War es hilfreich?

Lösung

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

Edit:

Aktualisiert mangels Zwänge ...

Andere Tipps

Dies setzt voraus, DocumentID und Tag sind die Primärschlüssel.

Bearbeiten : Geänderte Klausel mit einzelnen Tags zu zählen. Auf diese Weise ist es egal, was der Primärschlüssel ist.

Testdaten

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

Abfrage

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

Ergebnisse

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

Stellen Sie N und die Tag-Liste nach Bedarf.

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

Wie Sie die Liste der Tags in der generieren where-Klausel auf Ihre Anwendungsstruktur abhängt. Wenn Sie dynamisch die Abfrage als Teil des Codes zu erzeugen sind, dann könnten Sie einfach die Abfrage als eine große dynamisch generierte Zeichenfolge konstruieren.

Wir haben immer gespeicherten Prozeduren verwendet, um die Daten abzufragen. In diesem Fall gehen wir in der Liste der Tags als XML-Dokument. - ein Verfahren, wie das könnte etwas wie eine von ihnen suchen, wo das Eingabeargument wäre

<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

oder

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

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top