SQL嵌套请求

时间:2017-12-22 11:01:37

标签: sql postgresql

我有3个表格:

  1. transaction - 有关用户余额变化的一般信息。 primary key : transaction_id
  2. bet_transactions - 有关投注的特殊信息,foreign key : transaction_id
  3. win_transaction - 与bet_transactions相同,但包含wins
  4. 我想得到所有赌注和胜利的总和。 我想出了这个:

    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
    

1 个答案:

答案 0 :(得分:2)

将聚合函数和分组移动到嵌套的子查询,如下所示:

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

CTE更具可读性:

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关于建议。