我有一个要呈现给Json对象的关键字表:
ID Keyword Text Value
4 Category A 10
5 Category B 20
1 Season Winter 1
2 Season Spring 2
3 Season Summer 3
9 Season Fall 4
6 UnitType Ft Feet
7 UnitType Set Set
8 UnitType $ Dollar
将每个类别归为自己的对象。
我能够创建这个:
{"Keywords":[
{"Keyword":"Category","Values":[{"Value":"10","Text":"A"},{"Value":"20","Text":"B"}]},
{"Keyword":"Season","Values":[{"Value":"1","Text":"Winter"},{"Value":"2","Text":"Spring"},{"Value":"3","Text":"Summer"},{"Value":"4","Text":"Fall"}]},
{"Keyword":"UnitType","Values":[{"Value":"Dollar","Text":"$"},{"Value":"Feet","Text":"Ft"},{"Value":"Set","Text":"Set"}]}
]}
使用:
SELECT T.Keyword AS 'Keyword',
(SELECT [subT].[Value] AS 'Value', [subT].[Text] AS 'Text'
FROM tblKeywords subT WHERE subT.Keyword=T.Keyword
ORDER BY [subT].[Value]
FOR JSON PATH) AS 'Values'
FROM tblKeywords T
GROUP BY T.Keyword
FOR JSON PATH, ROOT('Keywords')
但是我希望能够将子查询的ROOT设置为关键字本身。这有可能吗?
所需的结果是:
{"Keywords":[
{"Category":[{"Value":"10","Text":"A"},{"Value":"20","Text":"B"}]},
{"Season":[{"Value":"1","Text":"Winter"},{"Value":"2","Text":"Spring"},{"Value":"3","Text":"Summer"},{"Value":"4","Text":"Fall"}]},
{"UnitType":[{"Value":"Dollar","Text":"$"},{"Value":"Feet","Text":"Ft"},{"Value":"Set","Text":"Set"}]}
]}
答案 0 :(得分:2)
结合FOR JSON
和字符串操作,但不使用动态语句的另一种可能的方法:
输入:
CREATE TABLE #tblKeywords (
Id int,
[Keyword] nvarchar(50),
[Text] nvarchar(50),
[Value] nvarchar(50)
);
INSERT INTO #tblKeywords
(ID, [Keyword], [Text], [Value])
VALUES
(4, 'Category', 'A', '10'),
(5, 'Category', 'B', '20'),
(1, 'Season', 'Winter', '1'),
(2, 'Season', 'Spring', '2'),
(3, 'Season', 'Summer', '3'),
(9, 'Season', 'Fall', '4'),
(6, 'UnitType', 'Ft', 'Feet'),
(7, 'UnitType', 'Set', 'Set'),
(8, 'UnitType', '$', 'Dollar')
T-SQL:
SELECT CONCAT(
N'{"Keywords":[',
STUFF(
(
SELECT DISTINCT CONCAT(N',{"', k.[Keyword], '":', c.[Json], N'}')
FROM #tblKeywords k
CROSS APPLY (
SELECT [Value], [Text]
FROM #tblKeywords
WHERE [Keyword] = k.[Keyword]
FOR JSON PATH
) c([Json])
FOR XML PATH('')
), 1, 1, N''
),
N']}'
) AS JsonOutput
输出:
JsonOutput
{"Keywords":[{"Category":[{"Value":"10","Text":"A"},{"Value":"20","Text":"B"}]},{"Season":[{"Value":"1","Text":"Winter"},{"Value":"2","Text":"Spring"},{"Value":"3","Text":"Summer"},{"Value":"4","Text":"Fall"}]},{"UnitType":[{"Value":"Feet","Text":"Ft"},{"Value":"Set","Text":"Set"},{"Value":"Dollar","Text":"$"}]}]}
答案 1 :(得分:1)
初始数据:
DROP TABLE IF EXISTS #tblKeywords;
CREATE TABLE #tblKeywords (ID INT, Keyword NVARCHAR(255), [Text] NVARCHAR(255), Value NVARCHAR(255));
INSERT INTO #tblKeywords(ID,Keyword,Text,[Value])VALUES
(4,'Category','A','10')
,(5,'Category','B','20')
,(1,'Season','Winter','1')
,(2,'Season','Spring','2')
,(3,'Season','Summer','3')
,(9,'Season','Fall','4')
,(6,'UnitType','Ft','Feet')
,(7,'UnitType','Set','Set')
,(8,'UnitType','$','Dollar')
;
不过,我知道动态SQL:
DECLARE @DynSql NVARCHAR(MAX) = (
SELECT 'SELECT ' + STUFF((
SELECT DISTINCT N',(SELECT [subT].[Value] AS [Value], [subT].[Text] AS [Text]
FROM #tblKeywords subT
WHERE subT.Keyword = ''' + t.Keyword + N'''
ORDER BY [subT].[Value]
FOR JSON PATH
) AS [' + t.Keyword + N']' + CHAR(13) + ' '
FROM #tblKeywords t
FOR XML PATH(''),TYPE).value('(./text())[1]','NVARCHAR(MAX)'),1,1,'')
+ 'FOR JSON PATH, ROOT(''Keywords'')'
)
;
--PRINT @DynSql;
EXEC (@DynSql);