簡體   English   中英

SQL 查詢以獲取 Json 內的 Json 值,以逗號分隔

[英]SQL Query to get the Json inside Json values by comma separated

我有以下 Json object。 我需要用逗號(,)分隔的任務名稱。

{
  "Model": [
    {
      "ModelName": "Test Model",    
      "Object": [
         {
           "ID": 1,
           "Name": "ABC",
           "Task" : [
             {
                TaskID : 1222,
                Name: "TaskA"
             },
             {
                TaskID : 154,
                Name: "TaskB"
             }
           ]
         },
         {
           "ID": 11,
           "Name": "ABCD",
           "Task" : [
             {
                TaskID : 222,
                Name: "TaskX"
             },
             {
               TaskID : 234,
               Name: "TaskY"
             }
           ]
        },         
     ]  
 }]}

預期的 Output 應在下表中。 我需要任務名稱應該用逗號分隔。

ModelName   ObjectID   ObjectName  TaskName
Test Model     1          ABC      TaskA, TaskB
Test Model     11         ABCD     TaskX, TaskY

我嘗試了以下查詢。 但我不知道如何對任務名稱進行分組。

                  SELECT   S1.ModelName,
                           S2.ID  AS ObjectID, 
                           S2.Name AS ObjectName, 
                           S3.TaskName
                     FROM TableA 
                       CROSS APPLY OPENJSON(JsonData)
                         WITH (Model NVARCHAR(MAX) '$.Model[0]' AS JSON) S1
                       CROSS APPLY OPENJSON (S1.Model) 
                         WITH (Object NVARCHAR(MAX) '$.Object' AS JSON,
                               ID  INT '$.ID',
                               Name NVARCHAR(250) '$.Name') S2
                       CROSS APPLY OPENJSON (S2.Object) 
                         WITH (Task NVARCHAR(MAX) '$.Task' AS JSON ,
                               TaskName NVARCHAR(MAX) '$.TaskName') S3  

您需要使用適用於 DB 版本 SQL Server 2017 及更高版本的STRING_AGG() function 以及以下GROUP BY表達式為

SELECT S1.ModelName, S2.ID  AS ObjectID, S2.Name AS ObjectName, 
       STRING_AGG(S3.TaskName, ',') WITHIN GROUP (ORDER BY TaskName) AS TaskName
  FROM <rest of your query>
 GROUP BY S1.ModelName, S2.ID, S2.Name

作為一個完整的查詢:

SELECT S1.ModelName, S3.ObjectID, S3.ObjectName,
       STRING_AGG(S4.TaskName, ',') WITHIN GROUP (ORDER BY S4.TaskName) AS TaskName
  FROM TableA 
 CROSS APPLY OPENJSON(JsonData)
  WITH (ModelName NVARCHAR(255) '$.Model[0].ModelName') S1
 CROSS APPLY OPENJSON (JsonData) 
  WITH (Object NVARCHAR(MAX)    '$.Model[0].Object' AS JSON) S2
 CROSS APPLY OPENJSON (S2.Object)   
  WITH (ObjectID       INT           '$.ID',
        ObjectName     NVARCHAR(255) '$.Name',
        Task           NVARCHAR(MAX) '$.Task' AS JSON) S3 
 CROSS APPLY OPENJSON (S3.Task) 
  WITH (TaskID   NVARCHAR(MAX) '$.TaskID',
        TaskName NVARCHAR(MAX) '$.Name') S4
 GROUP BY S1.ModelName, S3.ObjectID, S3.ObjectName

使用WITHIN GROUP (ORDER BY TaskName)是可選的,如果您不想訂購,那么您可以從 function 中刪除該部分,如下面的演示所示:

演示

您需要使用STRING_AGG()來聚合文本值,一種可能的方法(基於問題中的嘗試)是以下語句。 任務名稱的聚合針對Object JSON 數組中的每個項目:

桌子:

CREATE TABLE TableA (JsonData varchar(max))
INSERT INTO TableA (JsonData) VALUES ('{
  "Model": [
    {
      "ModelName": "Test Model",    
      "Object": [
         {
           "ID": 1,
           "Name": "ABC",
           "Task" : [
             {
                "TaskID" : 1222,
                "Name": "TaskA"
             },
             {
                "TaskID" : 154,
                "Name": "TaskB"
             }
           ]
         },
         {
           "ID": 11,
           "Name": "ABCD",
           "Task" : [
             {
                "TaskID" : 222,
                "Name": "TaskX"
             },
             {
               "TaskID" : 234,
               "Name": "TaskY"
             }
           ]
        }         
     ]  
 }]}')

陳述:

SELECT 
   j1.ModelName,
   j2.ObjectID, j2.ObjectName,
   c.TaskName
FROM TableA t
CROSS APPLY OPENJSON(t.JsonData, '$.Model[0]') WITH (
   ModelName varchar(50) '$.ModelName',
   Object nvarchar(max) '$.Object' AS JSON
) j1
CROSS APPLY OPENJSON(j1.Object, '$') WITH (
   ObjectID int '$.ID',
   ObjectName varchar(50) '$.Name',
   Task nvarchar(max) '$.Task' AS JSON
) j2
CROSS APPLY (
   SELECT STRING_AGG([Name], ',') AS TaskName
   FROM OPENJSON (j2.Task, '$') WITH (Name varchar(50) '$.Name')
) c

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM