计算另一个 JSON 数组中数组的大小:SQL 服务器

Counting size of an array inside another JSON array: SQL SERVER

JSON对象结构是:

{
  "store": {
    "storeId":123,
    "operations": {
      "seasons": [
        {
          "storeHours": [{},{},{}]  // consider it has 3 objects
        },
        {
          "storeHours": [{},{}]  //consider it has 2 objects
        }
      ]
    }
  }
}

我要统计"storeHours"的大小。我试过:

DECLARE @count INT = 0;
DECLARE @destination NVARCHAR = (N'$.store.operations.seasons[' +  @count +  N'].storeHours');

也试过:

DECLARE @destination NVARCHAR = CONCAT(N'$.store.operations.seasons[',  @count, N'].storeHours');

DECLARE @storeHoursCount INT = (
   select count(A.[key]) as [count] 
   from (VALUES(@json)) V(J)
   CROSS APPLY OPENJSON(V.J) WITH(
      [storeHours] nvarchar(MAX) @destination  AS JSON) S
   CROSS APPLY OPENJSON(S.storeHours) A
);

我收到一个错误:

Incorrect syntax near '@destination'

这个有效:

DECLARE @storeHoursCount INT = (
   select count(A.[key]) as [count] 
   from (VALUES(@json)) V(J)
   CROSS APPLY OPENJSON(V.J) WITH (
      [storeHours] nvarchar(MAX) '$.store.operations.seasons[0].storeHours' AS JSON
   ) S
   CROSS APPLY OPENJSON(S.storeHours) A
);

但我希望它是动态的。有什么我想念的吗?另外 CONCAT() 不工作的原因是什么?

编辑: 当我们想要所有 storeHours 计数时,@Zhorov 解决方案非常有效。即所有季节中存在的所有 storeHours 的总和。

我的要求是根据索引季节(例如:季节[0])计算商店营业时间。 如何实现?

答案:

如果我对你的理解是正确的,并且你想计算所有嵌套 $.storeHours 数组中的所有项目,可以选择以下方法:

JSON:

DECLARE @count INT = 0;
DECLARE @destination nvarchar(max) = N'
{
  "store": {
    "storeId":123,
    "operations": {
      "seasons": [
        {
          "storeHours": []
        }
      ]
    }
  }
}'

声明:

SELECT @count = COUNT(*)
FROM OPENJSON(@destination, '$.store.operations.seasons') j1
CROSS APPLY OPENJSON(j1.[value], '$.storeHours') j2

SELECT @count

作为附加说明,始终指定 nvarchar 变量的长度。当变量声明语句中未指定长度时,默认长度为 1。在您的情况下,@destination 变量的实际值只是 $.

更新:

如果您想...根据索引季节获取营业时间计数...,只需使用适当的WHERE 子句:

DECLARE @count INT = 0;
DECLARE @destination nvarchar(max) = N'
{
  "store": {
    "storeId":123,
    "operations": {
      "seasons": [
        {
          "storeHours": [{},{},{}]
        },
        {
          "storeHours": [{},{}] 
        }
      ]
    }
  }
}'

SELECT @count = COUNT(*)
FROM OPENJSON(@destination, '$.store.operations.seasons') j1
CROSS APPLY OPENJSON(j1.[value], '$.storeHours') j2
WHERE CONVERT(int, j1.[key]) = 0