Read average value from another MySQL table

I have 2 tables, one is a supplier and one is a feedback provider - how can I calculate the 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 that are definitely wrong.

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

+3
source share
2 answers

The join on tag causes rows from feedback to appear several times. This causes the average to deviate. You can rewrite the FROM part with a subquery for both tags and medium. This ensures that their calculations do not 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

suptags . feedback , .

+1

, , .

(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
0

Source: https://habr.com/ru/post/1723329/


All Articles