T-SQL:如何根据增量变化构建最新的对象状态?

时间:2013-02-14 07:19:01

标签: sql sql-server tsql grouping

情况如下:
有一些表存储对象的初始状态,然后对其状态进行增量更改。水木清华。像这样:

...ID...|...Date...|....Field1...|...Field2..|...Field3..|  
...1....|..Today...|....value1...|...NULL....|...NULL....|  
...2....|..date1...|....xxx......|...NULL....|...NULL....|  
...1....|..date2...|....NULL.....|...value2..|...NULL....|  
...1....|..date3...|....init1....|...init2...|...init3...|

所以问题是如何为所有类似于对象的对象构建最新状态 1;今天;值1;值2; INIT3?

2 个答案:

答案 0 :(得分:1)

WITH latestDate
AS
(
SELECT  ID, DATE, Field1, Field2, Field3,
        DENSE_RANK() OVER (ORDER BY DATE DESC) x
FROM    tableName
)
SELECT ID, DATE, Field1, Field2, Field3
FROM    latestDate
WHERE x = 1

答案 1 :(得分:0)

如果您的字段数量有限,可以试试这个。

否则,您将不得不构建动态查询

SQL Fiddle

MS SQL Server 2008架构设置

Create table Test (ID int, 
                   data datetime,
                   field1 varchar(50), 
                   field2 varchar(50), 
                   field3 varchar(50))

insert into test select 1,'2013-02-14','value1',NULL,NULL
insert into test select 2,'2013-02-12','xxx',NULL,NULL
insert into test select 1,'2013-02-10',NULL,'value2',NULL 
insert into test select 1,'2013-02-04','init1','init2','init3'

查询1

;WITH MinDate AS (
  SELECT ID, MIN(DATA) AS DATA, MAX(DATA) AS Lastdate
  FROM Test
  GROUP BY id
  )-- Date of the initial state of each id
, D1 AS (
  SELECT ID, Field1, ROW_NUMBER() OVER (ORDER BY DATA DESC) AS RowNumber
  FROM TEST
  WHERE Field1 IS NOT NULL
  ) --Last date when Field 1 was changed
, D2 AS (
  SELECT ID, Field2, ROW_NUMBER() OVER (ORDER BY DATA DESC) AS RowNumber
  FROM TEST
  WHERE Field2 IS NOT NULL
  )
, D3 AS (
  SELECT ID, Field3, ROW_NUMBER() OVER (ORDER BY DATA DESC) AS RowNumber
  FROM TEST
  WHERE Field3 IS NOT NULL
  )
SELECT T.ID, M.LastDate
, ISNULL(D1.Field1, T.Field1) AS Field1
, ISNULL(D2.Field2, T.Field2) AS Field2
, ISNULL(D3.Field3, T.Field3) AS Field3
FROM Test T
JOIN MinDate M ON T.id=M.id AND T.data=M.data
LEFT OUTER JOIN D1 ON T.ID=D1.ID AND D1.RowNumber=1
LEFT OUTER JOIN D2 ON T.ID=D2.ID AND D2.RowNumber=1
LEFT OUTER JOIN D3 ON T.ID=D3.ID AND D3.RowNumber=1

<强> Results

| ID |                        LASTDATE | FIELD1 | FIELD2 | FIELD3 |
-------------------------------------------------------------------
|  1 | February, 14 2013 00:00:00+0000 | value1 | value2 |  init3 |
|  2 | February, 12 2013 00:00:00+0000 |    xxx | (null) | (null) |