gpt4 book ai didi

sql-server - 将 JSON 字符串转换为 SQL Server 中的规范化架构

转载 作者:行者123 更新时间:2023-12-03 00:20:26 24 4
gpt4 key购买 nike

我在 Azure SQL Server 数据库中有一个表,它只是一个 nvarchar(max) 列,其中包含 JSON 字符串,如下所示,每行一个扁平化为一行(大约200,000 行)

{
"username": "George84",
"items": [
{
"type": 8625,
"score": "90"
}, {
"type": 8418,
"score": "84"
}, {
"type": 7818,
"score": "90"
}, {
"type": 23,
"score": "q"
}
]
}

每条记录都有一个用户名和一组包含一个或多个条目的项目。 items 数组中的每个条目都包含一个类型字段(整数)和一个分数字段(字符串)。用户名是唯一的。多个用户可能拥有相同类型的项目,并且这些重复项可能具有相同的分数,也可能不具有相同的分数。

我想将其转换为一组新的正确规范化的表,其架构如下所示:

Schema Diagram

我知道我可以使用外部应用程序来完成此操作,但我希望利用 SQL Server 2016 的 new JSON processing capability完全在数据库/TSQL 内完成。

完成此转换的最佳方法是什么?

最佳答案

这是我第一次使用 Json 和 T-sql,但我认为它很有趣,所以我认为可能有很多更好的解决方案,无论如何让我们开始吧。

首先我需要一些数据来开始,所以我将生成一些临时数据,如下所示:-

declare @jsonData Table (jsonText nvarchar(max))

insert into @jsonData(jsonText)values(N'{
"username": "George84",
"items": [{
"type": 8625,
"score": "90"
}, {
"type": 8418,
"score": "84"
}, {
"type": 7818,
"score": "90"
}, {
"type": 23,
"score": "q"
}
]
}'),(N'{
"username": "George85",
"items": [{
"type": 8625,
"score": "80"
}, {
"type": 8418,
"score": "90"
}, {
"type": 7818,
"score": "70"
}, {
"type": 232,
"score": "q"
}
]
}'),(N'{
"username": "George86",
"items": [{
"type": 8626,
"score": "80"
}, {
"type": 8418,
"score": "70"
}, {
"type": 7818,
"score": "90"
}, {
"type": 23,
"score": "q"
}
]
}'),(N'{
"username": "George87",
"items": [{
"type": 8625,
"score": "90"
}, {
"type": 8418,
"score": "70"
}, {
"type": 7818,
"score": "60"
}, {
"type": 23,
"score": "q"
}
]
}')

这将为我提供一个模拟您的主数据表的表。

让我们创建一些内存表来存储数据,如下所示:

declare @Users Table (ID int not null IDENTITY(1, 1),username nvarchar(50))
declare @Types Table (ID int not null IDENTITY(1, 1),[type] int)
declare @Scores Table (ID int not null IDENTITY(1, 1),score nvarchar(50))
declare @Items Table (ID int not null IDENTITY(1, 1),UserId int,TypeId int,ScoreId int)

您可能已经创建了上述表格,因此可以替换它们。所以让我们跳转到将填充表格的 t-sql

declare @RowsCount int=(select count(*) from @jsonData)
declare @index int=1
declare @jsonRowData NVARCHAR(MAX)
declare @username NVARCHAR(50)

while(@index<=@RowsCount)
begin
;with JsonDataWithSeq as (
select ROW_NUMBER() over(order by jsonText) [seq],* from @jsonData
) select top(1) @jsonRowData=JsonDataWithSeq.jsonText from JsonDataWithSeq where seq=@index

--select @jsonRowData [jsonRowData],ISJSON(@jsonRowData) [ISJSON]

SELECT @username=JSON_VALUE(@jsonRowData, '$.username')

if not exists (select * from @Users where username=@username)--no need for this check if names are unique in the list
insert into @Users (username) values(@username)

insert into @Types([type])
SELECT xx.[type] from OPENJSON(@jsonRowData, 'lax $.items') with ([type] int) xx where xx.[type] not in (select t.[type] From @Types t)

insert into @Scores([score])
SELECT xx.[score] from OPENJSON(@jsonRowData, 'lax $.items') with ([score] nvarchar(50)) xx where xx.[score] not in (select t.[score] From @Scores t)

insert into @Items(UserId,TypeId,ScoreId)
SELECT u.ID [UserID],t.ID [TypeID],s.ID [ScoreID] from OPENJSON(@jsonRowData, 'lax $.items') with ([type] int,[score] nvarchar(50)) xx
inner join @Users u on u.username=@username
inner join @Types t on t.[type]=xx.[type]
inner join @Scores s on s.score=xx.score

set @index=@index+1
end

select * from @Users
select * from @Types
select * from @Scores
select * from @Items

就是这样,希望对您有所帮助。

根据我提供的数据,我得到了以下结果:-

用户表:-

ID  username
== ========
1 George84
2 George85
3 George86
4 George87

类型表:-

ID  type
== =====
1 8625
2 8418
3 7818
4 23
5 232
6 8626

分数表:-

ID  score
== ======
1 90
2 84
3 90
4 q
5 80
6 70
7 60

项目表:-

ID      UserId  TypeId  ScoreId
== ====== ======= ========
1 1 1 1
2 1 1 3
3 1 2 2
4 1 3 1
5 1 3 3
6 1 4 4
7 2 1 5
8 2 2 1
9 2 2 3
10 2 3 6
11 2 5 4
12 3 6 5
13 3 2 6
14 3 3 1
15 3 3 3
16 3 4 4
17 4 1 1
18 4 1 3
19 4 2 6
20 4 3 7
21 4 4 4

关于sql-server - 将 JSON 字符串转换为 SQL Server 中的规范化架构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44833569/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com