2015-11-12 17 views
5

Ich habe 4 Tabellen namens Shops, Benutzer, Bewertung und Bewertung.SUM() funktioniert nicht in MySQL: SUM() mit DISTINCT

Ich möchte alle Bewertungen für den entsprechenden Shop mit überprüften Benutzerdetails und auch Gesamtbewertung für diesen Shop erhalten.

Ich habe fast mit der einzigen Abfrage getan. Aber das Problem ist, wenn der Shop die gleiche Bewertung für mehrere Male vom selben Nutzer hat, wird er als Einzelbewertung betrachtet. Aber diese Bewertung war korrekt.

d.h

enter image description here

aus dieser Tabelle user_id 3 Arbeitsplatz_id 1 als 4 Mal bewertet wurde. So ist die Zahl 4 und total_rating ist 17.

Meine Frage ist

select review.comments, users.username, count(distinct rating.id) as rating_count, 
sum(distinct rating.rating) as total_rating from users 
left join review on users.id = review.user_id and review.shop_id='1' 
left join rating on users.id = rating.user_id and rating.shop_id='1' 
where review.shop_id='1' or rating.shop_id='1' 
group by users.id, review.user_id, rating.user_id, review.id 

Wenn ich diese Abfrage ausführen ich

bekam

enter image description here

aber ich brauche total_rating 17 für user_id 3 ..

prüfen diese fiddle

+0

Was passiert, wenn Benutzer haben gleiches Geschäft mehr Bewertung als ein? –

+0

@ Code-Mönch Wir können es mehr als einer zeigen. Wie in meinem Beispiel Good, Test Review wurde von demselben Benutzer für den gleichen Shop – RaGu

Antwort

3

Sie setzen DISTINCT IN sum(rating.rating) as total_rating, das ist, warum das Ergebnis (12 = 17-5), da wird es 5 nur einmal enthalten, während Summe berechnet wird.

select review.comments, review.user_id, count(distinct rating.id) as rating_count, 
    sum(rating.rating) as total_rating from users 
    left join review on users.id = review.user_id and review.shop_id='1' 
    left join rating on users.id = rating.user_id and rating.shop_id='1' 
    where review.shop_id='1' or rating.shop_id='1' 
    group by users.id, review.user_id, rating.user_id, review.id 

Hier ist SQLFiddle

Beispielausgabe: enter image description here this helps

+0

versucht, dies nicht funktioniert – RaGu

+0

http://www.sqlfiddle.com/#!9/a5f23/15 –

+0

Bitte überprüfen Sie die Geige angebracht .. es funktioniert ist es nt? –

2

Versuchen Sie dies - Entfernen Sie die eindeutige von sum(rating.rating). Da Sie sum(distinct rating.rating) gab, ignoriert es ein 5 dass Benutzer 3 1.

select review.comments, users.username, count(distinct rating.id) as rating_count, 
sum(rating.rating) as total_rating from users 
left join review on users.id = review.user_id and review.shop_id='1' 
left join rating on users.id = rating.user_id and rating.shop_id='1' 
where review.shop_id='1' or rating.shop_id='1' 
group by users.id, review.user_id, rating.user_id, review.id 
+0

überprüft, versuchte dies, aber kein Glück. – RaGu

+0

Arbeiten. Danke – RaGu

2

Zunächst einmal zu speichern gab: Es macht keinen Sinn, Außen beitreten Datensätze aus einer Tabelle und sie dann in der WHERE-Klausel entfernen. Mit left join review ... sagen Sie: Finden Sie einen passenden Datensatz in der Tabelle Überprüfung, und wenn Sie keine finden, dann fügen Sie Nullen, so halten wir die Benutzer aufnehmen. Dann mit where review.shop_id='1' Sie sagen: Halten Sie nur Datensätze, wo Sie tatsächlich einen Datensatz in Überprüfung gefunden. Du entlässt also die Aufzeichnungen, die du gerade gemacht hast. Ihre WHERE-Klausel macht Ihre LEFT OUTER JOINS nur zu INNEREN VERBINDUNGEN.

Was Ihr tatsächliches Problem betrifft: Das kommt davon, dass Sie zuerst alle Tabellen verbinden und dann erst versuchen, Aggregate aus den resultierenden Datensätzen zu erhalten. Aggregate, bevor er stattdessen:

select 
    rev.comments, 
    usr.username, 
    coalesce(rat.rating_count, 0) as rating_count, 
    rat.total_rating 
from review rev 
join users usr on users.id = review.user_id 
left join 
(
    select user_id, shop_id, count(*) as rating_count, sum(rating) as total_rating 
    from rating 
    group by user_id, shop_id 
) rat on rat.user_id = usr.id and rat.shop_id = rev.shop_id 
where rev.shop_id = 1 
group by rev.id; 
+0

Danke. Es funktioniert. Aber die Abfrage war wenig kompliziert. Ich muss dies in CodeIgniter tun – RaGu

+0

Sie haben Recht, tut mir leid, in Ihrem Fall ist es nicht notwendig, voraggregieren, da es hier keine Verdopplung gibt.(Es könnte sein, wenn Sie Ihre Abfrage erweitert haben, um Daten von einer anderen Tabelle zu bekommen.) Ich wurde von Ihren beiden "distinct" verwirrt, die beide überflüssig sind. –

+0

Sie sollten diese Outer-Join-Sache jedoch begradigen. Und bitte beachten Sie, dass ich die Join-Reihenfolge und die Gruppierung nach Klausel geändert habe, um die Abfrage intuitiver zu gestalten: Es sind * Bewertungen * für einen Shop, den Sie anzeigen möchten, wählen Sie also aus 'Review'. Sie möchten seine Benutzerdaten anzeigen lassen, also schließen Sie sich 'users' an. Endlich wollen Sie Bewertungen, die zu Laden und Nutzer passen, falls verfügbar, also "Rating". Gruppieren Sie nach review.id, um eine Ergebniszeile pro Review zu erhalten. –