SQL嵌套请求

标签 sql postgresql

我有 3 个表格:

  1. transaction - 关于用户余额变化的一般信息。 主键:transaction_id
  2. bet_transactions - 关于投注的特殊信息,外键: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

最佳答案

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

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

已编辑:

我切换到正确的 ANSI 连接语法,也切换到外部连接和 CTE。谢谢@ThorstenKettner关于建议。

关于SQL嵌套请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47940405/

相关文章:

sql - 尝试正确插入数据

mysql - 在 BigQuery 中查询表

mysql - 在mysql中剪切文本

ruby-on-rails - 通过关系在 has_many 上使用关联值来过滤事件管理中的表(Rails 4/事件管理)

c# - Postgres : ArgumentException for bit_string(1) column in datatable

php - mysql在多个表中检索数据

mysql - 如何找到每个组的 MIN 值并选择整行?

django - 我如何从 postgresql View 表中获取对象列表来显示

sql - 如何在选择查询中比较多列与多字段数组?

java - 如何使用 JPA 实体构建和填充数据库?