2009-11-19 4 views
3

У меня есть 2 стола, один из них - поставщик, а другой - поставщик_feedback - как я могу рассчитать средний рейтинг для каждого поставщика? В настоящее время у меня есть это:Среднее значение из другого таблицы MySQL

SELECT s.premium, s.supplier_id, s.name, s.phone, s.website, 
    s.price_low, s.price_high, s.address1, s.address2, s.town, 
    s.county, s.postcode, 
    (SUM(f.rating)/(COUNT(f.rating) -1)) AS rate, 
    GROUP_CONCAT(REPLACE(t.name, ' ', ',') SEPARATOR ',') AS tags 
FROM suppliers AS s 
JOIN suppliers_to_tags AS st ON st.supplier_id = s.supplier_id 
JOIN supplier_tags AS t ON t.tag_id = st.tag_id 
JOIN supplier_feedback AS f ON s.supplier_id = f.supplier_id 
GROUP BY s.supplier_id 
HAVING tags LIKE '%HI%' 
ORDER BY s.premium DESC 
LIMIT 0 , 30 

Но я получаю очень странные результаты, которые определенно неверны.

Таблица поставщика_feedback будет иметь много записей, но первая запись должна быть дисконтирована по разным причинам.

+0

Вы используете функцию AVG? http://www.w3schools.com/SQL/sql_func_avg.asp – Adrian

+0

Вы хотите, чтобы первая запись таблицы поставщика_feedback для каждого поставщика игнорировалась или только первая запись в таблице? – Chris

ответ

0

использовать подзапрос, чтобы упростить процедуру, таким образом вы можете протестировать подзапрос для правильной настройки всех подключений к другим таблицам.

(SELECT supplier_id, AVG(rating) AS avg_rating 
FROM supplier_feedback WHERE feedback_id != x GROUP BY supplier_id) 

Предполагая, что feedback_id (независимо от первичного ключа для таблицы обратной связи есть) неизменна вы можете исключить запись, которую нужно игнорировать из подзапроса, остальные будут усреднены.

Вы можете присоединиться с этим:

SELECT s.*, r.avg_rating 
    FROM suppliers s 
    JOIN 
    (SELECT supplier_id, AVG(rating) AS avg_rating 
    FROM supplier_feedback WHERE feedback_id != x GROUP BY supplier_id) r 
    ON s.supplier_id = r.supplier_id 
1

Джойн на теге вызывает строки из обратной связи появляться несколько раз. Это приводит к тому, что среднее значение отклоняется. Вы можете переписать часть FROM с подзапросом как для тегов, так и для среднего. Это гарантирует, что их расчеты не мешают:

SELECT 
    <other columns> 
, feedback.rating 
, suptags.tags 
FROM suppliers AS s 
JOIN (
    SELECT 
     st.supplier_id 
    , GROUP_CONCAT(REPLACE(t.name, ' ', ',') SEPARATOR ',') AS tags 
    FROM suppliers_to_tags AS st 
    JOIN supplier_tags AS t ON t.tag_id = st.tag_id 
    GROUP BY st.supplier_id 
) as suptags ON suptags.supplier_id = s.supplier_id 
JOIN (
    SELECT 
     fb1.supplier_id 
    , AVG(fb1.rating) as rating 
    FROM supplier_feedback fb1 
    WHERE fb1.feedback_id NOT IN (
     SELECT min(fb2.feedback_id) 
     FROM supplier_feedback fb2 
     WHERE fb2.supplier_id = fb1.supplier_id 
    ) 
    GROUP BY fb1.supplier_id 
) feedback ON s.supplier_id = feedback.supplier_id 

suptags подзапрос добавляет все теги за поставщика в строку. Подзапрос feedback вычисляет средний рейтинг, исключая строку с наименьшей обратной связью.

Смежные вопросы