首页 > 解决方案 > 在 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作为数据类型处理。除非我错过了什么?

标签: mysqlsql

解决方案


您正在使用不具有窗口功能的旧 MySQL 版本。因此,要获取每个员工的最新文档,您需要两个步骤:

  1. 获取最大文档 ID 或日期
  2. 获取属于该 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 :-)


推荐阅读