SQL 服务器根 + FOR JSON 同一对象中的路径
SQL Server root + FOR JSON Path in the same object
我正在尝试检索 JSON 中的一些数据,但是,我很难以正确的方式格式化它,这里有一个例子:
CREATE TABLE #test (id int identity(1,1), name varchar(100), EntityType VARCHAR(10))
insert into #test values('Dell','PC')
insert into #test values('Microsoft','CO')
insert into #test values('MAC','PC')
insert into #test values('APPLE','CO')
SELECT * FROM #test WHERE EntityType = 'PC' FOR JSON PATH, ROOT('??')
drop table #test
我一直在尝试使用 root 但没有成功
我正在寻找这个结果,它是一个对象,然后是按列分组的数组
{
"CO": [
{
"id": 1,
"name": "Dell",
},
{
"id": 2,
"name": "Microsoft",
},
]
"PC" :[
{
"id": 3,
"name": "MAC",
},
{
"id": 4,
"name": "APPLE",
}]
}
根据您的需要,您可以通过以下两种方式进行此操作。
-- VIA FIXED VALUE --
SELECT [id], [name] FROM Test WHERE EntityType = 'PC'
FOR JSON PATH, ROOT( 'PC' );
-- VIA DYNAMIC SQL --
DECLARE @type varchar(2) = 'PC';
DECLARE @sql nvarchar(MAX) = 'SELECT [id], [name] FROM Test WHERE EntityType=''' + @type + ''' FOR JSON PATH, ROOT(''' + @type + ''');';
EXEC ( @sql );
两个示例 return 以下 JSON:
{
"PC": [{
"id": 1,
"name": "Dell"
}, {
"id": 3,
"name": "MAC"
}]
}
动态 SQL 在您需要可重复用于不同 EntityType
定义的通用功能时非常方便。
另一种没有动态的方法SQL。
实体类型级别的根值来自 table。
SQL
-- DDL and sample data population, start
DECLARE @tbl TABLE (id INT IDENTITY PRIMARY key, [name] varchar(100), EntityType VARCHAR(10));
INSERT INTO @tbl VALUES
('Dell','PC'),
('Microsoft','CO'),
('MAC','PC'),
('APPLE','CO');
-- DDL and sample data population, end
SELECT CONCAT(
N'{',
STUFF(
(
SELECT DISTINCT CONCAT(N',"', k.EntityType, '":', c.[Json])
FROM @tbl AS k
CROSS APPLY (
SELECT id, [name]
FROM @tbl
WHERE EntityType = k.EntityType
FOR JSON PATH
) c([Json])
FOR XML PATH('')
), 1, 1, N''
),
N'}'
) AS JsonOutput;
输出
{
"CO": [
{
"id": 2,
"name": "Microsoft"
},
{
"id": 4,
"name": "APPLE"
}
],
"PC": [
{
"id": 1,
"name": "Dell"
},
{
"id": 3,
"name": "MAC"
}
]
}
我正在尝试检索 JSON 中的一些数据,但是,我很难以正确的方式格式化它,这里有一个例子:
CREATE TABLE #test (id int identity(1,1), name varchar(100), EntityType VARCHAR(10))
insert into #test values('Dell','PC')
insert into #test values('Microsoft','CO')
insert into #test values('MAC','PC')
insert into #test values('APPLE','CO')
SELECT * FROM #test WHERE EntityType = 'PC' FOR JSON PATH, ROOT('??')
drop table #test
我一直在尝试使用 root 但没有成功
我正在寻找这个结果,它是一个对象,然后是按列分组的数组
{
"CO": [
{
"id": 1,
"name": "Dell",
},
{
"id": 2,
"name": "Microsoft",
},
]
"PC" :[
{
"id": 3,
"name": "MAC",
},
{
"id": 4,
"name": "APPLE",
}]
}
根据您的需要,您可以通过以下两种方式进行此操作。
-- VIA FIXED VALUE --
SELECT [id], [name] FROM Test WHERE EntityType = 'PC'
FOR JSON PATH, ROOT( 'PC' );
-- VIA DYNAMIC SQL --
DECLARE @type varchar(2) = 'PC';
DECLARE @sql nvarchar(MAX) = 'SELECT [id], [name] FROM Test WHERE EntityType=''' + @type + ''' FOR JSON PATH, ROOT(''' + @type + ''');';
EXEC ( @sql );
两个示例 return 以下 JSON:
{
"PC": [{
"id": 1,
"name": "Dell"
}, {
"id": 3,
"name": "MAC"
}]
}
动态 SQL 在您需要可重复用于不同 EntityType
定义的通用功能时非常方便。
另一种没有动态的方法SQL。
实体类型级别的根值来自 table。
SQL
-- DDL and sample data population, start
DECLARE @tbl TABLE (id INT IDENTITY PRIMARY key, [name] varchar(100), EntityType VARCHAR(10));
INSERT INTO @tbl VALUES
('Dell','PC'),
('Microsoft','CO'),
('MAC','PC'),
('APPLE','CO');
-- DDL and sample data population, end
SELECT CONCAT(
N'{',
STUFF(
(
SELECT DISTINCT CONCAT(N',"', k.EntityType, '":', c.[Json])
FROM @tbl AS k
CROSS APPLY (
SELECT id, [name]
FROM @tbl
WHERE EntityType = k.EntityType
FOR JSON PATH
) c([Json])
FOR XML PATH('')
), 1, 1, N''
),
N'}'
) AS JsonOutput;
输出
{
"CO": [
{
"id": 2,
"name": "Microsoft"
},
{
"id": 4,
"name": "APPLE"
}
],
"PC": [
{
"id": 1,
"name": "Dell"
},
{
"id": 3,
"name": "MAC"
}
]
}