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当前解决方案的执行速度将非常慢。