牛逼SQL - 机锋更换相关子查询

问题描述 投票:6回答:3

我当前正在使用相关子查询返回结果的查询,但我想这个问题可以用ROW_NUMBER来解决更雄辩也许()。

问题是围绕着价值V的配置文件,通过数年的一个项目。每个项目都有了多个版本,每个都有自己的配置文件时的版本介绍和数据目前看起来像这样whick开始:

    
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。

提前致谢

sql sql-server-2005
3个回答
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

0
投票

我想,你如何做到这一点也没关系。你可以检查是否有关于项目Id和年复合指数。

你可以检查查询计划中看到该查询的影响。

如果有一个“项目”表中您的数据库,你可以尝试另一种方法。插入表中列ItemVersionId并确保您更新该值时新版本将被保存。然后在你的查询中使用项目Id和ItemVersionId而不是使用子查询加盟项目表。


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

此外,您还可以改变的子查询也GROUP BY和返回项目ID,这样就可以对多个项目在同一时间,如果你需要为你的应用程序的其他部分返回数据。只是一定要然后添加条目标识号来连接标准。

© www.soinside.com 2019 - 2024. All rights reserved.