2013-02-14 34 views
0

下面是這種情況:
有一些表存儲對象的初始狀態,然後增量更改爲其狀態。水木清華。像這樣:T-SQL:如何基於其增量更改構建最新的對象狀態?

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

回答

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) | 
+0

非常感謝您的建議。這或多或少是直接的方式。我只是認爲對於大量的列有一些美麗的解決方案。如果表中有許多行和列,Cuz當前解決方案的執行速度會非常緩慢。 – 2013-02-14 09:37:53

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 
+0

實際上,此函數返回'1;今天;值1;空值; null'所以我不認爲這是正確的答案 – Daniel 2013-02-14 07:43:58

+0

正是!這不是關於排名。它是根據ID進行分組,併爲每個組內的每個字段選擇最新的非空值,並將所有這些內容合併到每個組的一行中。 – 2013-02-14 08:06:10

相關問題