我有3张桌子:
transaction
- 关于用户余额变化的一般信息。 primary key : transaction_id
。bet_transactions
- 有关投注的特殊信息,foreign key : transaction_id
。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关于建议。