3


0

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"].'
';


}

問題は、代わりにこれを取得することです:

名前:トム|時間:20 |バナナ:0 +名前:ブライアン|時間:202 |バナナ:6

これを回避する方法がわかりません。

3 Answer


3


問題は、2つのテーブルの外積を作成して、結果に反対側のテーブルの行数を乗算することです。 これを解決するには、最初に派生テーブルのテーブルの1つを集計した結果を計算し、この集計結果を他のテーブルに結合します。

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


1


*を使用することが問題です(group byを使用しているため)。 また、SUM(shop_time)はbanaanasの行と乗算されているため、202(bananasの2行)を取得しています。

このクエリを試してください。

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;


1


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
;