sql - 选择存储在 SQL 中的动态 json 作为选择查询的一部分
问题描述
我知道类似的问题已经被问过多次,但是我的情况似乎有点不同。
我的数据库表是这样的:
App ID | ID | JSONData | URL | CreatedOn
----------+-----------+-------------------+--------------+-----------------
5b5cd8 | 1 | {"F":"B", "S":"D"}| http://local | Mar 19 2018 13:04
5b5cd8 | 2 | {"F":"C", "S":"K"}| http://remote| Mar 29 2018 09:34
6b9df0 | 3 | {"T":"N", "D":"S"}| http://site | Apr 04 2018 16:12
App ID
column 可以有不同的值,但是相同的结构JSONData
是(*应该是)相同的App ID
。
无论如何我可以拆分JSONData
数据并得到这样的结果吗?
App ID | ID | F | S | URL | CreatedOn
----------+-----------+-----+-----+--------------+-------------------------
5b5cd8 | 1 | B | D | http://local | Mar 19 2018 13:04
5b5cd8 | 2 | C | K | http://remote| Mar 29 2018 09:34
接下来App ID
是这样的
App ID | ID | T | D | URL | CreatedOn
----------+-----------+-----+-----+--------------+-------------------------
6b9df0 | 3 | N | S | http://site | Apr 04 2018 16:12
注意:字段中的数据JSONData
大多是一层深度,即所有数据都是字符串,没有其他对象。
我发现的大多数时候都是这样的解决方案,要么使用静态 JSON 键名进行拆分,要么创建会导致性能问题的临时表。
解决方案
您已经被告知,结果集的列名必须事先知道。
唯一的解决方法是动态 SQL(将语句创建为字符串并EXEC()
获取其结果)。但这有一些主要缺点(和一些优点)......
您可能会这样做(需要 SQL-Server 2016+):
样机表
DECLARE @tbl TABLE(AppID VARCHAR(100),ID INT,JSONData NVARCHAR(MAX));
INSERT INTO @tbl VALUES
('5b5cd8',1,N'{"F":"B", "S":"D"}')
,('5b5cd8',2,N'{"F":"C", "S":"K"}')
,('6b9df0',3,N'{"T":"N", "D":"S"}');
--此查询使用JSON_VALUE
--您需要为每个可能的列列表创建一个语句 --
应用 aWHERE
来过滤适当的行
SELECT t.AppID
,t.ID
,JSON_VALUE(t.JSONData,'$.F') AS F
,JSON_VALUE(t.JSONData,'$.S') AS S
FROM @tbl t
WHERE t.AppID='5b5cd8'
--您可能包括所有可能的列
--这
在没有过滤器的情况下有效,但会返回很多 NULL
SELECT t.AppID
,t.ID
,JSON_VALUE(t.JSONData,'$.F') AS F
,JSON_VALUE(t.JSONData,'$.S') AS S
,JSON_VALUE(t.JSONData,'$.T') AS T
,JSON_VALUE(t.JSONData,'$.D') AS D
FROM @tbl t
-- 更清晰/更好阅读OPENJSON()
与-WITH
子句有关
SELECT t.AppID
,t.ID
,JsonColumns.*
FROM @tbl t
CROSS APPLY OPENJSON(t.JSONData) WITH(F CHAR(1)
,S CHAR(1)
,T CHAR(1)
,D CHAR(1)) JsonColumns
我的建议:将最后一个创建为 VIEW 或(可能更好)一个 iTVF,并针对此使用专用语句,每种类型的结构一个。
推荐阅读
- python - 使用基于 ctypes 的扩展安装 python 包的问题
- git - git push 有效,但不是 git push origin master
- tensorflow - Keras Tuner 从超参数搜索中返回验证损失
- mozilla - 远程计算机的 mozilla.cfg 设置
- javascript - t梳反应原生表单选择器无法显示选择的值
- python - Fabric echo 命令输出错误
- elasticsearch - Elasticsearch 包括每个嵌套对象的 geo_distance 并按 [0] element.distance 排序
- javascript - 如何在 chrome 扩展程序中以编程方式转到 youtube 视频中的特定时间?
- amazon-web-services - 将 S3 文件下载到 Elasticbeanstalk 应用程序目录不起作用
- vue.js - 在测试期间在 Web 应用程序的页面上定位组件的最佳实践是什么?