mysql - 使用 MySQL 5.7 将 2 个登录/注销时间表合并为 1 个
问题描述
我有两个表,每个表都有用户名和日期时间列,一个用于登录时间,另一个用于注销。我遇到了和我一样的问题,在这个问题中描述:基于时间合并两个表,这个很好的解决方案:
select
id,
min(case when action = 'in' then dt end) login_time,
max(case when action = 'out' then dt end) logout_time
from (
select
t.*,
sum(case when action = 'in' then 1 else 0 end)
over(partition by id order by dt) grp
from (
select id, login_time dt, 'in' action from login
union all select id, logout_time, 'out' from logout
) t
) t
group by id, grp
order by id, grp
但是这个解决方案使用“OVER”子句,在 MySQL5.7 中不支持。任何人都可以帮我转换这个相同的逻辑,但在 MySQL5.7 中没有“OVER”子句和支持。
解决方案
一种方法使用变量:
select id,
min(case when action = 'in' then dt end) as login_time,
max(case when action = 'out' then dt end) as logout_time
from (select t.*,
(@grp := if(@id = id, @grp,
if(@id := id, @grp + 1, @grp + 1)
)
) as grp
from (select id, login_time as dt, 'in' as action
from login
union all
select id, logout_time, 'out'
from logout
order by 1, 2
) t cross join
(select @id := -1, @grp := -1) params
) t
group by id, grp
order by id, grp;
注意:如果id
是一个字符串,那么@id
应该初始化为''
而不是-1
。
请注意,语句中的变量赋值SELECT
在 MySQL 8+ 中已被弃用。你真的应该升级到 MySQL 8+ 并学习窗口函数。
推荐阅读
- android - Android Room 教程不建
- arrays - 如何在 Reactjs 中使用 clickHandler 和 useState 更新对象数组
- json - 如何在 Swift 中处理 json null 值?
- css - 如何使用 purescript-css 将 CSS 边距属性设置为自动?
- node.js - 如何修复“验证错误:用户验证失败:名称:需要路径‘名称’。” 蒙古错误?
- javascript - 如何通过我在 https 上托管的 reactjs-app 向我在 http 上托管的 rest-api 提出上诉来解决错误
- java - 如何以最小顺序从反馈列表中找到每个用户给出的最新反馈?
- cassandra - 在 cassandra 中禁用读取修复
- ruby-on-rails - Rails/React/Yarn:如何从应用程序的根目录运行“yarn start”
- r - 避免嵌套循环但使用 (l)apply 迭代 2 个值?