近日在项目中遇到一个问题: 如何在报表中统计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())

数据内容:

创建转换视图:

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

查询结果如下:

总结下解决的思路:

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

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

一个SQLServer中JSON文档型数据的查询问题的更多相关文章

  1. 最近学习工作流 推荐一个activiti 的教程文档

    全文地址:http://www.mossle.com/docs/activiti/ Activiti 5.15 用户手册 Table of Contents 1. 简介 协议 下载 源码 必要的软件 ...

  2. Collection+JSON 文档

    Collection+JSON 文档 对于这个设计,我们不再以可能的状态和转移为起点,相反,我们将从一个集合状态响应中可能元素的顶层布局开始.从这一点入手,其他细节可以随着设计向超媒体类型最底层属性的 ...

  3. MongoDB学习(操作集合中的文档)

    文档概念 文档的数据结构和JSON基本一样. 所有存储在集合中的数据都是BSON格式. BSON是一种类json的一种二进制形式的存储格式,简称Binary JSON. 插入文档 insert()方法 ...

  4. package.json文档

    之前在博客中写过一篇关于 " node.js的安装配置 " 的文章,里面有提到利用 gulp watch 来监听文档的变化.其中需要 package.json 文件才能实现效果,所 ...

  5. 孤荷凌寒自学python第五十四天使用python来删除Firebase数据库中的文档

    孤荷凌寒自学python第五十四天使用python来删除Firebase数据库中的文档 (完整学习过程屏幕记录视频地址在文末) 今天继续研究Firebase数据库,利用google免费提供的这个数据库 ...

  6. [Xcode 实际操作]七、文件与数据-(17)解析JSON文档

    目录:[Swift]Xcode实际操作 本文将演示如何解析JSON文档. 项目中已添加一份JSON文档:menu.json { "menu": { "id": ...

  7. [.NET] 打造一个很简单的文档转换器 - 使用组件 Spire.Office

    打造一个很简单的文档转换器 - 使用组件 Spire.Office [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/6024827.html 序 之前,& ...

  8. Mongoose在向集合中插入文档时的集合命名问题

    Mongoose使用结构化的模式应用到MongoDB集合,为MongoDB Node.js原生驱动程序提供了更多的功能和简化了数据库操作. 从创建连接到向数据库中写入一个条数据经历了以下步骤: 1.连 ...

  9. 在SharePoint 2013 中使用文档库Scheduling (计划公布功能)

    本文讲述在SharePoint2013 中使用文档库Scheduling (计划公布功能)的步骤和注意的事项. 文档库Scheduling (计划公布功能) 用于设定当文档通过审批后特定的时间区间内才 ...

随机推荐

  1. JUC 并发类概览

    JUC 并发类及并发相关类概览,持续补充... AQS 内部有两个队列,一个等待队列(前后节点),一个条件队列(后继节点),其实是通过链表方式实现: 等待队列是双向链表:条件队列是单向链表:条件队列如 ...

  2. 『居善地』接口测试 — 5、使用Requests库发送POST请求

    目录 1.请求正文是application/x-www-form-urlencoded 2.请求正文是raw (1)json格式文本(application/json) (2)xml格式文本(text ...

  3. .NetCore·集成Ocelot组件之完全解决方案

    阅文时长 | 11.04分钟 字数统计 | 17672.8字符 主要内容 | 1.前言.环境说明.预备知识 2.Ocelot基本使用 3.Ocelot功能挖掘 4.Ocelot集成其他组件 5.避坑指 ...

  4. Windows10 添加 新的输入法

    Windows10系统 控制面板 区域 语言首选项 设置 添加 陈桥输入法

  5. Ubuntu 20.04 版本安装

    Ubuntu 20.04 版本安装 安装步骤 首先创建好Ubuntu 20.04虚拟机 等待系统检查完整性 选择语言 选择不更新,回车确定 键盘语言默认即可 网卡IP配置 设置代理服务器 设置源 自定 ...

  6. ssh登录巨慢加速验证

    ssh登录巨慢怎么办,设计验证是好的,但是那些验证的确没啥用反而造成了一些不便修改/开启 /etc/ssh/ssh_config这三个参数再重启即可取消验证 StrictHostKeyChecking ...

  7. ssh创建与添加密钥开启免密登陆 免确认机器指纹参数

     主要是两个步骤 1.控制主机创建密钥对(私钥和公钥) 2.把密钥对的公钥加入对方的认证列表中 [root@vps ~]# ssh-keygen [root@vps ~]# ssh-copy-id u ...

  8. global nonlocal 闭包构建 变量名解析原则

  9. 几年前,为什么我撸了一套RabbitMQ客户端?

    之前文章说过,如果使用 RabbitMQ,尽可能使用框架,而不要去使用 RabbitMQ 提供的 Java 版客户端. 细说起来,其实还是因为 RabbitMQ 客户端的使用有很多的注意事项,稍微不注 ...

  10. Linux将一个文件夹或文件夹下的所有内容复制到另一个文件夹

    Linux将一个文件夹或文件夹下的所有内容复制到另一个文件夹     1.将一个文件夹下的所有内容复制到另一个文件夹下 cp -r /home/packageA/* /home/cp/packageB ...