T SQL - Eloquent替换Correlated Subquery

时间:2008-11-10 12:08:54

标签: sql sql-server-2005

我有一个当前正在使用相关子查询返回结果的查询,但我认为可以使用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。

提前致谢

3 个答案:

答案 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添加到连接条件中。