使用OPENJSON读取JSON返回NULL,如何提取所有车型?
提取JSON中所有车型名称的SQL解决方案
你之前的查询返回NULL是因为$.Models是数组类型,直接用$.Models.Make不符合JSON路径的语法规则——数组必须通过索引或通配符才能访问内部元素。要提取所有层级的车型名称,可以用以下两种方法:
方法一:嵌套CROSS APPLY逐层解析
这种方法适合需要同时提取其他关联字段(比如车型分类、品牌)的场景,逻辑清晰:
DECLARE @PermsJSON NVARCHAR(MAX) = N'{ "Root": "Vehicles", "Models": [ { "Type": "Sedan", "Make": [ { "color": "Red", "name": "Toyota", "Models": [ "Corolla", "Camry" ] }, { "color": "Blue", "Make": "Honda", "Models": [ "Civic" ] } ] }, { "Type": "SUV", "Make": [ { "color": "White", "name": "Hyundai", "Models": [ "Santa", "Tucson" ] }, { "color": "Black", "Make": "Ford", "Models": [ "Bronco" ] } ] } ] }'; SELECT model_name FROM OPENJSON(@PermsJSON, '$.Models') AS outer_models CROSS APPLY OPENJSON(outer_models.value, '$.Make') AS makes CROSS APPLY OPENJSON(makes.value, '$.Models') WITH ( model_name NVARCHAR(50) '$' ) AS model_names;
逻辑说明:
- 第一层
OPENJSON遍历最外层的车型分类数组(Sedan、SUV) - 第二层
CROSS APPLY遍历每个分类下的品牌数组(Toyota、Honda等) - 第三层
CROSS APPLY解析每个品牌对应的车型数组,提取出具体车型名称
方法二:使用JSON路径通配符简化查询
如果只需要提取车型名称,用通配符[*]匹配所有数组元素,直接定位到目标数据,代码更简洁:
DECLARE @PermsJSON NVARCHAR(MAX) = N'{ "Root": "Vehicles", "Models": [ { "Type": "Sedan", "Make": [ { "color": "Red", "name": "Toyota", "Models": [ "Corolla", "Camry" ] }, { "color": "Blue", "Make": "Honda", "Models": [ "Civic" ] } ] }, { "Type": "SUV", "Make": [ { "color": "White", "name": "Hyundai", "Models": [ "Santa", "Tucson" ] }, { "color": "Black", "Make": "Ford", "Models": [ "Bronco" ] } ] } ] }'; SELECT value AS model_name FROM OPENJSON(@PermsJSON, '$.Models[*].Make[*].Models[*]');
逻辑说明:
$.Models[*].Make[*].Models[*]路径中,[*]表示匹配对应层级数组中的所有元素,直接遍历所有分类、品牌下的车型数组,提取出所有车型名称。
两种方法最终都会返回你需要的结果:Corolla、Camry、Civic、Santa、Tucson、Bronco。
内容的提问来源于stack exchange,提问作者Krishna Kishore
相关产品推荐
相关产品推荐

