获取SQL Server 2016中的json数组的长度

Mih*_*kov 8 json sql-server-2016

您知道SQL Server 2016中新的JSON_支持,所以假设我连续存在这些数据

{
  "BaseBoarding": 1,
  "PriceLineStrategy": "PerPersonPerNight",
  "Currency": "EUR",
  "BasePriceLineList": [
    {
      "RoomTypeId": 1,
      "PeriodId": 1,
      "Price": 10.0
    },
    {
      "RoomTypeId": 1,
      "PeriodId": 2,
      "Price": 100.0
    },
    {
      "RoomTypeId": 1,
      "PeriodId": 3,
      "Price": 190.0
    },
    {
      "RoomTypeId": 2,
      "PeriodId": 1,
      "Price": 280.0
    },
    {
      "RoomTypeId": 2,
      "PeriodId": 2,
      "Price": 310.0
    },
    {
      "RoomTypeId": 2,
      "PeriodId": 3,
      "Price": 340.0
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

如何以最高性能的方式获取"BasePriceLineList"的项目数,最好使用内置的JSON支持?

需要写这样的东西:

SELECT JSON_ARRLEN(JsonDataCol, '$.BasePriceline') FROM MyTable
WHERE Id = 1
Run Code Online (Sandbox Code Playgroud)

得到6作为结果.

Mic*_*son 28

假设的 SQL 语句:

SELECT JSON_ARRLEN(JsonDataCol, '$.BasePriceline') FROM MyTable
Run Code Online (Sandbox Code Playgroud)

可以通过实际语句来完成:

SELECT (SELECT COUNT(*) FROM OPENJSON(JsonDataCol, '$.BasePriceline')) FROM MyTable
Run Code Online (Sandbox Code Playgroud)


小智 11

使用表而不是变量:

SELECT count(priceLineLists.RoomTypeId)
FROM Mytable
CROSS APPLY OPENJSON (JsonDataCol, N'$.BasePriceLineList')
  WITH (
    RoomTypeId int)
      AS priceLineLists
Run Code Online (Sandbox Code Playgroud)

  • 我将其标记为正确答案,因为它可以同时在多行上使用。 (2认同)

dfu*_*ako 7

您可以将其转换为数据集,然后计算行数:

DECLARE @JSON NVARCHAR(4000) = N'{
  "BaseBoarding": 1,
  "PriceLineStrategy": "PerPersonPerNight",
  "Currency": "EUR",
  "BasePriceLineList": [
    {
      "RoomTypeId": 1,
      "PeriodId": 1,
      "Price": 10.0
    },
    {
      "RoomTypeId": 1,
      "PeriodId": 2,
      "Price": 100.0
    },
    {
      "RoomTypeId": 1,
      "PeriodId": 3,
      "Price": 190.0
    },
    {
      "RoomTypeId": 2,
      "PeriodId": 1,
      "Price": 280.0
    },
    {
      "RoomTypeId": 2,
      "PeriodId": 2,
      "Price": 310.0
    },
    {
      "RoomTypeId": 2,
      "PeriodId": 3,
      "Price": 340.0
    }
  ]
}'

select COUNT(*) 
FROM OPENJSON(@json, N'$.BasePriceLineList')
WITH (RoomTypeID varchar(100) '$.RoomTypeId')
Run Code Online (Sandbox Code Playgroud)


Bri*_*den 5

在进行一些临时数据审查时,这个基本需求出现了几次。所以我继续创建了一个很小的标量函数来非常通用地做到这一点。内置的假设很少,您可能需要使用isnull和/或使用json_value来拉出您正在尝试检查的嵌套数组。另外,我真的不知道这对任何规模的性能会产生什么影响,我一次只需要对几十条记录执行此操作。只是想我会分享,以防其他人在这里寻找一种相当通用的方法。

注意:在此使用了一些hacky“技巧”,例如确保函数在无效的JSON数组上抛出错误,即使throw在函数内部不允许。额外的除以零是为了防止任何人的隐式转换设置非常宽松,并且只是我在字符串返回有效的其他地方使用的模式。

create function array_length (@array nvarchar(max))
returns int as begin
  if (@array is null or isjson(@array) != 1
      or left(@array, 1) + right(@array, 1) <> '[]')
    return 'Invalid JSON array provided to array_length' + (1/0)
  return (select count(*) from openjson(@array))
end
Run Code Online (Sandbox Code Playgroud)