2017-07-18 33 views
1

對於一個人的地址變更記錄表筆合併和顯示領域分佈在多個行一行

+----------+----------+----------+--------+-----------------+-------------------+-----------------+ 
| DetailID | PersonID | ChangeID | TypeID | ChangeDateTime |  OldDetail  | NewDetail | 
+----------+----------+----------+--------+-----------------+-------------------+-----------------+ 
|  1 |  10 |  1 |  7 | 7/11/2017 15:48 | 510 S Spring St | 115 E 3rd St | 
|  2 |  10 |  2 |  7 | 7/6/2017 13:27 | 3351 Westwood  | 510 S Spring St | 
|  3 |  10 |  2 |  9 | 7/6/2017 13:27 | San Diego   | Los Angeles  | 
|  4 |  10 |  3 |  7 | 6/29/2017 10:38 | 661 Shatto Pl  | 3351 Westwood | 
|  5 |  10 |  3 |  9 | 6/29/2017 10:38 | Los Angeles  | San Diego  | 
|  6 |  10 |  4 |  7 | 3/3/2017 13:14 | 3835 W 8th St  | 661 Shatto Pl | 
|  7 |  10 |  5 |  7 | 11/22/2016 9:23 | 123 Park   | 3835 W 8th St | 
|  8 |  10 |  5 |  9 | 11/22/2016 9:23 | San Francisco  | Los Angeles  | 
|  9 |  10 |  6 |  7 | 8/3/2016 14:50 | 6650 Franklin Ave | 123 Park  | 
|  10 |  10 |  6 |  9 | 8/3/2016 14:50 | Los Angeles  | San Francisco | 
+----------+----------+----------+--------+-----------------+-------------------+-----------------+ 

DetailID是PK。 ChangeID代表每次只是地址或地址+城市更改。 TypeID代表更改類型:地址更改7,城市更改9。

我想結合這些記錄,使我有1行每變化描述地址和城市的變化,而不是分散在多行。如果該人在同一個城市內移動,我希望從上一次記錄/更新城市時複製該城市。

所需的輸出:

+----------+------------------------+--------------------------------+------------------------------+ 
| ChangeID |  ChangeDateTime |   OldDetail   |   NewDetail   | 
+----------+------------------------+--------------------------------+------------------------------+ 
| 1  | 7/11/2017 15:48  | 510 S Spring St, Los Angeles | 115 E 3rd St, Los Angeles | 
| 2  | 7/6/2017 13:27   | 3351 Westwood, San Diego  | 510 S Spring St, Los Angeles | 
| 3  | 6/29/2017 10:38  | 661 Shatto Pl, Los Angeles  | 3351 Westwood, San Diego  | 
| 4  | 3/3/2017 13:14   | 3835 W 8th St, Los Angeles  | 661 Shatto Pl, Los Angeles | 
| 5  | 11/22/2016 9:23  | 123 Park, San Francisco  | 3835 W 8th St, Los Angeles | 
| 6  | 8/3/2016 14:50   | 6650 Franklin Ave, Los Angeles | 123 Park, San Francisco  | 
+----------+------------------------+--------------------------------+------------------------------+ 

閱讀底部到頂部,因爲排序是下降的日期時間,用最新的地址爲最頂層。因此,這個人首先從位於洛杉磯富蘭克林大道6650號的住處開始,然後經過一系列改變,最終終於在洛杉磯第三街115號。

我無法嘗試的代碼給我這個

+1

我不明白你的問題,部分原因是因爲你只把'Address'和'City'隨處可見,而不是使用這將允許某人understan實際值你的邏輯。 –

+0

更新地址 – AS91

+0

你確定你沒有切換新舊? – dnoeth

回答

1

最簡單的解決方案(只要SQL Server不支持LAST_VALUEIGNORE NULLS選項)是基於遞歸。由於這不允許聚合等,所以您必須首先實現旋轉結果。 這可以使用條件聚集來完成:

select PersonID, ChangeId, ChangeDateTime, 
    max(case when TypeID = 7 then OldDetail end) as OldAddress, 
    max(case when TypeID = 9 then OldDetail end) as OldCity, 
    max(case when TypeID = 7 then NewDetail end) as NewAddress, 
    max(case when TypeID = 9 then NewDetail end) as NewCity 
into #temp 
from Table1 
group by PersonID, ChangeId, ChangeDateTime 
; 

然後它只是遍歷由行的數據行(假設有每人這應該是合理快速的地址更改少數):

with cte as 
(
    select PersonID, ChangeId, ChangeDateTime, OldAddress,OldCity, NewAddress, NewCity 
    from #temp as t1 
    -- would be easier (ChangeId = 1) if the ChangeId was in chronological order 
    where ChangeId = (select max(ChangeId) from #temp as t2 where t1.PersonID = t2.PersonID) 

    union all 

    select t1.PersonID, t1.ChangeId, t1.ChangeDateTime, t1.OldAddress, 
    coalesce(t1.OldCity,cte.NewCity) , t1.NewAddress, 
    coalesce(t1.NewCity,cte.NewCity) 
    from cte 
    join #temp as t1 
    on t1.PersonID = cte.PersonID 
    and t1.ChangeId = cte.ChangeId -1 
) 
select PersonID, ChangeID, ChangeDateTime, 
    OldAddress + ', ' + OldCity as OldDetail, 
    NewAddress + ', ' + NewCity as NewDetail 
from cte 
order by PersonID, changeid 

Fiddle

+0

MAX中應該有一個TypeID。我試過這個,並且它在地址和城市中顯示在不同的字段中。但是,如果只更新地址,則不會從以前的實例複製城市。所以這個字段保持空白。有沒有辦法包括這一點? [SQLFiddle](http://sqlfiddle.com/#!6/4d713/1/0) – AS91

+0

@ AS91:是的,當然,這不能按預期工作。 – dnoeth

+0

@ AS91:不幸的是,SQL Server不支持'LAST_VALUE'的'IGNORE NULLS'選項,那很容易。讓我想一想... – dnoeth