編集:-同様の問題を抱えている人のために、ここにさまざまな解決策をカバーする良い記事があります
次のテーブル recs と audit を考えると、SQL ではどのように結果のテーブルに変換されるでしょうか。
少し背景を説明すると、前のテーブルは、データを収集する CRUD アプリケーションで使用される標準 SQL テーブルの単純化された例です。列が更新されると、レコードが EAV 形式で監査テーブルに書き込まれます。recs テーブルを履歴テーブルに変換し、レポートを作成する時点での各行のコピーを作成する必要があります (データは最終的にスター スキーマ データ ウェアハウスに格納されます。
これは、手続き型言語では十分に簡単で、カーソルを使用して(醜い場合でも)扱いやすいようですが、機能するセットベースのアプローチはありますか?
私は現在 T-SQL を使用していますが、十分に豊富な SQL 方言から例やアイデアを移植できると思います。
設定
create table recs
(
ID int identity(1,1) not null primary key,
Column1 nvarchar(30) not null,
Column2 nvarchar(30) not null,
sys_updated_on datetime not null
)
create table audit
(
ID int identity(1,1) not null primary key,
recs_id int not null,
fieldname nvarchar(30) not null,
old_value nvarchar(30) not null,
new_value nvarchar(30) not null,
sys_updated_on datetime not null
)
insert into recs (Column1, Column2, sys_updated_on)
values ('A', 'B', '2012-10-31 22:00')
, ('C', 'D', '2012-10-31 22:30')
insert into audit (recs_id, fieldname, old_value, new_value, sys_updated_on)
values (1, 'Column1', 'Z', 'A', '2012-10-31 22:00')
, (2, 'Column2','X', 'D', '2012-10-31 22:30')
, (1, 'Column1', 'Y', 'Z', '2012-10-31 21:00')
結果データ
記録 ID 列 1 列 2 sys_updated_on 1 AB 2012/10/31 22:00:00 2 CD 2012/10/31 22:30:00
監査 ID recs_id フィールド名 old_value new_value sys_updated_on 1 1 列 1 ZA 31/10/2012 22:00:00 2 2 列 2 XD 2012 年 10 月 31 日 22:30:00 3 1 列 1 YZ 31/10/2012 21:00:00
望ましい結果
recs_id sys_updated_on 列 1 列 2 1ヌルYB 1 2012 年 10 月 31 日 21:00:00 ZB 1 2012 年 10 月 31 日 22:00:00 AB 2ヌルCX 2 2012/10/31 22:30:00 CD