2017-07-18 48 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