查询显示另一个 table 的旧值和新值 - 查询最新的 ChangeDate

Query to show old and new values from another table - query the latest ChangeDate

我在 SQL Server 2012 中有 3 个表。

Table历史是对TableA中的值所做的所有更改的历史。它可以对PRICE,LOT,INTEREST进行许多更改,但在大多数情况下该值是只改过一次。

Table一个

AID PRICE   LOT    INTEREST
------------------------
1   1500    9000   0.5
2   2500    20     1.5

Table B

BID AID
--------
11  1
22  2

Table历史

BID     ChangeField     OldValue    NewValue   ChangeDate
------------------------------------------------------------
11      PRICE           1700        1500       1/1/22
11      LOT             10000       8000       12/15/21 
11      LOT             8000        9000       2/2/22

我需要一个查询来显示 Table A 以及 Table 历史记录中的旧值和新值。如果有超过 1 个更改,则对于旧值,获取最近的先前值。在上面的示例中,Lot 最近的先前值是 2/2/22 的 8000(不是 12/15/21 的 10000)。

示例:

AID OldPRICE    NewPRICE    OldLot  NewLot  OldInterest NewInterest
----------------------------------------------------------------
1   1700        1500        8000    9000    0.5         0.5
2   2500        2500        20      20      1.5         1.5

本次查询returnsOldLot = 10000(Lot的最大值),而不是8000(最近的先前值)

SELECT A.AID,
   MAX(CONVERT(numeric(30, 2),ISNULL(CASE WHEN h.ChangeField = 'LOT' THEN h.OldValue 
   END,A.LOT))) OldLot,
   MAX(CONVERT(numeric(30, 2),ISNULL(CASE WHEN h.ChangeField = 'LOT' THEN h.NewValue 
   END,A.LOT))) NewLot
FROM A 
LEFT JOIN B ON A.AID = B.AID
LEFT JOIN History h ON B.BID = h.BID
WHERE H.BID = 11
GROUP BY A.AID

下面那个returns(注意OldLot = 10000而不是8000)

AID OldLot  NewLot  
--------------------
1   10000    9000    

谢谢

如果我正确理解你的要求,你就在每个字段的最新历史值之后,你可以使用 row_number 分区,然后你只需要将行转换为列以与当前值:

with h as (
    select b.aid, h.*, 
      Row_Number() over(partition by h.bid, h.changefield order by h.changedate desc) rn
    from history h
    join b on b.bid=h.bid
)
select a.aid,
  isnull(h.oldprice, a.price) OldPrice, a.PRICE newprice,
  isnull(h.oldLot, a.lot) OldLot, a.Lot NewLot,
  isnull(h.oldInterest, a.interest) OldInterest, a.Interest newInterest
from a
outer apply (
  select 
    max(case when changefield = 'LOT' then oldvalue end) OldLot,
    max(case when changefield = 'PRICE' then oldvalue end) OldPrice,
    max(case when changefield = 'INTEREST' then oldvalue end) OldInterest
  from h
  where h.aid = a.aid and h.rn = 1
)h

Demo Fiddle

另请注意,如果您使用的是更新版本的 SQL 服务器 (2016+),则使用 系统版本控制 及其自身扩展的内置功能到 t-sql 这种查询。