我有一个当前正在使用相关子查询返回结果的查询,但我认为可以使用ROW_NUMBER()更有说服力地解决问题。
问题出在价值v的概况上,通过项目的年数。每个项目都有许多版本,每个版本都有自己的配置文件,当引入版本并且数据当前如下所示时启动:
ItemId ItemVersionId Year Value =========================================== 1 1 01 0.1 1 1 02 0.1 1 1 03 0.2 1 1 04 0.2 1 1 05 0.2 1 1 06 0.3 1 1 07 0.3 1 1 08 0.4 1 2 04 0.3 1 2 05 0.3 1 2 06 0.3 1 2 07 0.4 1 2 08 0.5 1 3 07 0.6 1 3 08 0.7 2 1 01 0.1 2 1 01 0.1 2 1 01 0.2 etc
我想使用适用的最新版本返回项目的完整个人资料。对于第1项的上述示例:
ItemId ItemVersionId Year Value =========================================== 1 1 01 0.1 1 1 02 0.1 1 1 03 0.2 1 2 04 0.3 1 2 05 0.3 1 2 06 0.3 1 3 07 0.6 1 3 08 0.7
我目前正在使用
SELECT ItemId, ItemVersionId, Year, Value
FROM table t
WHERE
ItemId = 1
AND ItemVersionId = (SELECT MAX(ItemVersionId) FROM table WHERE ItemId = t.ItemId AND Year = t.Year)
虽然这会返回正确的我怀疑有一种更有效的方法,特别是当表变大时。
我正在使用SQL Server 2005。
提前致谢
答案 0 :(得分:5)
我会用CTE来做这件事:
WITH Result AS
(
SELECT Row_Number() OVER (PARTITION BY ItemId, Year
ORDER BY ItemversionId DESC) AS RowNumber
,ItemId
,ItemversionId
,Year
,Value
FROM table
)
SELECT ItemId
,ItemversionId
,Year
,Value
FROM Result
WHERE RowNumber = 1
ORDER BY ItemId, Year
答案 1 :(得分:0)
我认为你可以这样做。您可以检查ItemId和Year 上是否存在综合索引。
您可以检查查询计划以查看该查询的影响。
如果数据库中有“Item”表,您可以尝试其他方法。 在该表中插入列ItemVersionId ,并确保在保存新版本时更新该值。然后在您的查询中使用ItemId和ItemVersionId 加入Item表,而不是使用该子查询。
答案 2 :(得分:0)
这应该可行,但您必须使用自己的数据测试性能:
SELECT
T1.ItemID,
T1.ItemVersionID,
T1.Year,
T1.Value
FROM
MyTable T1
INNER JOIN (SELECT Year, MAX(ItemVersionID) AS MaxItemVersionID FROM MyTable T2 WHERE T2.ItemID = 1 GROUP BY Year) SQ ON
SQ.Year = T1.Year AND
SQ.MaxItemVersionID = T1.ItemVersionID
WHERE
T1.ItemID = 1
此外,您还可以将子查询更改为分组依据并返回ItemID,以便在需要应用程序的其他部分时,可以一次返回多个项目的数据。请务必将ItemID添加到连接条件中。