LEFT OUTER JOIN SUM удваивает проблему

Таблица: Покупки

shop_id shop_name shop_time 1 Brian 40 2 Brian 31 3 Tom 20 4 Brian 30 

Таблица: бананы

 banana_id banana_amount banana_person 1 1 Brian 2 1 Brian 

Теперь я хочу, чтобы он печатал:

Имя: Том | Время: 20 | Бананы: 0
Имя: Брайан | Время: 101 | Бананы: 2

Я использовал этот код:

 $result = dbquery("SELECT tz.*, tt.*, SUM(shop_time) as shoptime, count(banana_amount) as bananas FROM shopping tt LEFT OUTER JOIN bananas tz ON tt.shop_name=tz.banana_person GROUP by banana_person LIMIT 40 "); while ($data5 = dbarray($result)) { echo 'Name: '.$data5["shop_name"].' | Time: '.$data5["shoptime"].' | Bananas: '.$data5["bananas"].'<br>'; } 

Проблема в том, что я получаю это вместо этого:

Имя: Том | Время: 20 | Бананы: 0
Имя: Брайан | Время: 202 | Бананы: 6

Я просто не знаю, как обойти это.

Использование * – проблема (поскольку вы используете группу по). Кроме того, SUM (shop_time) умножается на столько строк в banaanas, поэтому вы получаете 202 (для двух рядов в бананах)

Попробуйте этот запрос:

 SELECT tt.shop_name, SUM(shop_time) AS shoptime, Ifnull(banana_amount, 0) AS bananas FROM shop tt LEFT OUTER JOIN (SELECT banana_person, SUM(banana_amount) AS banana_amount FROM bananas GROUP BY banana_person) tz ON tt.shop_name = tz.banana_person GROUP BY shop_name; 

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

 SELECT shop_name, shoptime, IFNULL(SUM(banana_amount), 0) FROM ( SELECT shop_name, SUM(shop_time) as shoptime FROM shopping GROUP BY shop_name ) tt LEFT JOIN bananas tz ON tt.shop_name=tz.banana_person GROUP BY shop_name 
 select xx.shop_name , xx.tot_time , coalesce(yy.tot_bananas, 0) as tot_bananas from ( select shop_name , sum(shop_time) as tot_time from shopping group by shop_name ) as xx left join ( select banana_person , sum(banana_amount) as tot_bananas from bananas group by banana_amount ) as yy on xx.shop_name = yy.banana_person order by xx.shop_name ;