2016-04-07 5 views
0

Ich habe eine Haupttabelle „Restaurants“ und eine Eins-zu-viele-Beziehung zu einem „RestaurantVotes“ -Tabelle. Ein Restaurant kann mehrere Stimmen haben. Es ist wie folgt definiert:SQL-Statement zum Zählen und Berechnen relationale Daten

CREATE TABLE `restaurant_votes` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `created_at` datetime NOT NULL, 
    `user_id` varchar(255) COLLATE utf8_unicode_ci NOT NULL, 
    `cat_food` int(11) NOT NULL, 
    `cat_cart` int(11) NOT NULL, 
    `cat_ambassador` int(11) NOT NULL, 
    `cat_drinks` int(11) NOT NULL, 
    `cat_service` int(11) NOT NULL, 
    `cat_ambience` int(11) NOT NULL, 
    `cat_price` int(11) NOT NULL, 
    `restaurant_id` int(11) DEFAULT NULL, 
    PRIMARY KEY (`id`), 
    KEY `IDX_1B96C91EB1E7706E` (`restaurant_id`), 
    CONSTRAINT `FK_1B96C91EB1E7706E` FOREIGN KEY (`restaurant_id`) REFERENCES `restaurants` (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 

CREATE TABLE `restaurants` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `created_at` datetime NOT NULL, 
    `updated_at` datetime NOT NULL, 
    `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 

Für einen API-Aufruf wir alle Restaurants mit Namen und die Gesamtbewertung für dieses Restaurant als JSON-Antwort erhalten müssen. Name etc. ist kein Problem, aber wir haben große Probleme eine SQL-Abfrage zu finden, die die Bewertung für jedes Restaurant bekommt. Die Bewertung wird wie folgt berechnet:

  1. Die Werte (Integer 1-5) aller Kategorien (cat_ *) summieren und durch die Anzahl der Kategorien (7) dividieren.
  2. das Ergebnis der Bewertungen summerize oben und den Wert durch die Anzahl der Bewertungen in der restaurant_votes Tabelle pro Restaurant teilen.
  3. die Gesamtwertung Rückkehr von 2. in der SQL-Abfrage zusammen mit dem Namen des Restaurants.

Ist dies überhaupt möglich SQL verwenden? Irgendein Rat? Vielen Dank!

+0

Nun, was haben Sie versucht? – OldProgrammer

+0

Müssen Sie es in einer einzigen Aussage haben? Welche Skriptsprache verwenden Sie, um den JSON zu erstellen, oder gibt Ihr SQL-Server JSON-Antworten direkt an? – LuvnJesus

+0

Nichts in Raw SQL. Wir verwenden das Symfony2-Framework für unsere Webapp und haben den mitgelieferten QueryBuilder verwendet. Auf eine benutzerdefinierte Eigenschaft zur Berechnung der Bewertung im QueryBuilder können wir jedoch nicht zugreifen. Der Datensatz besteht aus ~ 5000 Einträgen, daher müssen wir aufgrund von Leistungsproblemen viele Felder aus der Restauranttabelle ausschließen (ich habe die meisten Felder in der obigen Tabelle entfernt). Und das ist der Grund, warum wir nicht nur fertige Funktionen wie findAll verwenden können() usw. – Tronic

Antwort

1
select 
r.name, 
sum(rv.cat_food + 
    rv.cat_cart + 
    rv.cat_ambassador + 
    rv.cat_drinks + 
    rv.cat_service + 
    rv.cat_ambience + 
    rv.cat_price)/7 as total_score, 
sum(rv.cat_food + 
    rv.cat_cart + 
    rv.cat_ambassador + 
    rv.cat_drinks + 
    rv.cat_service + 
    rv.cat_ambience + 
    rv.cat_price)/7/count(rv.id) as average_score 
from restaurants r 
left join restaurant_votes rv 
    on r.id = rv.restaurant_id 
group by r.name 

ich SQLFiddle dies zu demonstrieren gepostet habe.

+0

DANKE. funktioniert wie erwartet! – Tronic

1
SELECT r.name,r.id,score.rating 
FROM 
restaurants as r 
INNER JOIN 
(
SELECT restaurant_id,AVG(cat_food + cat_cart + cat_ambassador + cat_drinks + cat_service + cat_ambience + cat_price)/7 AS rating 
FROM restaurant_votes 
GROUP BY restaurant_id 
)as score 
ON r.id = score.rating 

Würde das funktionieren? Es wird alle Restaurants in der Restaurant-Tabelle definiert und und erhält den Durchschnitt aller Spalten addiert und dividiert durch 7.

+0

Wählen Sie die andere Lösung. Vielen Dank. Aber Sie bekommen eine Stimme dafür, darüber nachzudenken. – Tronic