2017-07-18 12 views
1

の複数の行に分散表示フィールド:を合わせ、T</strong>人の住所変更レコード<strong>テーブルの一列

+----------+----------+----------+--------+-----------------+-------------------+-----------------+ 
| 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は、AddressまたはAddress + Cityが変更されるたびに表示されます。 TypeIDは変更のタイプを表します。住所変更の場合は7、市の変更の場合は9です。

私は、複数の行に分散されているのではなく、AddressとCityの両方の変更を示す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  | 
+----------+------------------------+--------------------------------+------------------------------+ 

ソートは、最新のアドレスが最上位であることと、日時を降順であるため、上へ下をお読みください。その人は最初にLAの6650フランク・アベニューに住んでいます。その後、一連の変更は最終的に115 E 3rd St、LAで終わります。再帰に基づいています(SQL ServerがLAST_VALUEためIGNORE NULLSオプションをサポートしていない限り)

は、私は私にこの

+1

を参照してください。あなたのロジック。 –

+0

住所を更新しました – AS91

+0

古いものと新しいものを入れ替えてもよろしいですか? – dnoeth

答えて

1

最も簡単な解決策を提供するためのコードを試みることができないんです。これは集計などを許可しないため、最初にピボットされた結果を具体化する必要があります。 これは条件付き集約使用して行うことができます。

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 

あなただけの `Address`、代わりに誰かがunderstanできるようになる実数値を使用してのどこでも` City`を入れて、部分的にので、私は、あなたの質問に従わないFiddle

+0

MAXの中にTypeIDがあったはずです。私はこれを試し、別のフィールドに表示されたAddressとCityを使ってトリックを行います。ただし、アドレスのみが更新された場合は、前のインスタンスから市の上にコピーされません。そのフィールドは空白のままです。それを含める方法はありますか? [SQLFiddle](http://sqlfiddle.com/#!6/4d713/1/0) – AS91

+0

@ AS91:もちろん、これは期待どおりに動作しません。 – dnoeth

+0

@ AS91:残念ながら、SQL Serverは 'LAST_VALUE'の' IGNORE NULLS'オプションをサポートしていません。それについて考えてみましょう... – dnoeth

関連する問題