[MySQL] Problem mit mehreren JOINS und Aggregat-Funktionen

Eroli

Erfahrenes Mitglied
Hallo zusammen,

ich habe ein Problem mit mehreren JOINS verbunden mit Aggregat-funktionen (hier: COUNT).
Hier mal ein einfaches Beispiel:

Ich habe 3 Tabellen: Eine Artikel-Tabelle mit Titel, eine View-Tabelle mit der Anzahl an Views des Artikels und eine dritte Kommentar-Tabelle (ist nur ein Beispiel, entspricht nicht meiner Struktur). Sagen wir, dass wir nur einen Artikel haben, 9 Views und 3 Kommentare.

Folgendes SQL-Script:
Code:
SELECT a.Title, v.Irgendwas, COUNT(k.PK_Kommentar) FROM artikel a
JOIN views v ON v.FK_Artikel = a.PK_Artikel
LEFT OUTER JOIN kommentare k ON k.FK_Artikel = a.PK_Artikel
GROUP BY v.FK_Artikel

Das GROUP-By brauche ich, damit ich für jeden KOmmentar (falls es mehrere sind) alle Views richtig zurückgeliefert bekomme.

Das LEFT OUTER JOIN brauche ich, da nicht jeder Artikel einen Kommentar haben muss.

So, wenn wir nun 9 Views haben für einen Artikel mit 3 Kommentaren, dann liefert mir dieses SQL-Script jedoch die Zahl 27 für die Kommentare zurück. Das entsteht wohl durch die 9*3 (=27). Wenn ich einen vierten Kommentar einfüge, dann erhalte ich durch dieses Script die Zahl 36 für die Anzahl an Kommentaren zurückgeliefert.

Kann da jemand Licht ins Dunkel bringen?

Vielen Dank,
Eroli
 
Ist logisch dass du 27 EEInträge kriegst.

Du musst jedes Feld das du im SELECT zurückgibst entweder im GROUP BY drin haben oder mit einer Aggregat-Funtion versehen.

Gruppieren willst du in dem Fall auf die Artikel.
In den COUNT() solltest du mit DISTINCT ergänzen, damit er nur nicht mehrfach zählt.

Am besten schaust du dir mal das Resultat an ohne GROUP BY und überlegst dir dann wie der GROUP BY aussehen muss.

In deinem Fall etwa so
SQL:
SELECT 
    a.Title, 
    COUNT(DISTINCT k.PK_Kommentar)  AS anzahl_kommentare,
    COUNT(DISTINCT v.PK_View) AS anzahl_views
FROM 
    artikel a
    JOIN views v ON v.FK_Artikel = a.PK_Artikel
    LEFT OUTER JOIN kommentare k ON k.FK_Artikel = a.PK_Artikel
GROUP BY 
    a.Title
 
Zuletzt bearbeitet von einem Moderator:
Hallo,

vielen Dank für deine Antwort und entschuldige meine etwas späte Antwort.

Dein Tipp mit den DISTINCTs funktionert ganz wunderbar mit der Anzahl an Kommentaren. Dank.

Jedoch funktionieren die Anzahl Views noch nicht richtig. Das ist etwas schwer zu erklären, denn die eigentliche Struktur passt nicht mehr so gut in das Beispiel hier, jedoch ist es so, dass jeder View-Datensatz ein Integer-Feld mit der Anzahl an Views besitzt. Diese müssen summiert werden, um an alle Views zu kommen.
Also in etwa so:

SQL:
SELECT 
    a.Title, 
    COUNT(DISTINCT k.PK_Kommentar)  AS anzahl_kommentare,
    SUM(DISTINCT v.Anzahl) AS anzahl_views
FROM 
    artikel a
    JOIN views v ON v.FK_Artikel = a.PK_Artikel
    LEFT OUTER JOIN kommentare k ON k.FK_Artikel = a.PK_Artikel
GROUP BY 
    v.FK_Artikel

Ich konnte noch nicht wirklich ein Muster erkennen, jedoch ist das Resultat anzahl_views bei 3 View-Datensätzen mit den Anzahl-Werten 4,2 und 1 nur 5 und nicht 7...Woran das liegt, ist mir derzeit noch ein Rätsel...

Vielleicht hast du eine Idee?

Viele Grüße,
Eroli

EDIT: anzahl_views ist zum beispiel bei 5 view-datensätzen und 4-comment-datensätzen = 28 (Ohne DISCTINCT bei den Views).
28/4 = 7 wäre der richtige Wert.
Ich bin verwirrt...

Beispiel
Code:
ID / ArtikelID / GruppenID / Views
1 / 1 / 1 / 2    (ein View-Datensatz mit einem View)
2 / 1 / 2 / 1    (ein gruppierter View-Datensatz mit je einem View)
3 / 1 / 2 / 1    (ein gruppierter View-Datensatz mit je einem View)
4 / 2 / 3 / 1    (ein anderer View-Datensatz für einen anderen Artikel)

Das richtige Resultat müsste hierbei also 4 sein.
 
Zuletzt bearbeitet:
Hallo nochmal,

da das alte Beispiel nicht mehr taugt, hier mal ein neues:

Wir haben Artikel, Bilder die zu einem Artikel gehören und die Kommentare.
Dabei können die Bilder gruppiert werden (quasi ein Album). Solch ein Album kann runtergeladen werden und ich möchte nun die Anzahl der gesamten Downloads aller Alben, die zu diesem Artikel gehören, ausgegeben bekommen:

Bilder-Tabelle:
Code:
ID / ArtikelID / GruppenID / Downloads / ...

SQL:
SELECT 
    a.Title, 
    COUNT(DISTINCT k.PK_Kommentar)  AS anzahl_kommentare,
    SUM(DISTINCT b.Downloads) AS anzahl_downloads
FROM 
    artikel a
    JOIN bilder b ON b.FK_Artikel = b.PK_Artikel
    LEFT OUTER JOIN kommentare k ON k.FK_Artikel = a.PK_Artikel
GROUP BY 
    b.ArtikelID

Das Problem ist dabei (da bin ich mir aber noch nicht sicher), dass gruppierte Datensätze durch das DISTINCT rausgefiltert werden und sich dadrin die falsche Anzahl gründet.

EDIT: Im Beispiel ist es nur möglich, dass man komplette Alben runterlädt, daher ergeben sich für gruppierte Bilder immer dieselbe Anzahl an Downloads. Das filtert das DISTINCT raus und das stört mich etwas. Kann man da etwas machen?

EDIT2: Ist es nicht sogar so, dass wenn man nur Bilder-Datensätze (zig-tausend) alle mit nur einem View hat, obiges Statement das Resultat 1 liefern würde?

EDIT3: Kann man das mit einem Subselect umgehen?

EDIT4:
Warum klappt das folgende eigentlich nicht?
SQL:
SELECT 6 AS a, 2 AS b, a/b AS c
Das klappt ja:
SQL:
SELECT 6/2 AS c

So könnte ich mein Problem ja auch lösen, wenn es denn funktionieren würde...
 
Zuletzt bearbeitet:

Neue Beiträge

Zurück