如何查询所有设备及其最后一位借阅用户(无借阅则留空)
解决设备最后借阅用户查询的方案
这个问题我之前也碰到过,核心是要先锁定每个设备的最后一次借阅记录,而不是直接把所有借阅记录都关联上来,这样就不会出现行数膨胀的问题了。给你两种常用的标准SQL解决方案,大部分主流数据库(MySQL、PostgreSQL、SQL Server等)都支持:
方法一:用窗口函数ROW_NUMBER()(推荐,逻辑更清晰)
通过窗口函数给每个设备的借阅记录按日期倒序编号,每个设备里编号为1的记录就是最新的借阅记录,再关联设备表和用户表即可。
WITH LatestLoans AS ( SELECT equipmentId, userId, -- 按设备分组,借阅日期倒序排序,给每条记录编号 ROW_NUMBER() OVER (PARTITION BY equipmentId ORDER BY date DESC) AS rn FROM Loans ) SELECT e.id AS equipment_id, e.description, -- 无借阅记录时自动返回NULL(空值) u.name AS last_borrower_name FROM Equipments e -- 左连接确保所有设备都被返回,只取每个设备的最新借阅记录(rn=1) LEFT JOIN LatestLoans ll ON e.id = ll.equipmentId AND ll.rn = 1 -- 左连接用户表,获取借阅人姓名 LEFT JOIN Users u ON ll.userId = u.id;
方法二:用子查询筛选最大借阅日期
先找出每个设备的最后借阅日期,再匹配对应的借阅记录,最后关联用户表。如果存在同一设备同一天多次借阅的情况,可以额外加条件取最新的那条(比如按借阅记录ID最大)。
SELECT e.id AS equipment_id, e.description, u.name AS last_borrower_name FROM Equipments e LEFT JOIN ( SELECT equipmentId, userId, date FROM Loans l -- 匹配每个设备的最大借阅日期 WHERE (l.equipmentId, l.date) IN ( SELECT equipmentId, MAX(date) FROM Loans GROUP BY equipmentId ) -- 可选:如果同一天有多个借阅记录,取ID最大的那条(确保唯一) AND l.id = (SELECT MAX(id) FROM Loans WHERE equipmentId = l.equipmentId AND date = l.date) ) latest_l ON e.id = latest_l.equipmentId LEFT JOIN Users u ON latest_l.userId = u.id;
为啥直接关联会行数变多?
你之前遇到的问题,是因为直接把Equipments和Loans左连接时,每个设备有多少条借阅记录就会返回多少行。而我们的需求是每个设备只返回一行,所以必须先过滤出每个设备的最后一次借阅记录,再做关联,这样就能保证结果行数和设备表一致了。
内容的提问来源于stack exchange,提问作者juliano.net
相关产品推荐
相关产品推荐

