【问题标题】:Importing nested name-value pairs from json into SQL Server将嵌套的名称-值对从 json 导入 SQL Server
【发布时间】:2019-02-14 10:35:16
【问题描述】:

我正在将一个 json 文件导入 SQL 2016,该文件在嵌套值结构中具有一些嵌套的名称-值对。这是我遇到问题的这些对中的值,例如。

{ "name": "Colour", "value": "Orange" }, { "name": "Calories", "value": "25" } 

sql:

Declare @JSON varchar(max)
SELECT @JSON = BulkColumn
FROM OPENROWSET (BULK 'C:\temp\fruit.json', SINGLE_CLOB) as j

If (ISJSON(@JSON)=1) BEGIN
    Select * from openjson ( @JSON )
    WITH(
        id int,
        fruit varchar(20),
        Colour varchar(20) '$.values.Colour',
        Weight int '$.values.Weight'
    ) as Orders
END
ELSE
  Select 'JSON is invalid!'

其中的结果是:

id  fruit   Colour  Weight
1   orange  NULL    NULL
23  Banana  NULL    NULL

完整(测试)数据..

[ { “身份证”:1, “水果”:“橙子”, “价值观”:[ {“名称”:“颜色”,“值”:“橙色”}, {“名称”:“重量”,“值”:“16”}, {“名称”:“卡路里”,“价值”:“25”} ] }, { “身份证”:23, “水果”:“香蕉”, “价值观”:[ {“名称”:“颜色”,“值”:“黄色”}, {“名称”:“重量”,“值”:“30”}, {“名称”:“卡路里”,“价值”:“250”} ] } ]

【问题讨论】:

    标签: json sql-server sql-server-2016 open-json


    【解决方案1】:

    您可以尝试下一种方法,它将返回完整数据:

    DECLARE @json nvarchar(max)
    SET @json = N'[ { "id": 1, "fruit": "orange", "values": [ { "name": "Colour", "value": "Orange" }, { "name": "Weight", "value": "16" }, { "name": "Calories", "value": "25" } ] }, { "id": 23, "fruit": "Banana", "values": [ { "name": "Colour", "value": "Yellow" }, { "name": "Weight", "value": "30" }, { "name": "Calories", "value": "250" } ] } ]'
    
    SELECT i.id, i.fruit, v.[name], v.[value]
    FROM OPENJSON(@json) 
    WITH (
       id int '$.id',
       fruit nvarchar(50) '$.fruit',
       [values] nvarchar(max) '$.values' AS JSON
    ) AS i
    CROSS APPLY (
       SELECT *
       FROM OPENJSON(i.[values])
       WITH (
          [name] nvarchar(max) '$.name',
          [value] nvarchar(max) '$.value'
       )
    ) v
    

    输出:

    id  fruit   name     value
    1   orange  Colour   Orange
    1   orange  Weight   16
    1   orange  Calories 25
    23  Banana  Colour   Yellow
    23  Banana  Weight   30
    23  Banana  Calories 250
    

    如果您想输出有关颜色和重量的信息,请尝试以下操作:

    DECLARE @json nvarchar(max)
    SET @json = N'[ { "id": 1, "fruit": "orange", "values": [ { "name": "Colour", "value": "Orange" }, { "name": "Weight", "value": "16" }, { "name": "Calories", "value": "25" } ] }, { "id": 23, "fruit": "Banana", "values": [ { "name": "Colour", "value": "Yellow" }, { "name": "Weight", "value": "30" }, { "name": "Calories", "value": "250" } ] } ]'
    
    SELECT i.id, i.fruit, v1.[value] AS Colour, v2.[value] AS Weight
    FROM OPENJSON(@json) 
    WITH (
       id int '$.id',
       fruit nvarchar(50) '$.fruit',
       [values] nvarchar(max) '$.values' AS JSON
    ) AS i
    OUTER APPLY (
       SELECT *
       FROM OPENJSON(i.[values])
       WITH (
          [name] nvarchar(max) '$.name',
          [value] nvarchar(max) '$.value'
       )
       WHERE [name] = 'Colour'
    ) v1 
    OUTER APPLY (
       SELECT *
       FROM OPENJSON(i.[values])
       WITH (
          [name] nvarchar(max) '$.name',
          [value] nvarchar(max) '$.value'
       )
       WHERE [name] = 'Weight'
    ) v2
    

    输出:

    id  fruit   Colour  Weight
    1   orange  Orange  16
    23  Banana  Yellow  30
    

    【讨论】:

    • 非常感谢 Zhorov,这是在读取数据,但不是在我所追求的结构中。有趣的方法 - 我会看看我是否能得到我想要的,直到可以提取所需的结构。
    • @Fetchezlavache 更新了答案。
    • 非常感谢。我仍然不敢相信这是最好的方法,但它确实有效......
    • @Fetchezlavache 我已将CROSS APPLY 更改为OUTER APPLY - 如果您的JSON 中没有ColourWeight。谢谢。
    • 有道理,谢谢。仍在寻找替代方案,因为实际上数据与水果无关,而且我有 20 多个名称/值对……:D
    猜你喜欢
    • 1970-01-01
    • 2022-01-03
    • 2014-04-21
    • 1970-01-01
    • 2021-02-09
    • 2017-03-09
    • 1970-01-01
    • 2018-04-09
    • 1970-01-01
    相关资源
    最近更新 更多