如何在SQL中获取JSON数据的最后一个键的值

时间:2019-07-24 10:07:04

标签: sql json sql-server

我在Json的键值对中有一个sql数据。我想要那个json中的Last Key Value。

SELECT TOP 1 
         ID,Code,JSON_QUERY(B.[value]) AS options
FROM OPENJSON(Json) WITH (ID nvarchar(max),Code nvarchar(max),Json nvarchar(max), options NVARCHAR(MAX) AS JSON) D
CROSS APPLY OPENJSON(D.Json) B
ORDER BY B.[key] DESC
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER;

我有Json个数据。

{"98934889":"Date: 08/16/2017","5551099988":"This is First comment","5454454545":"This is Second comment"}

我想要结果"This is second Comment"

2 个答案:

答案 0 :(得分:1)

解决方案1:

下一种方法基于以下事实:当OPENJSON与默认架构一起使用并且JSONJSON对象的数组时,result是一个表具有列keyvaluetype的列,而key列包含此JSON数组中元素的索引。重要的是,JSON必须是有效的JSON数组。

在您的情况下,您需要将JSON转换为有效的JSON对象数组(例如,{"a": 1, "b": 2}被转换为[{"a": 1}, {"b": 2}])。

DECLARE @json nvarchar(max) = N'{"98934889":"Date: 08/16/2017","5551099988":"This is First comment","5454454545":"This is Second comment"}'

SELECT TOP 1 j2.[value]
FROM OPENJSON(CONCAT(N'[', REPLACE(@json, N',', N'},{'), N']')) j1
CROSS APPLY OPENJSON(j1.[value]) j2
ORDER BY j1.[key] DESC

输出:

----------------------
value
----------------------
This is Second comment

解决方案2:

您可以使用ROW_NUMBER()CHARINDEX()OPENJSON()订购结果:

DECLARE @json nvarchar(max) = N'{"98934889":"Date: 08/16/2017","5551099988":"This is First comment","5454454545":"This is Second comment"}'

SELECT TOP 1 t.[value]
FROM (
   SELECT 
      *,
      ROW_NUMBER() OVER (ORDER BY CHARINDEX(CONCAT(N'"', [key], N'":'), @json)) AS Rn
   FROM OPENJSON(@json)
) t
ORDER BY t.Rn DESC

注释:

在这里似乎可以选择使用.. ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) ...,但不能保证像原始JSON那样对行进行排序(在{{ 1}}不是JSON数组)。

JSON

答案 1 :(得分:1)

我用

达到了这样的结果
SELECT TOP 1
ROW_NUMBER() OVER (Order by [Id]) AS [RowNum],
*
FROM 
[dbo].[Logs]
CROSS APPLY
OPENJSON([RawMessage])
WHERE [Id] = 340519
ORDER BY
[RowNum] DESC

对于所有交叉应用行,[Id]都相同。对于一个特定的行(用变量替换)

如果您想在JSON中检索多行的最后一个属性值,可以尝试一下

SELECT *
FROM

(SELECT 
    Max(RowNum) AS [MaxRow],
    [Id]
    FROM 
    (
        SELECT 
        ROW_NUMBER() OVER (Partition by [Id] Order by [Id]) AS [RowNum],
        [Id]

        FROM 
        [dbo].[Logs]
        CROSS APPLY
        OPENJSON([RawMessage])

        --WHERE [Id] in (340519,347307)

    ) AS [Qinner]
    GROUP BY
    [Id]
) as [Q1]

LEFT JOIN

(
    SELECT 
    ROW_NUMBER() OVER (Partition by [Id] Order by [Id]) AS [RowNum],
    [Id],
    [ProcessName],
    [OrganizationUnitId],
    [key],
    [value]

    FROM 
    [dbo].[Logs]
    CROSS APPLY
    OPENJSON([RawMessage])

    --WHERE [Id] in (340519,347307)

) AS [Q2]

ON
[Q1].[Id]= [Q2].[Id] AND
[Q1].[MaxRow] = [Q2].[RowNum]

我检索每个[Id](行)计数的最后一行的值,然后将其加入对具有行计数的OPENJSON具有CROSS APPLY结果的表。