2017-12-22 7 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 

이 제대로 작동하지 않습니다 : 난 항상 하나의 행을 얻을 합계가 올바르지 않습니다. 그러나이 중첩 된 부분 중 하나를 제거하면 예상대로 작동하기 시작합니다. 내가 도대체 ​​뭘 잘못하고있는 겁니까?

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 또는 win)이 '거래'테이블에 있습니까? 즉, 거래가 베팅인지 아니면 둘 다인지 또는 둘 다인지 알아보기 위해'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 

편집 :

적절한 ANSI 조인 구문으로 바꿨습니다. 또한 외부 조인과 CTE. 제안에 대해 @ThorstenKettner에게 감사합니다.

+0

'u.username by group by'를 제거한 다음 'u.username, u.balance, ...'를 선택하십시오. 아무 것도하지 않는 의사 집단입니다. 가독성을 위해'bet_sum'을'bt.bet_sum'으로,'win_sum'을'wt.win_sum'으로 한정하십시오. 그리고 같은 이유로 적절한 ANSI 조인으로 전환하십시오 .. –

+0

안녕하십니까, @ThorstenKettner가 완료되었습니다. 제안에 대해 고마워. – danihp