如何比较 SQL 中的两行 JSON 值?

How to compare two rows of JSON values in SQL?

我有一个计费数据存储在 table 中,就像 SQL 中这样。我想比较 BillContent(Json 具有未知属性的值)。我的目标是将当前版本的 BillContent 与以前版本进行比较,以查看不同部门进行了哪些更改。因此,我希望看到更改后的值。在 SQL 中完成这项工作的最简单方法是什么?

ID BillID VersionNo BillContent
1 150 9 1 {"ID":9,"Description":"testing Bill","Active":true,"AddressID":14,"DepartmentID":9,"LogbillingInfo":true,"ForwardBill":true,"VIP":false,"BillingBranchSectors":[{"SectorID":9,"InspectorID":0,"BillingMovingSteps":[]}],"BillingVersions":[]}
2 151 9 2 {"ID":9,"Description":"testing Bill","Active":true,"AddressID":14,"DepartmentID":9,"LogbillingInfo":true,"ForwardBill":true,"VIP":false,"BillingBranchSectors":[{"SectorID":9,"InspectorID":0,"BillingMovingSteps":[]}],"BillingVersions":[]}
3 152 9 3 {"ID":9,"Description":"testing Billagain","Active":true,"AddressID":14,"DepartmentID":9,"LogbillingInfo":true,"CancellingBillingInfo":false,"ForwardBill":true,"VIP":false,"BillingBranchSectors":[{"SectorID":9,"InspectorID":0,"BillingMovingSteps":[]}],"BillingMetaData[]":,"BillingVersions":[]}

首先我用这个语句得到上面的table:

select bvt.*
from BillVersionTable bvt
where BillID = 9
enter code here

所需解决方案的输出可能只是得到两个 Json 之间的差异,例如下面的 table:

可能的输出 1: 此输出 returns json 仅具有在比较版本与原始版本时不同或更改的属性

Difference
1 {"Description":"testing","LogbillingInfo":false,"ForwardBill":false,"VIP":false}

可能的输出 2: 此输出 returns 一个 VersionNo 和 json 的每个 属性 作为所有版本的列给定的过程。注意:某些属性具有嵌套数组。

VersionNo ID Description Active AddressID DepartmentID LogbillingInfo ForwardBill VIP BillingBranchSectors BillingMetaData BillingVersions
1 1 9 testing Bill true 14 9 true true false [{"SectorID":9,"InspectorID":0,"BillingMovingSteps":[]}] NULL NULL
2 2 9 testing Bill true 14 9 true true false [{"SectorID":9,"InspectorID":0,"BillingMovingSteps":[]}] NULL NULL
3 3 9 testing Billagain true 14 9 true false true [{"SectorID":9,"InspectorID":2,"BillingMovingSteps":[]}] ["metaDatasteps": true, DescriptiveDetail:[]] NULL

可能的解决方案: 比较这些帐单版本的最简单方法是使用 SQL 内置 JSON_VALUE,正如下面 YuTing 所建议的。这将 return 来自版本 table 的 BillContent (JSON) 的每个 属性 作为给定账单 ID 的所有版本的列。对于已知 JSON 对象的属性的情况,这是一个很好的解决方案。 但是,JSON_VALUE 不适用于数组,因为我们在包含数组的 JOSN 中有一些属性,例如 'BillingVersions'。这就是 JSON_QUERY 的来源。 bill id 9的这种做法的例子如下:

    select bv.VersionNo,
JSON_VALUE(BillContent, '$.ID') AS ID,
JSON_VALUE(BillContent, '$.Description') AS Description,
JSON_VALUE(BillContent, '$.Active') AS Active,
JSON_VALUE(BillContent, '$.AddressID') AS AddressID,
JSON_VALUE(BillContent, '$.DepartmentID') AS DepartmentID,
JSON_VALUE(BillContent, '$.LogbillingInfo') AS LogbillingInfo,
JSON_VALUE(BillContent, '$.CancellingBillingInfo') AS CancellingBillingInfo,
JSON_VALUE(BillContent, '$.ForwardBill') AS ForwardBill,
JSON_VALUE(BillContent, '$.VIP') AS VIP,
JSON_QUERY(BillContent, '$.BillingBranchSectors') AS BillingBranchSectors,
JSON_QUERY(BillContent, '$.BillingVersions') AS BillingVersions,
JSON_QUERY(BillContent, '$.BillingMetaData') AS BillingMetaData
from BillVersionTable bv
where BillID = 9

使用json_value,查看微软的文档。

CREATE TABLE data
(
    ID int NOT NULL,
    BillID int NOT NULL,
    VersionNo int NOT NULL,
    BillContent nvarchar(1000) NOT NULL,
);
insert into data values
 (150, 9, 1, '{"ID":9,"Description":"testing Bill","Active":true,"AddressID":14,"DepartmentID":9,"LogbillingInfo":true,"ForwardBill":true,"VIP":false,"BillingBranchSectors":[{"SectorID":9,"InspectorID":0,"BillingMovingSteps":[]}],"BillingVersions":[]}')
,(151, 9, 2, '{"ID":9,"Description":"testing Bill","Active":true,"AddressID":14,"DepartmentID":9,"LogbillingInfo":true,"ForwardBill":true,"VIP":false,"BillingBranchSectors":[{"SectorID":9,"InspectorID":0,"BillingMovingSteps":[]}],"BillingVersions":[]}')
,(152, 9, 3, '{"ID":9,"Description":"testing Billagain","Active":true,"AddressID":14,"DepartmentID":9,"LogbillingInfo":true,"CancellingBillingInfo":false,"ForwardBill":true,"VIP":false,"BillingBranchSectors":[{"SectorID":9,"InspectorID":0,"BillingMovingSteps":[]}],"BillingMetaData":[],"BillingVersions":[]}')
select 
JSON_VALUE(BillContent, '$.ID') AS ID,
JSON_VALUE(BillContent, '$.Description') AS Description,
JSON_VALUE(BillContent, '$.Active') AS Active,
JSON_VALUE(BillContent, '$.AddressID') AS AddressID,
JSON_VALUE(BillContent, '$.DepartmentID') AS DepartmentID,
JSON_VALUE(BillContent, '$.LogbillingInfo') AS LogbillingInfo,
JSON_VALUE(BillContent, '$.CancellingBillingInfo') AS CancellingBillingInfo,
JSON_VALUE(BillContent, '$.ForwardBill') AS ForwardBill,
JSON_VALUE(BillContent, '$.VIP') AS VIP,
JSON_VALUE(BillContent, '$.BillingBranchSectors') AS BillingBranchSectors,
JSON_VALUE(BillContent, '$.BillingVersions') AS BillingVersions,
JSON_VALUE(BillContent, '$.BillingMetaData') AS BillingMetaData
from data
where BillID = 9

dbfiddle