mysql - 在 MySQL 5.7 中使用日期条件模拟 row_number
问题描述
我在 MySQL 5.7.34 中工作,我有以下内容:
create table employees (
employee_id int not null auto_increment,
first_name varchar(100) not null,
last_name varchar(100) not null,
primary key (employee_id)
);
create table documents (
document_id int not null auto_increment,
title varchar(100) not null,
last_modified datetime not null,
employee_id int not null,
primary key (document_id),
foreign key (employee_id) references employees(employee_id)
);
我在这里创建了一个 db-fiddle。小提琴中显示的列只是少数,但在真实的数据集中,documents
表格将有 20 列或更多列,并且都需要显示。
SQL查询:
-- simply query
select e.employee_id,
e.first_name,
e.last_name,
d.title
from employees e
inner join documents d on e.employee_id = d.employee_id;
电流输出:
员工ID | 名 | 姓 | 标题 |
---|---|---|---|
1 | 约翰 | 能源部 | JD_Doc_Updated |
1 | 约翰 | 能源部 | JD_Doc |
2 | 麦克风 | 安德森 | MA_Doc |
期望的输出:
对于每个员工,我只想获取最新的文档。在 MS SQL Server(和最新版本的 MySQL)中,我可以使用类似ROW_NUMBER() OVER(PARTITION BY d.employee_id ORDER BY d.last_modified DESC) AS num
员工ID | 名 | 姓 | 标题 |
---|---|---|---|
1 | 约翰 | 能源部 | JD_Doc_Updated |
2 | 麦克风 | 安德森 | MA_Doc |
我不确定如何在这里实现相同的目标。
我读过这个问题,我认为这里的问题不一样,其他问题处理同一张表上的数据,而不是datetime
作为数据类型处理。除非我错过了什么?
解决方案
您正在使用不具有窗口功能的旧 MySQL 版本。因此,要获取每个员工的最新文档,您需要两个步骤:
- 获取最大文档 ID 或日期
- 获取属于该 ID 或日期的行
假设“最新文档”指的是最后修改的文档:
select *
from employees e
join documents d
on d.employee_id = e.employee_id
and (d.employee_id, d.last_modified) in
(
select employee_id, max(last_modified)
from documents
group by employee_id
)
order by e.employee_id;
该IN
子句确保加入的文档在最新文档集中。还有其他几种写法。您可以将该IN
子句替换为相关子句以引用员工的 ID。或者,您可以加入表格并拥有NOT EXISTS
一个较新文档的标准。或者你可以升级到 MySQL 8 :-)
推荐阅读
- php - 从数组中删除重复键?
- python - 如何使用 Python 导入(.tex 文件),创建一个新的(.tex 文件)并从导入的(.tex 文件)追加新的(.tex 文件)
- r - R问题:如何计算多列的平均值并选择要保存在数据集中的变量
- java - 教我为什么此代码无法检查我的输入是否为 int,以及如何修复它
- mysql - 将 SQL 查询转换为具有多个表的 sequelize 查询
- go - 如果数组作为 &val 传入,然后转换为 interface{},则更新数组元素
- c# - 应用程序中 WM_TOUCH 和 WM_GESTURE 的 TUIO 触摸事件
- c# - 如何使用 autofac 通过字符串解析具有 3rd 方通用接口的类
- c# - C# 将对象转换为图像
- audio-streaming - 使用 NAudio 和 Vorbis 直播音频文件