开发者

Count average from another MySQL table

开发者 https://www.devze.com 2022-12-11 17:50 出处:网络
I have 2 tables, one is supplier and one is supplier_feedback - how can I calculate th开发者_JS百科e average rating for each supplier?I currently have this:

I have 2 tables, one is supplier and one is supplier_feedback - how can I calculate th开发者_JS百科e average rating for each supplier? I currently have this:

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

But I get very strange results, which definitely aren't correct.

The supplier_feedback table will have many records, but the first record must be discounted for various reasons.


use a subquery to make things simpler, that way you can test the subquery for correctness seperately of all the joins to other tables.

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

Assuming that feedback_id (whatever the primary key for the feedback table is) is unchanging you can exclude the record you want to ignore from the subquery, the rest will be averaged.

You can then join with this:

    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


The join on tag is causing rows from feedback to appear multiple times. That causes the average to be way off. You could rewrite the FROM part with a subquery for both the tags and the average. That makes sure their calculations don't interfere:

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

The suptags subquery adds all tags per supplier to a string. The feedback subquery calculates the average rating, excluding the row with the lowest feedback_id.

0

精彩评论

暂无评论...
验证码 换一张
取 消