Syntax bei SELECT ... COUNT mit zwei Tabellen
Kalle
- datenbank
0 Philipp Hasenfratz0 Eternius0 Eternius
0 Ilja
Hallöle,
ich habe eine Tabelle mit Vereinen und eine andere Tabelle mit Veranstaltungsterminen. Nun möchte ich eine Liste mit ALLEN Vereinen und der Anzahl ihrer Veranstaltungen, auch bei Null Veranstaltungen.
PROBLEM: Beim Folgenden Query bekomme ich nur Vereine, die mindestens eine Veransatltung haben:
SELECT akt_adressen.nr nr, akt_adressen.name1 name, akt_adressen.plz plz, akt_adressen.ort_nr ort_nr, akt_adressen.ort ort, count(*) ct
FROM akt_adressen
INNER JOIN termine
ON ( termine.tag >= '".$tag_von."'
and termine.tag <= '".$tag_bis."'
and termine.loe_kz = 0
and akt_adressen.nr = termine.veranstalter_nr )
GROUP BY plz, name
Wo liegt mein Denkfehler?
Liebe Grüße aus Worms, Kalle
Halihallo Kalle
PROBLEM: Beim Folgenden Query bekomme ich nur Vereine, die mindestens eine Veransatltung haben:
LEFT OUTER JOIN ist dein Freund.
INNER JOIN termine
ON ( termine.tag >= '".$tag_von."'
and termine.tag <= '".$tag_bis."'
and termine.loe_kz = 0
and akt_adressen.nr = termine.veranstalter_nr )
INNER JOIN ... ON (...)
definiert _nur_ die Join-Bedingung! - Alles was _nicht_ zur Join-
Bedignung gehört, kommt in die WHERE-Klausel!
In deinem Beispiel gehört wohl alles ausser
akt_adressen.nr=termine.veranstalter_nr
in die WHERE-Klausel. Aber: daran hängt der Fehler sicher nicht, es
ist eine reine Stil-Bemerkung.
Viele Grüsse
Philipp
Hallo Philipp,
habe den SELECT geändert, aber das Ergebnis ist genau gleich, es fehlen weiterhin die Vereine ohne Termine:
SELECT akt_adressen.nr nr, akt_adressen.name1 name, akt_adressen.plz plz, akt_adressen.ort_nr ort_nr, akt_adressen.ort ort, count(*) ct
FROM akt_adressen
LEFT OUTER JOIN termine
ON ( akt_adressen.nr = termine.veranstalter_nr )
WHERE termine.tag >= '".$tag_von."'
AND termine.tag <= '".$tag_bis."'
AND termine.loe_kz = 0
GROUP BY plz, name
Das war also nicht die Lösung.
Hast du noch einen Tipp?
Liebe Grüße, Kalle.
Halihallo Kalle
SELECT akt_adressen.nr nr, akt_adressen.name1 name, akt_adressen.plz plz, akt_adressen.ort_nr ort_nr, akt_adressen.ort ort, count(*) ct
FROM akt_adressen
LEFT OUTER JOIN termine
ON ( akt_adressen.nr = termine.veranstalter_nr )
WHERE termine.tag >= '".$tag_von."'
AND termine.tag <= '".$tag_bis."'
AND termine.loe_kz = 0
GROUP BY plz, name
Falls es zu einem Verein kein Termin gibt, werden die Attribute des
Termins mit NULL aufgefüllt. Die Konsequenz ist, dass die WHERE-
Bedingung nicht mehr zugrifft und _deshalb_ werden diese Vereine
dennoch nicht selektiert. LEFT OUTER JOIN funktioniert aber :-)
Vielleicht unterstützt deine Datenbank eine Art
IS_NULL(termine.id)
dann könntest du etwa folgende WHERE-Klausel entwerden:
... WHERE
IS_NULL(termine.id) OR
(
termine.tag >= '...' AND
termine.tag <= '...' AND
termine.loe_kz = 0
)
sprich: Entweder der Verein hat gar keinen Termin _oder_ er erfüllt
alle genannten "Termin-Eigenschaften".
Das war also nicht die Lösung.
Ich bringe dir nur Vorschläge. In die Lösung umsetzen, musst du schon
selber.
Hast du noch einen Tipp?
War der mit LEFT OUTER JOIN denn nicht gut?
Viele Grüsse
Philipp
yo,
Die Konsequenz ist, dass die WHERE-
Bedingung nicht mehr zugrifft und _deshalb_ werden diese Vereine
dennoch nicht selektiert. LEFT OUTER JOIN funktioniert aber :-)
wenn mch nicht alles täuscht, dann sollte der optimierer zuerst die bedigungen in den WHERE Klausel überprüfen und dann erst die JOIN Bedingung durchführen.
Ilja
soweit ich das weiss ist das das NULL problem, dass alle Datensätze die NULL enthalten automatisch falsch sind ?!
kommentar/hilfe bitte ;-)
da hammers doch: http://www.mysql.de/doc/de/Problems_with_NULL.html
ich würde die tabelle einfach umstrukturieren und einen default wert zuweisen der nicht NULL ist sondern ''
yo,
zum einen bekommst du probleme, weil nach der SELECT Klausel nur die spalten erwähnt werden sollten, die auch durch die GROUP BY Klausel gruppiert wurden, mit ausnahme von aggregat funktionen. neuere MySQL Vesionen erlauben zwar solche Konstrukte und schmeissen keine Fehlermeldung aus, das ist aber nicht immer zum vorteil, sondern oft ein rate mal mit rosenthal. insofern würde ich einfach die entsprechenden spalten n der GROUP BY KLausel hinzufügen oder zum Testen erst mal die Spalten in der SELECT Klausel einschränken.
zum anderen solltest du dich an den rat von phillip halten, LEFT JOIN ist dein freund. aggregatfunktionen wie count() zählen NULL werte nicht mit, was aber eigentlich nicht dein problem sein sollte, da du count(*) anwendest.
Ilja