查找第一行结果

时间:2010-11-10 08:58:57

标签: sql-server tsql

我有一个历史表,其中包含每次更改记录时的快照。我正在尝试使用原始捕获日期返回某个历史记录行。我目前正在使用此功能:

select
    s.Description,
    h.CaptureDate OriginalCaptureDate
from
    HistoryStock s
    left join 
        ( select 
              StockId,
              CaptureDate
          from
              HistoryStock
          where
              HistoryStockId in ( select MIN(HistoryStockId) from HistoryStock group by StockId )
        ) h on s.StockId = h.StockId
where
    s.HistoryStockId = @HistoryStockId

这样可行,但有一百万条记录在缓慢的一面,我不知道如何优化这个查询。

如何优化此查询?

更新

WITH OriginalStock (StockId, HistoryStockId)
AS  (
    SELECT  StockId, min(HistoryStockId)
    from HistoryStock group by StockId
    ),
OriginalCaptureDate (StockId, OriginalCaptureDate) 
As (
   SELECT h.StockId, h.CaptureDate
   from HistoryStock h join OriginalStock o on h.HistoryStockId = o.HistoryStockId
  )

select
    s.Description,
    h.OriginalCaptureDate
from
    HistoryStock s left join OriginalCaptureDate h on s.StockId = h.StockId
where
    s.HistoryStockId = @HistoryStockId

我已经更新了使用CTE的代码但是我的性能并不好,只是性能提升很小。有什么想法吗?

再说一遍,我需要到达StockId历史表中的第一条记录,而不是最早的捕获日期。

2 个答案:

答案 0 :(得分:1)

我不确定我是否完全理解数据如何从您的查询中运行,但在我看来,嵌套这样的查询对于性能来说永远不会有好处。您可以尝试以下方式:

    WITH MinCaptureDate (StockID, MinCaptureDate)
AS  (
    SELECT   HS.StockID
        ,MIN(HS.CaptureDate) AS OriginalCaptureDate
    FROM    HistoryStock    HS
    GROUP BY 
         HS.Description
    )
SELECT   HS.Description
    ,MCD.OriginalCaptureDate
FROM    HistoryStock    HS
JOIN    MinCaptureDate  MCD
    ON HS.StockID = MCD.StockID
WHERE   HS.StockID = @StockID

答案 1 :(得分:0)

我想我知道你想要实现的目标。您基本上需要指定历史记录库存记录的描述,但您希望与库存的第一个历史记录关联的日期...所以,如果您的历史记录表看起来像这样

StockId   HistoryStockId   CaptureDate   Description
1         1                Apr 1         Desc 1
1         2                Apr 2         Desc 2
1         3                Apr 3         Desc 3

并指定@HistoryStockId = 2,您需要以下结果

Description   OriginalCaptureDate
Desc 2        Apr 1

我认为以下查询会为您带来稍微好一点的效果。

WITH OriginalStock (StockId, CaptureDate, RowNumber) 
AS  ( 
    SELECT  
        StockId, 
        CaptureDate,
        RowNumber = ROW_NUMBER() OVER (PARTITION BY StockId ORDER BY HistoryStockId ASC)
    from HistoryStock 
    )

select 
    s.Description, 
    h.CaptureDate 
from 
    HistoryStock s left join OriginalStock h on s.StockId = h.StockId and h.RowNumber = 1
where 
    s.HistoryStockId = @HistoryStockId