gpt4 book ai didi

mysql - 如何让我的 GROUP BY 获取特定列的最后一行(按日期)的值?

转载 作者:行者123 更新时间:2023-11-29 02:48:03 26 4
gpt4 key购买 nike

我有一个包含 GROUP BY 子句的查询。此查询从 records 表中获取员工“签到”时间,如果 dn 字段为 1,则员工在办公室,但是如果是2,那么他/她就离开了。

假设我将 records.dn 放在 GROUP BY 子句中。这导致每个员工都有重复的条目(我在表格中一个接一个地得到他们的名字,两次)。

我尝试在选择中使用 MIN 和 MAX,但这根本没有意义。

因此,从数据库中员工可能多次 checkin 和 checkout 的多行中,我如何获取最新行并使用其 dn 字段?

这是我正在谈论的查询:

select 
MAX(records.dn),
`records`.`din`,
`users`.`username`,
`users`.`id` as `user_id`,
DATE(records.created_at) AS date,
TIME(MIN(records.created_at)) AS first_log,
TIME(MAX(records.created_at)) AS last_log
from `records`
inner join `users` on `records`.`din` = `users`.`din`
where records.created_at BETWEEN '2016-09-05 00:00:00'
AND '2016-09-08 00:00:00'
group by `users`.`username`, DATE(records.created_at)
order by `first_log` asc

(第一个选择列是我尝试做的,使用 MAX)

这是带有一些示例数据的记录表:

the table

我如何实现我正在寻找的东西?

最佳答案

substring_index()/group_concat() 技巧可能完全符合您的要求:

select substring_index(group_concat(r.dn order by created_at desc), ',', 1) as last_dn, 
u.username, u.id as `user_id`,
DATE(r.created_at) AS date,
TIME(MIN(r.created_at)) AS first_log,
TIME(MAX(r.created_at)) AS last_log
from records r inner join
users u
on r.din = u.din
where r.created_at >= '2016-09-05' and
r.created_at < '2016-09-08'
group by u.username, DATE(r.created_at)
order by first_log asc;

如所写,这具有三个限制:

  1. 假定 dn 中没有逗号(使用不同的分隔符可以轻松修复)。
  2. 假定用户一天的 dn 列表不会超过 group_concat() 的最大字符串长度。这也可以使用系统参数进行调整。
  3. last_dn 是一个字符串,即使它不是原始类型也是如此。

但这个技巧在大多数情况下都很有效。参数 group_concat_max_len 是中间字符串的大小。它的默认值(此处为 described)为 1,024。对于多达一百个或更多的整数,这应该没问题。它是一个 session 参数,很容易更改。

另请注意以下更改:

  • 我认为查询中不必要的反引号只会让它更难阅读。
  • 使用表别名使查询更易于编写和阅读。
  • 我不认为你的意思是 between,因为它是包容性的。我猜您希望日期/时间值严格在 8 号之前。

关于mysql - 如何让我的 GROUP BY 获取特定列的最后一行(按日期)的值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39427044/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com