如何优化使用多个子选择语句的查询

时间:2012-03-15 23:20:28

标签: sql performance max

希望有人可以帮我解决这个问题: 我的表是:

id  Version  datetime     name     resource 
---|--------|------------|--------|--------- 
1  | 1      | 03/03/2009 | con1   | 399  
2  | 2      | 03/03/2009 | con1   | 244 
3  | 3      | 01/03/2009 | con1   | 555 
4  | 1      | 03/03/2009 | con2   | 200 
5  | 2      | 03/03/2009 | con2   | 500 
6  | 3      | 04/03/2009 | con2   | 600 
7  | 4      | 31/03/2009 | con2   | 700 

我需要选择每个具有“datetime”最大值的不同“名称”,该名称小于或等于给定日期;如果有多个记录满足第一个条件,那么版本是最大版本。

如果给定日期是'04 / 03/2009',结果将是:

id  Version  datetime     name     resource 
---|--------|------------|--------|--------- 
2  | 2      | 03/03/2009 | con1   | 244  
6  | 3      | 04/03/2009 | con2   | 600 

目前我已经创建了以下查询,但是我怀疑在大型桌面上运行时性能并不是最好的:

SELECT [id], [Version], [datetime], [name], [resource]  
FROM theTable
WHERE [Version] = 
(
SELECT MAX(Version) FROM theTable AS theTable2 WHERE theTable.[name] = theTable2.[name] 
AND  theTable2.[datetime] = 
    (
    SELECT MAX(theTable3.[datetime]) FROM theTable AS theTable3 
    WHERE theTable2.[name] = theTable3.[name] AND theTable3.[datetime] <= '04/03/2009'
    )
)

如果有人提出更有效的方法,我会很感激;如果可能的话,举一个例子: - )。

提前致谢。

1 个答案:

答案 0 :(得分:2)

您可以使用PARTITION BY。这使您基本上可以对结果进行排名。在您的实例中,您希望仅选择排名为1的结果。首先,使用无效日期时间过滤掉结果(使用WHERE),然后在分区中按列降序排序(因此,第一个结果将是一个具有最大日期时间,并且,如果是datetime tie,则也是最大版本。)

SELECT [id], [Version], [datetime], [name], [resource]
FROM
(
   SELECT [id], [Version], [datetime], [name], [resource], row_number() 
     OVER (PARTITION BY [name] ORDER BY [datetime] DESC, [Version] DESC) as groupIndex
   FROM theTable
   WHERE [datetime] <= '04/03/2009'
) AS t
WHERE groupIndex = 1