【问题标题】:JSON Path Filter Expression SQL ServerJSON 路径过滤器表达式 SQL Server
【发布时间】:2020-03-29 14:37:53
【问题描述】:

我有以下 JSON。我试图构建一个查询来获取名字、姓氏、iPhone 号码和家庭号码。我正在尝试使用 JSON 路径过滤器表达式。它不适合我。

{
  "firstName": "John",
  "lastName" : "doe",
  "age"      : 26,
  "address"  : {
    "streetAddress": "naist street",
    "city"         : "Nara",
    "postalCode"   : "630-0192"
  },
  "phoneNumbers": [
    {
      "type"  : "iPhone",
      "number": "0123-4567-8888"
    },
    {
      "type"  : "home",
      "number": "0123-4567-8910"
    }
  ]
}

使用的查询

DECLARE @jsonInfo NVARCHAR(MAX)

SET @jsonInfo=N'{  

  "firstName": "John",
  "lastName" : "doe",
  "age"      : 26,
  "address"  : {
    "streetAddress": "naist street",
    "city"         : "Nara",
    "postalCode"   : "630-0192"
  },
  "phoneNumbers": [
    {
      "type"  : "iPhone",
      "number": "0123-4567-8888"
    },
    {
      "type"  : "home",
      "number": "0123-4567-8910"
    }
  ]

 }' 
 SELECT
 JSON_VALUE(@jsonInfo,'$.firstName') AS FirstName,
 JSON_VALUE(@jsonInfo,'$.lastName') AS LastName

 --JSON_VALUE(@jsonInfo,'$.phoneNumbers[?(@.type=="iPhone")].number') AS IPhoneNumber,
 --JSON_VALUE(@jsonInfo,'$.phoneNumbers[?(@.type=="home")].number') AS HomeNumber

问候 阿米尔塔拉杰

【问题讨论】:

    标签: json sql-server


    【解决方案1】:

    解析此 JSON 的一种方法是使用 OPENJSON() 和显式架构。 phoneNumbers 是一个 JSON 数组,因此您需要一个额外的 OPENSJON() 调用。

     SELECT 
        j1.firtstName, j1.lastName, j1.streetAddress, j1.city, j1.postalCode,
        j2.*
     FROM OPENJSON(@jsonInfo) WITH (
        firtstName varchar(100) '$.firstName',
        lastName varchar(100) '$.lastName',
        streetAddress varchar(100) '$.address.streetAddress',
        city varchar(100) '$.address.city',
        postalCode varchar(100) '$.address.postalCode',
        phoneNumbers nvarchar(max) '$.phoneNumbers' AS JSON 
     ) j1
     CROSS APPLY (
        SELECT 
           MAX(CASE WHEN [type] = 'iPhone' THEN [number] END) AS iPhone,
           MAX(CASE WHEN [type] = 'home' THEN [number] END) AS home
        FROM OPENJSON(j1.phoneNumbers) WITH (
           type varchar(10) '$.type',
           number varchar(20) '$.number'
        ) 
     ) j2
    

    结果:

    firtstName  lastName    streetAddress   city    postalCode  iPhone          ome
    John        doe         naist street    Nara    630-0192    0123-4567-8888  0123-4567-8910
    

    当然,您可以使用$.phoneNumbers[x].number 作为path 表达式从$.phoneNumbers JSON 数组中提取每个电话号码(x 是从零开始的索引):

    SELECT 
        j1.firtstName, j1.lastName, j1.streetAddress, j1.city, j1.postalCode,
        j1.number1, j1.number2
     FROM OPENJSON(@jsonInfo) WITH (
        firtstName varchar(100) '$.firstName',
        lastName varchar(100) '$.lastName',
        streetAddress varchar(100) '$.address.streetAddress',
        city varchar(100) '$.address.city',
        postalCode varchar(100) '$.address.postalCode',
        number1 varchar(100) '$.phoneNumbers[0].number',
        number2 varchar(100) '$.phoneNumbers[1].number'
    ) j1
    

    【讨论】:

    • 输出必须是单个记录。不是多条记录 FirstName LastName Iphone Home John doe 0123-4567-8888 0123-4567-8910
    • 谢谢,现在。我将分析查询并让您知道是否有任何问题。
    • 我同意您的交叉应用解决方案。从零开始的索引将不起作用,因为在我在 Project 中的真实示例中,我们有各种类型,并且它们可能不会出现在固定位置。
    • 我会说你的回答很棒。测试了数据库中的多条记录。
    猜你喜欢
    • 1970-01-01
    • 2019-11-13
    • 2014-11-20
    • 1970-01-01
    • 1970-01-01
    • 2020-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多