Vinzenz Mai: Mehrere Bedingungen über mehrere Datensätze verteilt Gruppieren

Beitrag lesen

Hallo,

mir wurde bereits heute schon mal geholfen, bei einem anderen Problem mit einer Datenbank.

Jetzt habe ich noch eine Frage, ich hoffe das ist jetzt kein Doppelposting.

grundsätzlich hätte ich Dir dazu geraten, diese Frage hier in Deinem alten Thread unterzubringen - und zwar als Antwort auf Dein Ausgangsposting. Du sparst Dir die Hinweise auf die darunterliegenden Daten.

titel | filter
------+-------
abc1  | 10
abc1  | 20
abc2  | 10
abc2  | 20
abc2  | 30
abc3  | 10
abc3  | 40
abc4  | 20
abc4  | 50

Jetzt möchte ich alle Titel deren Filter ZUMINDEST (10 UND 20) ist. Sprich, das Ergebnis sollte so aussehen:

titel

abc1
abc2

Mir gefällt Deine Art der Fragenstellung.

Gibts statt dem OR oder AND einen "ZUMINDEST" Operator oder ähnliches, bzw. wie kann ich mein Problem sonst lösen?

Drei Möglichkeiten kommen mir spontan in den Sinn:

1. Nutze einen Selfjoin:

  
SELECT                   -- Gib mir  
    t1.titel             -- die Titel  
FROM                     -- aus meiner  
    test t1              -- Tabelle, die hier über t1 angesprochen wird  
INNER JOIN               -- die mit  
    test t2              -- sich selbst verknüpft ist  
ON                       -- über  
    t1.titel = t2.titel  -- gleiche Titel  
WHERE                    -- wobei  
    t1.filter = 10       -- der Filter in der "ersten" Tabelle den Wert 10  
AND                      -- und  
    t2.filter = 20;      -- in der "zweiten" Tabelle den Wert 20 hat.

Wie ich in meinem Artikel anmerke, skaliert der Selfjoin nicht gut, insbesondere, wenn ich an

Ein Titel kann übrigens einen oder mehrere Filter haben.

denke. Die Erweiterung auf drei Filter wäre vom Prinzip her einfach.

2. Nutze Subselects:

  
SELECT                     -- Gib mir  
    t1.titel               -- die Titel,  
FROM  
    test t1  
WHERE                      -- die den  
    t1.filter = 10         -- Filterwert 10 haben,  
AND                        -- und  
    t1.titel IN (          -- in der  
        SELECT             -- Liste  
            t2.titel       -- der Titel enthalten sind,  
        FROM  
            test t2  
        WHERE              -- die  
            t2.filter = 20 -- den Filterwert 20 haben  
    );

Die Erweiterung auf weitere Filter erfolgt analog.

3. Nutze COUNT(*) in einem Subselect:

  
SELECT                         -- Gib mir  
    v.titel                    -- die Titel,  
FROM (                         -- die in der  
    SELECT DISTINCT            -- Liste der eindeutigen Einträge  
        t1.titel,              -- der Titel  
        t1.filter              -- und Filterwerte auftreten,  
    FROM  
        test t1  
    WHERE                      -- die die  
        t1.filter IN (10, 20)  -- Filterwerte 10 oder 20 haben  
    ) v                        -- (Das Subselect benötigt zwingend einen Namen)  
GROUP BY                       -- wobei wir  
    v.titel                    -- nach den Titeln gruppieren  
HAVING                         -- und nur die haben möchten  
    COUNT(*) = 2               -- die genau zweimal vorkommen.

Diese dritte Variante lässt sich offensichtlich am einfachsten erweitern.

Deine Aufgabe wäre es, die Performance der verschiedenen Versionen mit Deinen Daten zu prüfen. Bestimmt gibt es noch weitere Möglichkeiten, zu dem von Dir gewünschten Resultat zu gelangen.

Freundliche Grüße

Vinzenz