我有以下sql视图结果,其中包含系统中每个表的每个字段的审计更改:
在这种情况下,上面的图片告诉我们,对于名为 Lucas 已撤消读取和写入权限> MySubscription 。
我需要在网格中显示该信息,但这不是我想要显示的内容,我的意思是,我不想显示ID。我需要显示“Read”而不是50,“Write”而不是51,“Lucas”而不是1和“MySubscription”而不是6。
要做到这一点,我想改进sql视图以获取值而不是他们的ID,如上所述。我正在寻找的结果是这一个:
数据库包含表订阅, ProductPermissions 和 TenantUsers 以使用连接获取所需信息。
请您告诉我一些关于如何实现我需要的线索?谢谢。
答案 0 :(得分:2)
您可以使用一系列LEFT JOIN
执行此操作,可能需要某些转换才能使加入列的数据类型与NewValue
相同(我假设了一个名为{{1的列)在所有连接表中,这可能需要更改):
Name
如果需要,您可以将每个事务PIVOT分成一行:
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'
这是一个非常脏的解决方案,我倾向于以您想要选择它的格式存储这些数据,而不是50/51,直接在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;
列存储读/写。
或者,如果您确实希望第二种格式每个事务有一行,那么我倾向于以这种方式存储它。值得一读的是Entity-Attribute-Value Antipattern。
答案 1 :(得分:0)
您可以PIVOT
数据和LEFT JOIN
查找表。如有必要,请UNPIVOT
。
答案 2 :(得分:0)
如果您只需要显示单词而不是数字,请创建一个查找表,在您要显示的数字和单词之间进行映射:
create table NewValueText (
NewValue integer,
Description char(20)
);
insert into NewValueText values
(50, 'Read'),
(51, 'Write'); --etc.
--MyTable is your table that contains the NewValue column.
select Description from MyTable
inner join NewValueText on MyTable.NewValue = NewValueText.NewValue;
答案 3 :(得分:0)
您可以尝试加入特定值的表格。您需要为除了Really之外的其他值创建一个查找表,这是一个肮脏的解决方案,因为这意味着将NewValue
字段硬编码到SQL中:
...
FROM
audit LEFT JOIN
mysubscription ON audit.rowid = mysubscription.tenantuserid
AND audit.newvalue = 1
LEFT JOIN
lookup_list ON audit.rowid = lookup_list.lookup_id
AND audit.newvalue <> 1
...
这可能适合你。