【问题标题】:Join Two Collections in SQL Server 2016 with JSON Data使用 JSON 数据连接 SQL Server 2016 中的两个集合
【发布时间】:2017-08-30 21:21:19
【问题描述】:

目前,我正在使用带有 JSON 的 SQL Server 2016,我想将集合连接在一起。到目前为止,我创建了两个集合:

CREATE TABLE collect_person(person...)
CREATE TABLE collect_address(address...)

JSON 文档在第一个集合 (collection_person) 中将如下所示:

{
   "id" : "P1",
   "name" : "Sarah",
   "addresses" : {
      "addressId" : [
         "ADD1",
         "ADD2"
      ]
   }
}

第二个集合 (collect_address) 中的 JSON 文档如下所示:

{
   "id" : "ADD1",
   "city" : "San Jose",
   "state" : "CA"
}

{
   "id" : "ADD2",
   "city" : "Las Vegas"
   "state" : "NV"
}

我想获取名为“Sarah”的人的地址,因此输出将类似于:

{
   {"city" : "San Jose", "state" : "CA"},
   {"city" : "Las Vegas", "state" : "NV"}
}

我不想将 JSON 转换为 SQL 并将 SQL 转换为 JSON。这可以在 SQL Server 2016 中使用 JSON 实现吗?请告诉我如何操作?提前谢谢你。

【问题讨论】:

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


    【解决方案1】:

    我的问题有点晚了,但可以通过交叉应用来完成,我还使用了公用表表达式。根据表的大小,我建议在每个表的 id 字段上创建一个持久计算列,假设数据不会更改并且每条记录有一个 addressId 或添加一些其他可以索引和使用的键值限制需要转换为 JSON 的记录。这是一个简单的例子,它还没有经过性能测试,所以“YMMV”。

    构建示例表

    DECLARE @collect_person AS TABLE
    (Person NVARCHAR(MAX))
    
    DECLARE @collect_address as TABLE
    ([Address] NVARCHAR(MAX))
    
    INSERT INTO @collect_person (Person)
    SELECT N'{
       "id" : "P1",
       "name" : "Sarah",
       "addresses" : {
          "addressId" : [
             "ADD1",
             "ADD2"
          ]
       }
    }'
    
    INSERT INTO @collect_address ([Address])
    VALUES 
    (N'{
       "id" : "ADD1",
       "city" : "San Jose",
       "state" : "CA"
    }')
    ,('{
       "id" : "ADD2",
       "city" : "Las Vegas",
       "state" : "NV"
    }')
    

    查询表

    ;WITH persons AS (    
     SELECT --JP.*   
      JP.id
      ,JP.name
     ,JPA.addressId -- Or remove the with clause for JPA and just use JPA.value as addressId    
     FROM @collect_person
     CROSS APPLY OPENJSON([person])
      WITH (
        id varchar(50) '$.id'
        ,[name] varchar(50) '$.name'
        ,addresses nvarchar(max) AS JSON
      )  as JP
      CROSS APPLY OPENJSON(JP.addresses, '$.addressId')
       WITH (
            addressId varchar(250) '$'
       )  AS JPA
    )
    ,Addresses AS (
        SELECT A.*  
        FROM @collect_address AS CA
        CROSS APPLY OPENJSON([Address])
            WITH (
            id varchar(50) '$.id'
            ,city varchar(50) '$.city'
            ,state varchar(2) '$.state'
        ) as A
    )
    
    SELECT * FROM persons
      INNER JOIN Addresses
       ON persons.addressId = Addresses.id
    

    同样,这不是执行此操作的理想方法,但它会起作用,并且如前所述,您可能应该在每个表上都有一个键字段,该字段被索引以限制在表上完成的扫描和 JSON 解析。

    有原生编译,但对我来说是新的,我不熟悉利弊。

    Optimize JSON processing with in-memory OLTP

    【讨论】:

      猜你喜欢
      • 2020-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-09
      • 2018-07-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多