Problem mit GROUP BY … Mehrfacheinträge in Bewertungstabelle zusammenfassen

loefchen

Benutzer
Beiträge
8
Hallo zusammen!

Ich steh grad mächtig aufm Schlauch. Es geht um eine Ratinganzeige für Vodka-Filler-Kombinationen. Ich habe mehrere Datenbanken verknüft:

vodkamatch_vodkas ist eine Tabelle mit ID, VODKA_NAME
vodkamatch_fillers ist eine Tabelle mit ID, FILLER_NAME, VARIANTE
vodkamatch_matches ist eine Tabelle mit ID, VODKA_NR, FILLER_NR, RATING

mittels


SELECT T1.VODKA_NAME, T1.NR, T2.FILLER_NAME, T2.VARIANTE, T3.RATING FROM vodkamatch_vodkas T1, vodkamatch_fillers T2, vodkamatch_matches T3 WHERE T1.NR = T3.VODKA_NR AND T2.NR = T3.FILLER_NR ORDER BY T3.RATING DESC

Das funktioniert soweit einwandfrei, doch jetzt kommt dazu, dass Kombinationen doppelt bewertet werden.
Diese Doppelbewertungen möchte ich mit einem GROUP BY zusammenfassen und ein Durchschnittsrating mit AVG berechnen.

Ich durchsteige es aber leider einfach nicht und bringe nichts funktionales zusammen.

Wer kann helfen?
 
Werbung:
Scheinbar hab ich's doch hinbekommen:

SELECT T1.VODKA_NAME, T1.NR, T2.FILLER_NAME, T2.VARIANTE, T3.RATING,
AVG(T3.RATING)
FROM vodkamatch_vodkas T1, vodkamatch_fillers T2, vodkamatch_matches T3
WHERE T1.NR = T3.VODKA_NR AND T2.NR = T3.FILLER_NR
GROUP BY T3.VODKA_NR,T3.FILLER_NR
ORDER BY T3.RATING DESC

Nachtrag: Das mit dem AVG klappt scheinbar nicht. Er nimmt keinen Durchschnittswert sondern den ersten der Gruppe. Was habe ich verbaselt?
 
Scheinbar hab ich's doch hinbekommen:

Der Schein trügt. Auch wenn MySQL hier Dir keinen Fehler liefert sondern ein Resultat, so ist die Abfrage dennoch logisch falsch und das Resultat maximal zufällig das, was Du erwartest bzw. was richtig ist. Ist ein altbekannter Bug in MySQL, der sehr gern von Anfängern gefunden wird.
 
Zuerst einmal: Crosspostings verstoßen gegen die Forenregeln.

Alle Spalten im Resultat müssen entweder aggregiert oder gruppiert sein. Das ist quasi ein Naturgesetz, nur bei den Jungs von MySQL noch nicht angekommen. MySQL läßt verstöße dagegen zu, liefert ohne weitere Hinweise falsche Ergebnisse.

Befolge also das Gesetz.

Andere Datenbanken, (eigentlich alle anderen) kennen Window-Funktionen, die das, was Du machen willst, sehr einfach realisieren können. Aber das kann MySQL auch nicht.
 
Sorry, wusste ich nicht. (@crossposting)

Ich bekomme mit SQL eigentlich immer nur das Nötigste zusammengeschustert, und da stoße ich gerade tatsächlich verständnismäßig an meine Grenzen.

Es wäre also unglaublich nett, wenn du mir sagen könntest, wie ich's abändern müsste, dass es funktioniert.
 
vermutlich suchst Du sowas wie folgt, oder?

Code:
andreas@[local]:5433/test*# select * from vodkas;
 id |  name  
----+--------
  1 | vodka1
  2 | vodka2
  3 | vodka3
(3 rows)

andreas@[local]:5433/test*# select * from fillers;
 id |  name  | variante  
----+---------+-----------
  1 | filler1 | variante1
  2 | filler2 | variante2
(2 rows)

andreas@[local]:5433/test*# select * from matches;
 id | vodka | filler | rating
----+-------+--------+--------
  1 |  1 |  1 |  10
  2 |  1 |  2 |  12
  3 |  2 |  1 |  2
  4 |  2 |  2 |  5
(4 rows)

andreas@[local]:5433/test*# select t1.name as vodka_name, t1.id, t2.name as filler_name, t2.variante, t3.rating, avg(t3.rating) over (partition by t1.id) as avg_per_vodka, avg(t3.rating) over (partition by t2.id) as avg_per_filler from vodkas t1, fillers t2, matches t3 where t1.id=t3.vodka and t2.id=t3.filler  order by t3.rating desc;
 vodka_name | id | filler_name | variante  | rating |  avg_per_vodka  |  avg_per_filler   
------------+----+-------------+-----------+--------+---------------------+--------------------
 vodka1  |  1 | filler2  | variante2 |  12 | 11.0000000000000000 | 8.5000000000000000
 vodka1  |  1 | filler1  | variante1 |  10 | 11.0000000000000000 | 6.0000000000000000
 vodka2  |  2 | filler2  | variante2 |  5 |  3.5000000000000000 | 8.5000000000000000
 vodka2  |  2 | filler1  | variante1 |  2 |  3.5000000000000000 | 6.0000000000000000
(4 rows)

andreas@[local]:5433/test*#
 
Nene,

eher so:

id | vodka | filler | rating
----+-------+--------+--------
1 | 1 | 1 | 5
2 | 1 | 2 | 4
3 | 1 | 1 | 2
4 | 2 | 2 | 5

Es geht um mehrere verschieden bewertete, gleiche Kombinationen, sprich z. B. 2x 1+1.

So in etwa sollte das Ergebnis aussehen.

vodka_name | id | filler_name | variante | rating
------------+----+-------------+-----------+--------+---------------------+--------------------
vodka1 | 1 | filler1 | variante1 | 3.5 |
vodka1 | 2 | filler2 | variante2 | 4 |
vodka2 | 3 | filler2 | variante2 | 5 |

Ich bin jetzt ehrlich gesagt so langsam verständnismäßig wirklich ausgestiegen. Habe versucht, das von dir entsprechend umzusetzen, aber habe nun nen Knoten im Kopf.
So hab ich's gemacht, und ich erhalte nen Fehler...

SELECT T1.VODKA_NAME as VODKA_NAME, T3.NR, T2.FILLER_NAME as FILLER_NAME, T2.VARIANTE, T3.RATING,
AVG(T3.RATING) over (PARTITION by T1.NR) as AVG_PER_VODKA, AVG(T3.RATING) over (PARTITION by T2.NR) as AVG_PER_FILLER
FROM vodkamatch_vodkas T1, vodkamatch_fillers T2, vodkamatch_matches T3
WHERE T1.NR = T3.VODKA_NR AND T2.NR = T3.FILLER_NR
ORDER BY T3.RATING DESC
 
also so:

Code:
andreas@[local]:5433/test*# select * from matches;
 id | vodka | filler | rating
----+-------+--------+--------
  1 |  1 |  1 |  5
  2 |  1 |  2 |  4
  3 |  1 |  1 |  2
  4 |  2 |  2 |  5
(4 rows)

andreas@[local]:5433/test*# select distinct v.name as vodka_name, f.name as filler_name, f.variante as variante, avg(m.rating) over (partition by v.name, f.name) from matches m left join vodkas v on m.vodka=v.id left join fillers f on m.filler=f.id order by vodka_name, filler_name;
 vodka_name | filler_name | variante  |  avg   
------------+-------------+-----------+--------------------
 vodka1  | filler1  | variante1 | 3.5000000000000000
 vodka1  | filler2  | variante2 | 4.0000000000000000
 vodka2  | filler2  | variante2 | 5.0000000000000000
(3 rows)

andreas@[local]:5433/test*#
 
Da gibt er aus:

Fehler: (1064) You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '(partition by V.VODKA_NAME, F.FILLER_NAME) from vodkamatch_matches M left join vodkamatch_' at line 1

(hab die variablen an meine natürlich ausgetauscht...)
 
Werbung:
Zurück
Oben