首页 > 解决方案 > 如何选择最大日期早于某个值的行

问题描述

我有Microsoft SQL Server 2008和一个包含如下数据的表:

id | file_date [datatime] | file_path [varchar(255)]
____________________________________________________
1  |  01-01-1999          |   C:\f1.txt
2  |  01-01-2020          |   C:\f2.txt
3  |  05-05-1999          |   C:\f3.txt
4  |  05-05-2020          |   C:\f3.txt
5  |  05-05-1999          |   C:\f4.txt
6  |  06-05-1999          |   C:\f4.txt

我需要选择所有file_paths,其中file_date是旧的,并且此file_path与较新的file_date不存在其他行

例如,如果我必须获取日期早于 2019 年的行,我的结果应该是这样的:

file_path
C:\f1.txt
C:\f4.txt

我有一个解决方案:

SELECT rslt.file_path
FROM mytable rslt
GROUP BY rslt.file_path
HAVING MAX(rslt.file_date) < '2019-01-01'

问题是这个脚本需要大约 2 分钟才能在表中返回大约 62k 行,其中我有 4460 万行,而简单的脚本来获取所有早于日期的行(见下文)需要 2-3 秒

SELECT * FROM mytable WHERE file_date < '2019-01-01'

那么,有什么方法可以优化我的解决方案吗?

标签: sqlsql-serversql-server-2008

解决方案


DECLARE @TargetDate     date    =   '01-01-2019'
DECLARE     @PathList   TABLE   (id int, file_date datetime, file_path varchar(255))
INSERT INTO @PathList   VALUES
            (1, '01-01-1999', 'C:\f1.txt')
        ,   (2, '01-01-2020', 'C:\f2.txt')
        ,   (3, '05-05-1999', 'C:\f3.txt')
        ,   (4, '05-05-2020', 'C:\f3.txt')
        ,   (5, '05-05-1999', 'C:\f4.txt')
        ,   (6, '06-05-1999', 'C:\f4.txt')
;

SELECT  DISTINCT
        PL.file_path
FROM            @PathList   PL                                        
    LEFT JOIN   @PathList   PH  ON  PH.file_path =  PL.file_path    
                                AND PH.file_date >= @TargetDate 
WHERE   
            PL.file_date    <   @TargetDate 
        AND PH.id           IS  NULL

推荐阅读