要查看发生了什么,请查看不带分组依据的子查询。
select
Signups.user_id,
timeoutTable.*,
confirmedTable.*
from Signups
left join (
select * from Confirmations where action = 'timeout'
) as timeoutTable on Signups.user_id = timeoutTable.user_id
left join (
select * from Confirmations where action = 'confirmed'
) as confirmedTable on Signups.user_id = confirmedTable.user_id
timeoutTable confirmedTable
user_id user_id time_stamp action user_id time_stamp action
15 null null null null null null
16 null null null null null null
7 7 2021-03-25 07:40:25 timeout 7 2020-01-24 15:43:47 confirmed
7 7 2020-03-31 13:11:43 timeout 7 2020-01-24 15:43:47 confirmed
10 null null null null null null
5 null null null null null null
9 null null null null null null
8 8 2021-03-07 19:48:06 timeout 8 2020-07-27 19:43:25 confirmed
12 null null null null null null
请注意user_id 7有2行,每行都有一个超时
和
确认。这些行被计算为
二者都
超时和确认。这是因为您要同时连接两个表。
如果我们先进行聚合,然后再加入,计数就会计算出来。
select
Signups.user_id,
timeoutTable.*,
confirmedTable.*
from Signups
left join (
select user_id, count(user_id) as timeouts
from Confirmations
where action = 'timeout'
group by user_id
) as timeoutTable on Signups.user_id = timeoutTable.user_id
left join (
select user_id, count(user_id) as confirmations
from Confirmations
where action = 'confirmed'
group by user_id
) as confirmedTable on Signups.user_id = confirmedTable.user_id
timeoutTable confirmedTable
user_id user_id timeouts user_id confirmations
15 null null null null
16 null null null null
7 7 2 7 1
10 null null null null
5 null null null null
9 null null null null
8 8 1 8 1
12 null null null null
Demonstration
注:
left join (
select * from Confirmations where action = 'timeout'
) as timeoutTable on Signups.user_id = timeoutTable.user_id
最好写成没有子查询。
left join Confirmations as timeoutTable
on Signups.user_id = timeoutTable.user_id
and where timeoutTable.action = 'timeout'
注意:当列名与SQL关键字冲突或非常接近时,这很好地表明您的名称过于通用。例如
time_stamp
。什么时候盖章?使用更具描述性的内容,例如
created_at
或
action_at
或
confirmed_at
。
这就引出了每一行确认代表什么的问题。它们不是确认,而是确认尝试。也许该表应该称为ConfirmationAttempts,时间戳为
attempted_at
。