Sie OUTER können GILT:
SELECT i.*
FROM Items i
OUTER APPLY (
SELECT COUNT(*) as TagsCount
FROM ItemTags it
INNER JOIN Tags t
ON t.TagID = it.TagID
WHERE i.ItemID = it.ItemID
AND t.TagName IN ('tag1','tag2')
) as tt
WHERE TagsCount = 2
Zuerst bekommen wir alle ItemID
's mit gezählt TagsID
' s. Dann kommen Sie mit Items
Tabellen mit Filtern nur diejenigen, die TagsCount = 2
EDIT # 1
hinzufügen Probe haben:
;WITH Items AS (
SELECT *
FROM (VALUES
(1,'Item1',100),(2,'Item2',50),(3,'Item3',90),(4,'Item4',63),(5,'Item5',75)
)as t(ItemID,ItemName,ItemCost)
)
, Tags AS (
SELECT *
FROM (VALUES
(1,'tag1'),(2,'tag2'),(3,'tag3'),(4,'tag4'),(5,'tag5')
) as t(TagID, TagName)
)
, ItemTags AS (
SELECT *
FROM (VALUES
(1,1),(1,2), --This
(2,1),(2,2),(2,3), --and that records we need to get
(3,1), (3,3),(3,4),
(4,2), (4,5),
(5,1)
) as t(ItemID, TagID)
)
SELECT i.*
FROM Items i
CROSS APPLY (
SELECT COUNT(*) as TagsCount
FROM ItemTags it
INNER JOIN Tags t
ON t.TagID = it.TagID
WHERE i.ItemID = it.ItemID
AND t.TagName IN ('tag1','tag2')
HAVING COUNT(*) = 2
) as tt
Ausgang:
ItemID ItemName ItemCost
1 Item1 100
2 Item2 50
EDIT # 2
Wenn Sie Elemente ohne tag3
-Tags filtern möchten, können Sie den linken Join hinzufügen.
SELECT i.*
FROM Items i
CROSS APPLY (
SELECT COUNT(*) as TagsCount
FROM ItemTags it
INNER JOIN Tags t
ON t.TagID = it.TagID
WHERE i.ItemID = it.ItemID
AND t.TagName IN ('tag1','tag2')
HAVING COUNT(*) = 2
) as tin
LEFT JOIN (
SELECT it.Itemid
FROM ItemTags it
INNER JOIN Tags t
ON t.TagID = it.TagID
WHERE t.TagName IN ('tag3')
) tnot
ON tnot.Itemid = i.itemid
WHERE tnot.ItemId is NULL
Wenn yo von einigen Tags filtern möchten Sie temporäre Tabelle mit Elementen verwenden können, die eine Tags hat, und hat Tags, die Sie nicht brauchen, und dann kommen. Auch dynamisches SQL kann eine Option sein.
Das ist ziemlich ordentlich, und ich stelle mir die Gruppe nach Skalen relativ gut vor (gegenüber der äußeren Anwen- dungslösung). Hypothetisch, würde ich, wenn ich 30 Bedingungen auslöste, diesen Ansatz mit 30 Summensätzen (Fall ...) oder etwas anderem verwenden? – Vok
@Vok. . . Absolut. Die "GROUP BY" hat im Wesentlichen konstante Leistung unabhängig von der Anzahl der Bedingungen (der große Aufwand ist die Aggregation, nicht die Berechnung einer anderen aggregierten Spalte). Die 'JOIN'-Methode funktioniert oft besser für eine oder zwei Bedingungen, aber die komplexen Abfragen können schwer zu warten sein und den Optimierer verwirren. –