代码之家  ›  专栏  ›  技术社区  ›  DC07

SQL将Json数组解析为行

  •  0
  • DC07  · 技术社区  · 2 年前

    我试图将“custinfo”数组解析为行,而不是查询中的特定列(数组中可能没有或有很多值)

         DECLARE @json NVARCHAR(MAX) ='{
      "customer": [
        {
          "id": "123",
          "history": [
            {
              "id": "a123",
              "dates": [
                {
                  "date": "2022-03-19",
                  "details": {
                    "custinfo": [
                      "male",
                      "married"
                    ],                
                    "age": 40            
                    }}]}]}]}'
                                                 
    SELECT
        JSON_VALUE ( j.[value], '$.id' ) AS CustId,
      JSON_VALUE ( m.[value], '$.id' ) AS CustId_Hist,
       JSON_VALUE ( a1.[value], '$.date' ) AS date,
       JSON_VALUE ( a1.[value], '$.details.age' ) AS age,
       JSON_VALUE ( a1.[value], '$.details.custinfo[0]' ) AS custinfo0,
       JSON_VALUE ( a1.[value], '$.details.custinfo[1]' ) AS custinfo1
    FROM OPENJSON( @json, '$."customer"' ) j
     CROSS APPLY OPENJSON ( j.[value], '$."history"' ) AS m
      CROSS APPLY OPENJSON ( m.[value], '$."dates"' ) AS a1
    

    预期结果:

    enter image description here

    1 回复  |  直到 2 年前
        1
  •  1
  •   Thom A    2 年前

    正如我在评论中提到的,我会转而使用 WITH 子句和定义列及其数据类型。然后,您还可以使用以下命令将值分成两行。注:额外费用 OPENJSON 最后,哪一个治疗 custinfo 就像阵列一样;返回2行(数组中的每个值对应1行):

    DECLARE @json NVARCHAR(MAX) ='{
      "customer": [
        {
          "id": "123",
          "history": [
            {
              "id": "a123",
              "dates": [
                {
                  "date": "2022-03-19",
                  "details": {
                    "custinfo": [
                      "male",
                      "married"
                    ],                
                    "age": 40            
                    }}]}]}]}';
                                                 
    SELECT c.id AS CustId,
           h.id AS CustId_Hist,
           d.date AS date,
           d.age AS age,
           ci.[value] AS custinfo
    FROM OPENJSON( @json,'$.customer')
         WITH (id int,
               history nvarchar(MAX) AS JSON) c
         CROSS APPLY OPENJSON (c.history)
                     WITH (id varchar(10),
                           dates nvarchar(MAX) AS JSON) h
         CROSS APPLY OPENJSON (h.dates) 
                     WITH(date date,
                          details nvarchar(MAX) AS JSON,
                          age int '$.details.age') d
         CROSS APPLY OPENJSON(d.details,'$.custinfo') ci;