在 SQL 中循环遍历 JSON 数据集

时间:2021-03-12 14:22:08

标签: sql json sql-server

我希望基于 JSON 数据集创建一个包含两列“时间”和“空气温度”的临时表(请参阅下面的示例 sql 代码)。

enter image description here

我面临的问题是 time 和 air_temperature 在层次树中处于不同级别,其中 air_temperature 是时间级别的子级。所以我需要遍历时间序列级别以找到每次的孩子。

在 .NET 中,我可以使用 for each 循环来完成此操作,但我希望在 MSSQL 中执行类似的操作。

foreach (var data in forecast.properties.timeseries)
                {
                    insertStmt = String.Format("INSERT INTO dbo.WeatherJSON(time,air_temperature) VALUES('{0}', '{1}')",
                    data.time,
                    data.data.instant.details.air_temperature,
                    cmd = new SqlCommand(insertStmt, conn);
                    cmd.ExecuteNonQuery();
                }

DECLARE @json NVARCHAR(MAX)

SET @json='{
                "type":"Feature",
                "geometry":{
                    "type":"Point",
                    "coordinates":[13.023,55.596,10]},
                "properties":{
                    "meta":{
                        "updated_at":"2021-03-10T05:57:53Z",
                        "units":{
                            "air_pressure_at_sea_level":"hPa",
                            "air_temperature":"celsius",
                            "cloud_area_fraction":"%",
                            "precipitation_amount":"mm",
                            "relative_humidity":"%",
                            "wind_from_direction":"degrees",
                            "wind_speed":"m/s"}},
                    "timeseries":[
                        {"time":"2021-03-10T06:00:00Z",
                        "data":{
                            "instant":{
                                "details":{
                                    "air_pressure_at_sea_level":1019.9,
                                    "air_temperature":-1.9,
                                    "cloud_area_fraction":7.2,
                                    "relative_humidity":88.8,
                                    "wind_from_direction":137.3,
                                    "wind_speed":1.2}},
                                "next_12_hours":{
                                    "summary":{
                                        "symbol_code":"partlycloudy_day"}},
                                "next_1_hours":{
                                    "summary":{
                                        "symbol_code":"clearsky_day"},
                                    "details":{"precipitation_amount":0.0}},
                                "next_6_hours":{
                                    "summary":{
                                        "symbol_code":"partlycloudy_day"},
                                    "details":{"precipitation_amount":0.0}
                                    }
                                }
                            },
                    {"time":"2021-03-10T07:00:00Z",
                        "data":{
                            "instant":{
                                "details":{
                                    "air_pressure_at_sea_level":1020.3,
                                    "air_temperature":-0.3,
                                    "cloud_area_fraction":9.1,
                                    "relative_humidity":80.8,
                                    "wind_from_direction":139.9,
                                    "wind_speed":1.2}},
                                        "next_12_hours":{
                                            "summary":{
                                                "symbol_code":"partlycloudy_day"}},
                                        "next_1_hours":{
                                            "summary":{
                                                "symbol_code":"clearsky_day"},
                                            "details":{
                                                "precipitation_amount":0.0}},
                                        "next_6_hours":{
                                            "summary":{
                                                "symbol_code":"partlycloudy_day"},
                                            "details":{"precipitation_amount":0.0}
                                            }
                                        }
                                    }]
                                }
                            }'

SELECT *
FROM OPENJSON(@json)
WITH (   
                time    datetime  '$.properties.timeseries',   
                air_temperature nvarchar(50) '$.properties.timeseries.data.instant.details' 
               
              
 ) 

1 个答案:

答案 0 :(得分:4)

您需要根据解析的 JSON 的结构使用正确的 path 表达式:

SELECT *
FROM OPENJSON(@json, '$.properties.timeseries')
WITH (   
   time datetime '$.time',   
   air_temperature nvarchar(50) '$.data.instant.details.air_temperature' 
)