1. ホーム
  2. データベース
  3. エムエスエル

SQLServerにおけるJSONドキュメント型データのクエリ問題を解決する。

2022-01-06 14:26:49

最近、あるプロジェクトで問題に遭遇しました。JSON形式で保存されたデータをレポート内でカウントするには?

例えば、各質問の回答を記録するアンケート記録テーブルがあります。構造は下図のようになっています(横型のテーブルデザイン)。

<テーブル ID ユーザー 日付 Q1_回答 Q2_Answer Q3_回答 行番号 回答ユーザー 回答日 質問1結果 質問2結果 質問3結果

Q1_Answer]、[Q2_Answer]、[Q3_Answer]に記録されているデータは、選択肢の値であることからJSON文書の形式になっており、複数の選択肢があることを考慮して、以下の形式で格納されます。

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


ここで、codeはオプションを表し、descはオプションのテキスト説明を表します。

さて、ユーザーはPowerBIを使って、結果の統計を実施したいと考えています。いくつかの質問があります。

  • Power BI では、JSON データからオプション値を直接読み取ることができない
  • また、複数選択である場合の対処法。

分析に適したデータ構造は、次のようなものです。

<テーブル 行番号 回答ユーザー 回答日 質問番号 ユーザーオプション オプションテキスト 1 ユーザー1 2021-6-26 Q1 A 1月 2 ユーザー1 2021-6-26 Q2 A 月 3 ユーザー1 2021-6-26 Q2 B 火 4 ユーザー1 2021-6-26 Q3 A スイミング 6 ユーザー2 2021-6-26 Q1 B 2月 7 ユーザー2 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& quot;:"Jan."}, {"code":"b", "desc":"Feb."}]', '[{"code":"a", "desc"', '[{"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.
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ドキュメントベースのデータをクエリするためのものです。SQLServerでのJSONデータのクエリについては、スクリプトハウスの過去記事を検索するか、以下の記事を引き続き閲覧してください。