如何从包含 json 查询的 table 构建多活动卫星 table?

How to build a Multi-Active Satellite table from a table containing json query?

我有一个 table 如下:

id          |first_active           |openingtimes_json
8326cdd20459|1970-01-01 01:00:00+01 |{"openingTimes":[{"applicable_days":63,"periods":[{"startp":"06:00","endp":"22:00"}]},{"applicable_days":64,"periods":[{"startp":"07:00","endp":"21:00"}]}]}
d392f7532218|1970-01-01 01:00:00+01 |{"openingTimes":[{"applicable_days":31,"periods":[{"startp":"06:00","endp":"22:00"}]},{"applicable_days":64,"periods":[{"startp":"09:00","endp":"22:00"}]},{"applicable_days":32,"periods":[{"startp":"08:00","endp":"22:00"}]}]}

我想根据这样的 Data Vault 原则拥有卫星 table:

id           |subsq|first_active           |applicable_days|startp |endp  |
8326cdd20459 |1    |1970-01-01 01:00:00+01 |63             |06:00  |22:00 |
8326cdd20459 |2    |1970-01-01 01:00:00+01 |64             |07:00  |21:00 |
d392f7532218 |1    |1970-01-01 01:00:00+01 |31             |06:00  |22:00 |
d392f7532218 |2    |1970-01-01 01:00:00+01 |64             |09:00  |22:00 |
d392f7532218 |3    |1970-01-01 01:00:00+01 |32             |08:00  |22:00 |

现在我只知道如何select查询json的内容。 例如,如果我 运行 JSON_VALUE([openingtimes_json], '$.openingTimes[0}.applicable_days')

我的第一条记录是 63。

您需要 SQL Server 2016+ 使用两个 OPENJSON() 调用(使用默认和显式模式)和适当的 APPLY 运算符来解析存储的 JSON。

请注意,我假设 $.periods JSON 数组有一个项目(如果没有,则需要一个额外的 APPLY 运算符和一个 OPENJSON() 调用) :

SELECT 
   v.id, 
   CONVERT(int, j1.[key]) + 1 AS subsq,
   v.first_active,
   j2.applicable_days, 
   j2.startp, 
   j2.endp
FROM (VALUES
   ('8326cdd20459', '1970-01-01 01:00:00+01', '{"openingTimes":[{"applicable_days":63,"periods":[{"startp":"06:00","endp":"22:00"}]},{"applicable_days":64,"periods":[{"startp":"07:00","endp":"21:00"}]}]}'),
   ('d392f7532218', '1970-01-01 01:00:00+01', '{"openingTimes":[{"applicable_days":31,"periods":[{"startp":"06:00","endp":"22:00"}]},{"applicable_days":64,"periods":[{"startp":"09:00","endp":"22:00"}]},{"applicable_days":32,"periods":[{"startp":"08:00","endp":"22:00"}]}]}')
) v (id, first_active, openingtimes_json)
CROSS APPLY OPENJSON (v.openingtimes_json, '$.openingTimes') j1
CROSS APPLY OPENJSON (j1.[value]) WITH (
   applicable_days int '$.applicable_days',
   startp varchar(5) '$.periods[0].startp',
   endp varchar(5) '$.periods[0].endp'
) j2

结果:

id           subsq  first_active           applicable_days   startp  endp
8326cdd20459     1  1970-01-01 01:00:00+01              63   06:00   22:00
8326cdd20459     2  1970-01-01 01:00:00+01              64   07:00   21:00
d392f7532218     1  1970-01-01 01:00:00+01              31   06:00   22:00
d392f7532218     2  1970-01-01 01:00:00+01              64   09:00   22:00
d392f7532218     3  1970-01-01 01:00:00+01              32   08:00   22:00