我有2个表,一个是供应商,一个是supplier_feedback - 如何计算每个供应商的平均评级?我目前有这个:
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
但是我得到了非常奇怪的结果,这肯定是不正确的。
supplier_feedback表将有许多记录,但第一条记录必须因各种原因打折。
答案 0 :(得分: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
子查询计算平均评分,不包括feedback_id最低的行。
答案 1 :(得分: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