如何让SQL查询返回与min(duration)匹配的对应ID?
解决SQL中返回对应最小Duration的ID问题
你的问题很典型——当你用GROUP BY分组后,min(ID)和min(duration)是分别计算每组里的最小ID和最小Duration,这俩值并不一定来自同一条记录,所以才会出现ID和最小Duration不匹配的情况。下面给你两种常用的解决思路:
方法一:使用窗口函数(推荐,SQL Server 2008及以上支持)
用ROW_NUMBER()窗口函数,按ServiceName和MethodName分组,再按duration升序排序,每个组里排第一的记录就是Duration最小的那条,同时能拿到对应的ID:
WITH RankedLogs AS ( SELECT ServiceName, MethodName, duration, ID, COUNT(*) OVER (PARTITION BY ServiceName, MethodName) AS count, ROW_NUMBER() OVER (PARTITION BY ServiceName, MethodName ORDER BY duration ASC, ID ASC) AS rn FROM dbo.log ) SELECT ServiceName, MethodName, duration, ID, count FROM RankedLogs WHERE rn = 1;
这里ORDER BY duration ASC, ID ASC是为了如果同一组里有多个记录Duration相同,会取ID最小的那条;如果想要返回所有Duration最小的记录,可以把ROW_NUMBER()换成RANK()或者DENSE_RANK()。
方法二:子查询关联
先通过子查询找到每个ServiceName+MethodName组合的最小Duration和记录数,再关联原表找到对应的ID:
SELECT l.ServiceName, l.MethodName, l.duration, l.ID, g.count FROM dbo.log l INNER JOIN ( SELECT ServiceName, MethodName, MIN(duration) AS min_duration, COUNT(*) AS count FROM dbo.log GROUP BY ServiceName, MethodName ) g ON l.ServiceName = g.ServiceName AND l.MethodName = g.MethodName AND l.duration = g.min_duration;
这个方法会返回所有Duration等于组内最小值的记录,如果同一组有多个这样的记录,都会被列出来。如果只想要其中一条,可以加上TOP 1 WITH TIES或者再嵌套一层取最小ID。
内容的提问来源于stack exchange,提问作者JDBA
相关产品推荐
相关产品推荐

