SQLServer中JSON文档型数据的查询问题解决


Posted in SQL Server onJune 27, 2021

近日在项目中遇到一个问题: 如何在报表中统计JSON格式存储的数据?

例如有个调查问卷记录表,记录每个问题的答案。 其结构示意如下(横表设计)

Id user date Q1_Answer Q2_Answer Q3_Answer
行Id 答题用户 答题日期 问题一结果 问题二结果 问题三结果

在[Q1_Answer]、[Q2_Answer]、[Q3_Answer]中记录的数据格式是JSON文档内容,因为是选项值,而且考虑到可能有多选, 所以存储的格式如下:

1 [ 
     {"code":"a", "desc":"Jan."},
     {"code":"b", "desc":"Feb."}
  ]

其中 code 表示选项, desc 表示选项的文字描述。

现在,用户想用PowerBI 来实现对结果的统计。有如下几个问题:

  • 在Power BI中,无法直接从JSON数据中读取到选项值
  • 如果是多选,又该如何处理。

比较适合分析的数据结构应该长这样:

行Id 答题用户 答题日期 问题编号 用户选项 选项文字
1 user1 2021-6-26 Q1 A Jan.
2 user1 2021-6-26 Q2 A Mon.
3 user1 2021-6-26 Q2 B Tue.
4 user1 2021-6-26 Q3 A Swimming
6 user2 2021-6-26 Q1 B Feb.
7 user2 2021-6-26 Q2 ... ...

 注意,上述Q2用户填了2个选项。 本身问卷设定就是支持多选的。 用JSON文档结构保存数据, 主要是为了方便采集和数据存取。因此要额外做些数据处理, 使采集的数据便于统计。

笔者经过一些调查, 发现可以结合使用UNPIVOT和OPENJSON方法来达到理想的效果。 具体过程如下:

准备表格和初始化数据

-- 1 create table
Create Table T_Questionaire(id int identity(1,1) primary key, username varchar(100), t1 nvarchar(500),t2 nvarchar(500),t3 nvarchar(500), dt datetime)


-- 2 init data
Insert into T_Questionaire( username, t1, t2, t3, dt) 
values ('John' , '[{"code":"a", "desc":"Monday"}]', '[{"code":"a", "desc":"Jan."}]', '[{"code":"b", "desc":"2021"}]' ,getdate())
 ,     ('Alice' , '[{"code":"b", "desc":"Tuesday"}]', '[{"code":"a", "desc":"Jan."}, {"code":"b", "desc":"Feb."}]', '[{"code":"a", "desc":"2020"},{"code":"b", "desc":"2021"}]' ,getdate())

数据内容:

SQLServer中JSON文档型数据的查询问题解决

 创建转换视图:

Create   or alter view V_VerticalQuestionaire 
as
with pt as (
select a.username, a.T, a.answers,  a.dt from dbo.T_Questionaire a
unpivot 
  (  answers for T in (t1,t2,t3  ))
a)
select pt.username, pt.dt, pt.T , aw.code, aw.[desc]
from pt 
  cross apply openjson(answers) WITH (code NVARCHAR(100) '$.code', [desc] NVARCHAR(100) '$.desc') aw

查询结果如下:

SQLServer中JSON文档型数据的查询问题解决

 总结下解决的思路:

1 先用unpivot将列行转换, 使横表记录变成纵表记录

2 使用openjson 将json数据转换为集合数据, 然后使用cross apply 将集合展开

好了,到此这篇关于SQLServer中JSON文档型数据的查询问题解决的文章就介绍到这了,更多相关SQLServer中JSON数据查询内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

SQL Server 相关文章推荐
SQLServer 错误: 15404,无法获取有关 Windows NT 组/用户 WIN-8IVSNAQS8T7\Administrator 的信息
Jun 30 SQL Server
SQL写法--行行比较
Aug 23 SQL Server
SQLServer之常用函数总结详解
Aug 30 SQL Server
Windows环境下实现批量执行Sql文件
Oct 05 SQL Server
SQL Server2019数据库备份与还原脚本,数据库可批量备份
Nov 20 SQL Server
sql时间段切分实现每隔x分钟出一份高速门架车流量
Feb 28 SQL Server
SQL Server表分区降低运维和维护成本
Apr 08 SQL Server
使用MybatisPlus打印sql语句
Apr 22 SQL Server
SQL Server一个字符串拆分多行显示或者多行数据合并成一个字符串
May 25 SQL Server
SQL Server中的逻辑函数介绍
May 25 SQL Server
在SQL Server中使用 Try Catch 处理异常的示例详解
Jul 15 SQL Server
sql字段解析器的实现示例
Jun 23 #SQL Server
解决sql server 数据库,sa用户被锁定的问题
在 SQL 语句中处理 NULL 值的方法
Jun 07 #SQL Server
sql中mod()函数取余数的用法
sql查询结果列拼接成逗号分隔的字符串方法
如何有效防止sql注入的方法
SQL 窗口函数实现高效分页查询的案例分析
You might like
用libTemplate实现静态网页的生成
2006/10/09 PHP
Zend Studio 无法启动的问题解决方法
2008/12/04 PHP
PHP文件读写操作之文件写入代码
2011/01/13 PHP
PHP调用wsdl文件类型的接口代码分享
2014/11/19 PHP
php实现简单文件下载的方法
2015/01/30 PHP
PHP获取远程http或ftp文件的md5值的方法
2019/04/15 PHP
SUN的《AJAX与J2EE》全文译了
2007/02/23 Javascript
Add Formatted Text to a Word Document
2007/06/15 Javascript
基于jQuery的消息提示插件之旅 DivAlert(三)
2010/04/01 Javascript
javascript中传统事件与现代事件
2015/06/23 Javascript
全面解析Bootstrap表单使用方法(表单按钮)
2015/11/24 Javascript
前端jquery部分很精彩
2016/05/03 Javascript
jQuery实现点击弹出背景变暗遮罩效果实例代码
2016/06/24 Javascript
JavaScript数值千分位格式化的两种简单实现方法
2016/08/01 Javascript
详解如何使用微信小程序云函数发送短信验证码
2019/03/13 Javascript
JavaScript中将值转换为字符串的五种方法总结
2019/06/06 Javascript
基于Vue el-autocomplete 实现类似百度搜索框功能
2019/10/25 Javascript
vue-property-decorator用法详解
2019/12/12 Javascript
如何使用Jquery动态生成二级选项列表
2020/02/06 jQuery
vue使用exif获取图片经纬度的示例代码
2020/12/11 Vue.js
python发送邮件示例(支持中文邮件标题)
2014/02/16 Python
python实现在pickling的时候压缩的方法
2014/09/25 Python
Python中计算三角函数之cos()方法的使用简介
2015/05/15 Python
python 计算两个日期相差多少个月实例代码
2017/05/24 Python
python解释器spython使用及原理解析
2019/08/24 Python
python opencv实现图片缺陷检测(讲解直方图以及相关系数对比法)
2020/04/07 Python
Python几种常见算法汇总
2020/06/02 Python
Lululemon英国官网:加拿大瑜伽服装品牌
2019/01/14 全球购物
阿姆斯特丹杜莎夫人蜡像馆官方网站:Madame Tussauds Amsterdam
2019/03/12 全球购物
怎样写演讲稿
2014/01/04 职场文书
护士岗前培训自我评鉴
2014/02/28 职场文书
小学副班长竞选稿
2015/11/21 职场文书
OpenCV-Python实现轮廓拟合
2021/06/08 Python
Java输出Hello World完美过程解析
2021/06/13 Java/Android
Flutter Navigator 实现路由传递参数
2022/04/22 Java/Android
Java存储没有重复元素的数组
2022/04/29 Java/Android