在 json 上使用交叉应用并按大小写排序时,整个 table 的不同结果

distinct result by entire table when using cross apply on json and order by with case

我需要按字典中的值对我的结果进行排序,该字典在我的 table 中存储为 JSON,等于一个参数。 为了得到它,我在订单中使用 case by 检查字典中的值是否与参数匹配。 订购 table 后,我需要区分结果,但出现错误,我无法弄清楚。

这是我的查询:

declare @FilteredItemIDs -> temp table that filtered my items

declare @CurrentGroupID as int

select distinct item.*
from Items as items
    outer apply openjson(json_query(Data, '$.itemOrderPerGroup'), '$') as X
where items.ItemID in (select ItemID from @FilteredItemIDs )
order by case
    when @CurrentGroupID!= 0 and (JSON_VALUE(X.[Value], '$.Key') = @CurrentGroupID) then 1
    else 2 end,
    CONVERT(int, JSON_VALUE(X.[Value], '$.Value'))

当您对结果集 DISTINCT 时,实际上是在对所有列使用 GROUP BY。因此,当您到达 ORDER BY.

时,X.Value 不再存在

使用DISTINCT通常是一种代码味道,它表明连接没有经过深思熟虑。在这种情况下,您可能应该将 OPENJSON 放在子查询中,使用 SELECT TOP (1),尽管没有样本数据和预期结果很难说。

select
  item.*
from Items as items
outer apply (
    select top (1)
      X.[Key],
      X.Value
    from openjson(Data, '$.itemOrderPerGroup')
      with (
          [Key] int,
          Value int
      ) as X
) X
where items.ItemID in (select ItemID from @FilteredItemIDs )
order by case
    when @CurrentGroupID != 0 and X.Key = @CurrentGroupID then 1
    else 2 end,
    X.[Value];

注意 OPENJSON 与 JSON 路径和 属性 名称的正确使用。

如果您真正想要的是过滤 OPENJSON 结果,而不是按它们排序,那么您可以在 EXISTS

中执行此操作
select
  item.*
from Items as items
outer apply  X
where items.ItemID in (select ItemID from @FilteredItemIDs )
  and exists (select 1
    from openjson(Data, '$.itemOrderPerGroup')
      with (
          [Key] int,
          Value int
      ) as X
    where @CurrentGroupID = 0 or X.Key = @CurrentGroupID
);