使用同一个表中的两个MAX列优化查询

时间:2012-01-13 06:33:57

标签: sql sql-server sql-server-2008 sql-server-2005 tsql

我需要优化以下查询

 SELECT  
     Id, -- identity
     CargoID,
     [Status] AS CurrentStatus
 FROM    
     dbo.CargoStatus
 WHERE   
     id IN (SELECT TOP 1 ID
            FROM dbo.CargoStatus CS
            INNER JOIN STD.StatusMaster S ON CS.ShipStatusID = S.SatusID
            WHERE CS.CargoID=CargoStatus.CargoID
            ORDER BY YEAR([CS.DATE]) DESC, MONTH([CS.DATE]) DESC, 
                     DAY([CS.DATE]) DESC, S.StatusStageNumber DESC)

有两个表

  1. CargoStatus
  2. StatusMaster

    • Statusmaster包含StatusID, StatusName, StatusStageNumber(int)
    • CargoStatus包含ID, StatusID (FK StatusMaster StatusID column), Date
  3. 还有其他更好的方法来编写此查询。

    我想要每件货物的最新状态(每cargoID只有一个条目)。

1 个答案:

答案 0 :(得分:6)

由于您似乎使用的是SQL Server 2005或更高版本,因此可以使用具有ROW_NUMBER()窗口函数的CTE:

;WITH LatestCargo AS
(
   SELECT 
       cs.Id, -- identity
       cs.CargoID,
       cs.[Status] AS CurrentStatus
       ROW_NUMBER() OVER(PARTITION BY cs.CargoID 
                         ORDER BY cs.[Date], s.StatusStageNumber DESC) AS 'RowNum'
   FROM 
       dbo.CargoStatus cs
   INNER JOIN 
       STD.StatusMaster s ON cs.ShipStatusID = s.[StatusID]
)
SELECT 
    Id, CargoID, [Status]
FROM 
    LatestCargo 
WHERE 
    RowNum = 1

此CTE按CargoID“分区”您的数据,对于每个分区,ROW_NUMBER函数会发出序号,从1开始并按Date DESC排序 - 所以最新一行得到RowNum = 1(对于每个CargoID),这是我在后面的SELECT语句中从CTE中选择的。