Prüfung auf mehrere Kriterien
Kürzlich erreichte mich die Anfrage aus unserer PASS-Gruppe, wie man am effektivsten aus einer Menge von Lieferungen diejenigen herausfinden könnte, wo mehrere Kriterien erfüllt sein müssten. Eine Kombination von Joins oder AND-Bedingungen schien nicht der richtige Weg zu sein.
Die Fragestellung
Gegeben ist eine Menge von Lieferungen, die sich aus Artikeln und Losen zusammensetzt. Ein Los ist hier vergleichbar mit einer Charge. Gesucht werden z. B. alle Lieferungen, in denen der Artikel 1 aus Los 101 und der Artikel 2 aus Los 102 enthalten sind.
Die Lösung
Man speichert zuerst die gewünschten Artikel und Lose in einer Hilfstabelle ab, die unsere Suchmaske darstellen soll. Danach verknüpft man die Lieferungen mit der Suchmaske und zählt, wie oft jede Lieferung dort einen Treffer hatte. Stimmt am Ende die Anzahl der Treffer mit der Anzahl der Bedingungen in der Suchmaske überein, hat man eine Lieferung gefunden.
Das T-SQL Skript
Das Skript ist weitestgehend selbsterklärend und besteht überwiegend aus der Zusammenstellung der Beispieldaten. Am Ende wird alles mit einer CTE (Common Table Expression) voranalysiert und dann ausgewertet. Die Kombination von Lieferung, Artikel und Los in der Ausgangstabelle ist eindeutig.
DECLARE @tab AS TABLE (Lieferung INT, Artikel INT, Los INT);
INSERT INTO @tab(Lieferung, Artikel, Los) VALUES (1, 1, 101);
INSERT INTO @tab(Lieferung, Artikel, Los) VALUES (1, 1, 102);
INSERT INTO @tab(Lieferung, Artikel, Los) VALUES (1, 3, 101);
INSERT INTO @tab(Lieferung, Artikel, Los) VALUES (1, 2, 102);
INSERT INTO @tab(Lieferung, Artikel, Los) VALUES (2, 1, 101);
INSERT INTO @tab(Lieferung, Artikel, Los) VALUES (2, 1, 102);
INSERT INTO @tab(Lieferung, Artikel, Los) VALUES (2, 3, 101);
DECLARE @Suchmaske AS TABLE (Artikel INT, Los INT);
INSERT INTO @Suchmaske(Artikel, Los) VALUES(1, 101);
INSERT INTO @Suchmaske(Artikel, Los) VALUES(2, 102);
-- Prüfung mit CTE und Join
WITH Vorberechnung AS
(SELECT Lieferung, COUNT(*) AS Anzahl
FROM @tab t1
INNER JOIN @Suchmaske s1 ON t1.Artikel = s1.Artikel AND t1.Los = s1.Los
GROUP BY Lieferung
)
SELECT DISTINCT Lieferung
FROM Vorberechnung v
WHERE v.Anzahl = (SELECT COUNT(*) FROM @Suchmaske)
;
Print article | This entry was posted by cmu on 06.03.14 at 15:11:00 . Follow any responses to this post through RSS 2.0. |