Mehrere Bedingungen über mehrere Datensätze verteilt Gruppieren
asmodin
- datenbank
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.
Ausgangslage: MySQL
Ich habe 3 Tabellen die ich per LEFT JOIN verbinde (also 2 Tabellen über eine Beziehungstabelle), soweit alles in Ordnung.
Ohne weitere Bedingung sieht das etwa so aus:
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
Probiert habe ich das so:
GROUP BY titel HAVING filter = 10 OR filter = 20
Gruppiert ist es richtig, allerdings sieht das so aus:
titel
-----
abc1
abc2
abc3
abc4
Nächster Versuch:
GROUP BY titel HAVING filter = 10 AND filter = 20
Da bekomme ich keine Ergebnisse mehr, was ich auch nachvollziehen kann.
Ein Titel kann übrigens einen oder mehrere Filter haben. Leider bin ich aus der MySQL-Doku nicht schlau geworden, der Abschnitt zu HAVING ist sehr kurz. Zudem bin ich mir nicht sicher, ob das überhaupt das Richtige für mich ist.
Gibts statt dem OR oder AND einen "ZUMINDEST" Operator oder ähnliches, bzw. wie kann ich mein Problem sonst lösen?
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
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.
Die Daten sind ja andere, das vorherige war ein MSSQL-Problem :) das hier ist eine andere Baustelle, darum war ich mir nicht sicher.
Mir gefällt Deine Art der Fragenstellung.
Danke. Das ist aber purer Eigennutz. Mit ordentlicher Fragestellung und Problembeschreibung kommt man schneller zum Ziel!
- Nutze COUNT(*) in einem Subselect:
Diese dritte Variante lässt sich offensichtlich am einfachsten erweitern.
Das sieht mir für meine Zwecke am vernünftigsten aus. Ich denke ich werde mich mit dieser Methode beschäftigen. Ich melde mich dann wieder. Danke vorerst für deine Hilfe.
- Nutze COUNT(*) in einem Subselect:
Diese dritte Variante lässt sich offensichtlich am einfachsten erweitern.
Das sieht mir für meine Zwecke am vernünftigsten aus. Ich denke ich werde mich mit dieser Methode beschäftigen. Ich melde mich dann wieder. Danke vorerst für deine Hilfe.
Hallo nochmal,
die Lösung #3 funktioniert wunderbar.
Vielen Dank