Question

I'm trying to get the rates from anonymous people plus the ones who are registered. They are in different tables.

SELECT product.id, (SUM( users.rate + anonymous.rate ) / COUNT( users.rate + anonymous.rate ))
FROM products AS product
LEFT JOIN users ON users.id_product = product.id
LEFT JOIN anonymous ON anonymous.id_product = product.id
GROUP BY product.id
ORDER BY product.date DESC 

So, the tables are like the following:

users-->
id | rate | id_product | id_user
1     2        2           1
2     4        1           1
3     5        2           2

anonymous-->
id | rate | id_product | ip
1     2        2          192..etc
2     4        1          198..etc
3     5        2          201..etc

What I'm trying with my query is: for each product, I would like to have the average of rates. Currently the output is null, but I have values in both tables.

Thanks.

Was it helpful?

Solution

Try like this..

SELECT product.id, (SUM( ifnull(ur.rate,0) + ifnull(ar.rate,0) ) / (COUNT(ur.rate)+Count(ar.rate)))
FROM products AS product
LEFT JOIN users_rate AS ur ON ur.id_product = product.id
LEFT JOIN anonymous_rate AS ar ON ar.id_product = product.id
GROUP BY product.id 

Sql Fiddle Demo

OTHER TIPS

First, you are getting a cross join for each product within the table. This is not what you really want. I think this is close to what you are looking for

SELECT p.id,
       (coalesce(u.sumrate, 0) + coalesce(a.sumrate, 0)) / coalesce(u.num, 0) + coalesce(a.num, 0))
FROM products p LEFT JOIN
     (select id_product, sum(rate) as sumrate, count(*) as num
      from users u
      group by id_product
     ) u
     ON u.id_product = p.id left join
     (select id_product, sum(rate) as sumrate, count(*) as num
      from anonymous a
      group by id_product
     ) a
     ON a.id_product = p.id
ORDER BY p.date DESC;

Assuming that id is unique in the product table, you don't need an aggregation at the outer level.

You cannot use count and sum on joins if you group by

CREATE TABLE products (id integer);
CREATE TABLE users_rate (id integer, id_product integer, rate integer, id_user integer);
CREATE TABLE anonymous_rate (id integer, id_product integer, rate integer, ip varchar(25));

INSERT INTO products VALUES (1);
INSERT INTO products VALUES (2);
INSERT INTO products VALUES (3);
INSERT INTO products VALUES (4);

INSERT INTO users_rate VALUES(1, 1, 3, 1);
INSERT INTO users_rate VALUES(1, 2, 3, 1);
INSERT INTO users_rate VALUES(1, 3, 3, 1);
INSERT INTO users_rate VALUES(1, 4, 3, 1);

INSERT INTO anonymous_rate VALUES(1, 1, 3, '192..');
INSERT INTO anonymous_rate VALUES(1, 2, 3, '192..');

select p.id,
ifnull(
  ( ifnull( ( select sum( rate ) from users_rate where id_product = p.id ), 0 ) +
    ifnull( ( select sum( rate ) from anonymous_rate where id_product = p.id ), 0 ) )
  /
  ( ifnull( ( select count( rate ) from users_rate where id_product = p.id ), 0 ) +
    ifnull( ( select count( rate ) from anonymous_rate where id_product = p.id ), 0 )), 0   )
from products as p
group by p.id

http://sqlfiddle.com/#!2/a2add/8

I've check on sqlfiddle. When there are no rates 0 is given. You may change that.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top