SQL-Abfrage, die unterschiedliche Ergebnisse liefert, die mehrere Spalten übereinstimmen
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
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