1

表列:

id
---------
details

我的表列详细信息有 json 对象,例如

"data" : [ {
   "name" : "luke",
   "dob" : "12-10-90",
   "addr" : "sample1",
 }, 
{
    "name" : "sam",
    "dob" : "12-10-88",
    "addr" : "sample2"
   }
]

我想写一个查询,它会给我如下记录:

| id   | name|  dob      |addr       |
|:-----|:----|:--- ------|:----------|
| 1    | luke|  12-10-90 |  sample1  |
| 1    | sam |  12-10-88 |  sample2  |

我试过了

select 
    ID,
    JSON_VALUE(DETAILS, '$.data[0].name') , 
    JSON_VALUE(DETAILS, '$.data[0].dob') , 
        JSON_VALUE(DETAILS, '$.data[0].addr')
from 
    users;

结果计数:

id  cnt  name       dob       addr   
--  ---  ---------  --------  -------
 1    5  luke       12-10-90  sample1
 1    5  sam        12-10-88  sample2
 2    5  awd        12-10-90  sample1
 2    5  awdawdm    12-10-88  sample2
 2    5  sevsevsev  12-10-88  sample2

预期的

id  cnt  name       dob       addr   
--  ---  ---------  --------  -------
 1    2  luke       12-10-90  sample1
 1    2  sam        12-10-88  sample2
 2    3  awd        12-10-90  sample1
 2    3  awdawdm    12-10-88  sample2
 2    3  sevsevsev  12-10-88  sample2
4

2 回答 2

3

要从 json 数组中获取所有对象以及其他列,您可以使用 OpenJson() 和 Cross Apply,如下所示:

 create table users (id int, details nvarchar(max));
 insert into users values (1,N'{
               "data":[
                       {
                        "name" : "luke",
                        "dob" : "12-10-90",
                        "addr" : "sample1"
                       },
                       {
                         "name" : "sam",
                         "dob" : "12-10-88",
                         "addr" : "sample2"
                       }
                      ]
              }');

询问:

 SELECT u.id,count(details.name)over() cnt, details.name, details.dob,details.addr,details.*
 FROM users u CROSS APPLY OPENJSON (u.details,N'$.data') 
           WITH (   
                   
                 [Name] VARCHAR(100) '$.name',
                 dob VARCHAR(10) '$.dob',
                 addr VARCHAR(100) '$.addr'
                
               
  ) AS details

输出:

ID cnt 姓名 出生日期 地址 姓名 出生日期 地址
1 2 卢克 12-10-90 样品1 卢克 12-10-90 样品1
1 2 山姆 12-10-88 样品2 山姆 12-10-88 样品2

db<>在这里摆弄

您的代码正在运行@DLV。请检查。数据格式存在问题。

 create table users (id int, details nvarchar(max));
 insert into users values (1,N'{"data" : 
 [ {     "name" : "luke",     "dob" : "12-10-90",     "addr" : "sample1",   },  
 {      "name" : "sam",      "dob" : "12-10-88",      "addr" : "sample2"    }  
 ]}');




 select 
     ID,
     JSON_VALUE(DETAILS, '$.data[0].name') , 
     JSON_VALUE(DETAILS, '$.data[0].dob') , 
     JSON_VALUE(DETAILS, '$.data[0].addr')
 from 
     users;

输出:

ID (无列名) (无列名) (无列名)
1 卢克 12-10-90 样品1

db<>在这里摆弄

于 2021-03-16T05:16:39.863 回答
3

您可以遍历每条记录并使用它OPENJSON来实现这一点。

DECLARE @Id int
,@details NVARCHAR(MAX)

DROP TABLE IF EXISTS #Result
CREATE TABLE #Result (Id INT, [Name] VARCHAR(100),dob VARCHAR(10),addr VARCHAR(100))

DECLARE json_cursor CURSOR FOR 
SELECT Id,details 
FROM #DetailsTable  -- Replace with your table

OPEN json_cursor  
FETCH NEXT FROM json_cursor INTO @Id,@details

WHILE @@FETCH_STATUS = 0  
BEGIN  
      
      BEGIN
      INSERT INTO #Result
        SELECT @Id AS Id,*
            FROM OPENJSON(@details,N'$.data')
            WITH (   
                  
                            [Name] VARCHAR(100) '$.name',
                            dob VARCHAR(10) '$.dob',
                            adrr VARCHAR(100) '$.addr'
               
              
             ) 
      END

      FETCH NEXT FROM json_cursor INTO @Id,@details 
END 

CLOSE json_cursor  
DEALLOCATE json_cursor 

SELECT * FROM #Result

确保您的 json 对象包含在'{}' 如下所示

{"data" : [ {
   "name" : "luke",
   "dob" : "12-10-90",
   "addr" : "sample1",
 }, 
{
    "name" : "sam",
    "dob" : "12-10-88",
    "addr" : "sample2"
   }
]}
于 2021-03-16T04:32:43.817 回答