一連のLEFT JOIN
s を使用してこれを行うことができます。結合する列のデータ型を同じにするために、いくつかのキャストが必要になる場合があります (結合するすべてのテーブルでNewValue
呼び出される列を想定していますが、これは変更が必要になる場合があります)。Name
SELECT a.AuditLogId,
a.Operation,
a.[Table],
a.RowId,
a.Name,
[OldValue] = COALESCE(s_Old.Name, pp_old.Name, t_Old.Name),
[NewValue] = COALESCE(s_New.Name, pp_New.Name, t_New.Name)
FROM AuditLog a
LEFT JOIN Subscriptions s_Old
ON a.OldValue = CAST(s_Old.SubscriptionID AS VARCHAR)
AND a.Name = 'SubscriptionID'
LEFT JOIN ProductPermissions pp_Old
ON a.OldValue = CAST(p_Old.ProductPermissionID AS VARCHAR)
AND a.Name = 'ProductPermissionId'
LEFT JOIN TenantUsers t_Old
ON a.OldValue = CAST(t_Old.TenantUserId AS VARCHAR)
AND a.Name = 'TenantUsers'
LEFT JOIN Subscriptions s_New
ON a.NewValue = CAST(s_New.SubscriptionID AS VARCHAR)
AND a.Name = 'SubscriptionID'
LEFT JOIN ProductPermissions pp_New
ON a.NewValue = CAST(p_New.ProductPermissionID AS VARCHAR)
AND a.Name = 'ProductPermissionId'
LEFT JOIN TenantUsers t_New
ON a.NewValue = CAST(t_New.TenantUserId AS VARCHAR)
AND a.Name = 'TenantUsers'
必要に応じて、これをトランザクションごとに 1 つの行に PIVOT できます。
SELECT a.AuditLogId,
a.Operation,
a.[Table],
a.RowId,
[OldSubscriptionValue] = MAX(s_old.Name),
[OldProductPermissionValue] = MAX(pp_old.Name),
[OldTennantUserValue] = MAX(t_old.Name),
[NewSubscriptionValue] = MAX(s_New.Name),
[NewProductPermissionValue] = MAX(pp_New.Name),
[NewTennantUserValue] = MAX(t_New.Name)
FROM AuditLog a
LEFT JOIN Subscriptions s_Old
ON a.OldValue = CAST(s_Old.SubscriptionID AS VARCHAR)
AND a.Name = 'SubscriptionID'
LEFT JOIN ProductPermissions pp_Old
ON a.OldValue = CAST(p_Old.ProductPermissionID AS VARCHAR)
AND a.Name = 'ProductPermissionId'
LEFT JOIN TenantUsers t_Old
ON a.OldValue = CAST(t_Old.TenantUserId AS VARCHAR)
AND a.Name = 'TenantUsers'
LEFT JOIN Subscriptions s_New
ON a.NewValue = CAST(s_New.SubscriptionID AS VARCHAR)
AND a.Name = 'SubscriptionID'
LEFT JOIN ProductPermissions pp_New
ON a.NewValue = CAST(p_New.ProductPermissionID AS VARCHAR)
AND a.Name = 'ProductPermissionId'
LEFT JOIN TenantUsers t_New
ON a.NewValue = CAST(t_New.TenantUserId AS VARCHAR)
AND a.Name = 'TenantUsers'
GROUP BY a.AuditLogId, a.Operation, a.[Table], a.RowId;
これはかなり汚い解決策です。このデータを選択したい形式で保存する傾向があります。つまり、50/51 の代わりに、読み取り/書き込みをNewValue
列に直接保存します。
あるいは、トランザクションごとに 1 つの行を持つ 2 番目の形式が必要な場合は、この方法で保存する傾向があります。Entity-Attribute-Value Antipatternについて読む価値があるかもしれません。