2016-04-07 5 views
0

私はメインテーブル「レストラン」と「レストラン投票」テーブルとの1対多の関係を持っています。 1つのレストランは複数の投票を持つことができます。私たちは名前とJSONレスポンスとしてこのレストランの総合評価を含むすべてのレストランを取得する必要がありますAPI呼び出しのためにリレーショナルデータを数えて計算するためのSQL文

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; 

:それは、次のように定義されています。名前などは問題ではありませんが、各レストランの評価を取得するSQLクエリを見つけるのに大きな問題があります。評価は次のように計算されます。

  1. すべてのカテゴリ(cat_ *)の値(整数1〜5)をサマライズし、カテゴリ(7)の数で除算します。
  2. 上記の評価の結果をサマライズし、その値をレストランあたりのrestaurant_votesテーブルの評価数で除算します。
  3. SQLクエリの総合評価をレストラン名とともに返します。

これはSQLでも可能ですか?何かアドバイス?ありがとう!

+0

あなたは何を試しましたか? – OldProgrammer

+0

あなたは1つのステートメントでそれを持っている必要がありますか?どのスクリプト言語を使用してJSONを作成していますか、またはJSON応答を直接提供するSQLサーバーですか? – LuvnJesus

+0

未加工SQLには何もありません。 symfony2フレームワークをWebアプリケーションに使用し、付属のQueryBuilderを使用しました。しかし、QueryBuilderで評価を計算するためのカスタムプロパティにアクセスすることはできません。データセットは〜5000エントリで構成されているため、パフォーマンス上の問題(上記のSQLのほとんどのフィールドが削除されている)のためにレストランテーブルから多くのフィールドを除外する必要があります。これは、findAll()などのレディメイド関数を使用できない理由です。 – Tronic

答えて

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 

で割っます私はこれを実証するSQLFiddleを掲載しました。

+0

ありがとうございます。期待どおりに動作します! – 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 

これは機能しますか? それはレストランのテーブルで定義されているすべてのレストランを取得し、すべての列の平均値を加算し、7

+0

他のソリューションを選択しました。ありがとう。しかし、あなたはそれについて考えて投票する。 – Tronic