2017-12-22 17 views
1

は提出:SQLネストされた要求

  1. transaction - ユーザーのバランス変更に関する一般的な情報。 primary key : transaction_id
  2. bet_transactions - ベットに関する特別な情報、foreign key : transaction_id
  3. win_transaction - bet_transactionsと同じですが、winsを含みます。

すべての賭けと勝利の合計を取得します。 私はこの思い付いた:

select 
    u.username as username, 
    u.balance as balance, 
    sum(bt.amount) as bet_sum, 
    sum(wt.amount) as win_sum 
from 
    users u, 
    (
     select 
      t.* 
     from 
      transactions t, 
      bet_transactions b 
     where 
      t.transaction_id = b.transaction_id 
    ) bt, 
    (
     select 
      t.* 
     from 
      transactions t, 
      win_transactions w 
     where 
      t.transaction_id = w.transaction_id 
    ) wt 
where 
    u.username = bt.username and 
    u.username = wt.username 
group by 
    u.username 

それが正常に動作しない:私は常に一列のみを取得し、合計が正しくありません。 しかし、このようなネストされた部分の1つを削除すると、期待どおりに機能し始めます。私は間違って何をしていますか?

select 
    u.username as username, 
    u.balance as balance, 
    sum(bt.amount) as bet_sum 
from 
    users u, 
    (
     select 
      t.* 
     from 
      transactions t, 
      bet_transactions b 
     where 
      t.transaction_id = b.transaction_id 
    ) bt 
where 
    u.username = bt.username 
group by 
    u.username 
+2

これは、1980年代に使用した結合構文です。それは1992年に冗長化されました。もう使用しないでください。代わりに適切なANSI結合を使用して、エラーの発生が少なく、読み込みと保守が容易になります( 'トランザクションからt_transaction_id = b.transaction_id'にbet_transactions bに参加する)。 –

+0

金額(賭け金または勝利金額)はテーブル「取引」にありますか?これは、トランザクションが賭けか勝利か、あるいはその両方であるかを知るために 'bet_transactions'と' win_transactions'だけを調べることを意味します。 –

答えて

2

ネストされたサブクエリにすることによって移動集計関数やグループ、このような何か:CTEと

select 
    u.username as username, 
    u.balance as balance, 
    bt.bet_sum, 
    wt.win_sum 
from 
    users u 
    left outer join 
    (
     select 
      t.username, sum(b.amount) as bet_sum 
     from 
      transactions t, 
      bet_transactions b 
     where 
      t.transaction_id = b.transaction_id 
     group by 
      t.username 
    ) bt 
     on u.username = bt.username 
    left outer join 
    (
     select 
      t.username, sum(w.amount) as win_sum 
     from 
      transactions t, 
      win_transactions w 
     where 
      t.transaction_id = w.transaction_id 
     group by 
      t.username 
    ) wt 
     on u.username = wt.username 

をより読み:

WITH 
bt as 
    (
     select 
      t.username, sum(b.amount) as bet_sum 
     from 
      transactions t, 
      bet_transactions b 
     where 
      t.transaction_id = b.transaction_id 
     group by 
      t.username 
    ), 
wt as 
    (
     select 
      t.username, sum(w.amount) as win_sum 
     from 
      transactions t, 
      win_transactions w 
     where 
      t.transaction_id = w.transaction_id 
     group by 
      t.username 
    ) 
select 
    u.username as username, 
    u.balance as balance, 
    bt.bet_sum, 
    wt.win_sum 
from 
    users u 
    left outer join bt 
     on u.username = bt.username 
    left outer join wt 
     on u.username = wt.username 

EDITED:

私は適切なANSI結合構文に切り替えました。また、外部結合とCTE。ありがとうございました@ThorstenKettnerについての提案。

+0

'u.usernameでグループ化する'を削除し、 'u.username、u.balance、...'を選択するだけです。これは何もしない擬似集約です。読みやすくするために 'bet_sum'を' bt.bet_sum'と 'win_sum'を' wt.win_sum'で修飾してください。同じ理由で適切なANSIジョインに切り替えます。 –

+0

こんにちは@ThorstenKettnerが完了しました。ありがとうございました。 – danihp

関連する問題