T-SQL:如何基于对象的增量更改构造最新的对象状态?

T-SQL:如何基于对象的增量更改构造最新的对象状态?,sql,sql-server,tsql,grouping,Sql,Sql Server,Tsql,Grouping,情况是这样的: 有一些表存储对象的初始状态,然后对其状态进行增量更改。Smth。像这样: ...ID...|...Date...|....Field1...|...Field2..|...Field3..| ...1....|..Today...|....value1...|...NULL....|...NULL....| ...2....|..date1...|....xxx......|...NULL....|...NULL....| ...1....|..date2...|..

情况是这样的:
有一些表存储对象的初始状态,然后对其状态进行增量更改。Smth。像这样:

...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

如果字段数量有限,可以尝试此操作

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
否则,您将不得不构造一个动态查询

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'
;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
| 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) |
查询1

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'
;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
| 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) |

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'
;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
| 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) |

实际上,这是返回
1;今天价值1;无效的空
所以我认为这不是正确的答案!这与排名无关。这是关于按ID分组,为组中的每个字段选择最新的NOTNULL值,并为每个组将所有这些内容组合成一行。非常感谢您的建议。这或多或少是一种直接的方法。我只是觉得对于大量的专栏来说,有一个很好的解决方案。如果表中有许多行和列,Cuz当前解决方案的执行速度将非常慢。