如何将 T-SQL 主元中的值压缩为 JSON?
How do you condense the values in a T-SQL pivot into a JSON?
我在 SQL 服务器中有一个 table,格式如下:
date
userId
sessionStartTime
SessionEndTime
nClicks
2020-01-01
0
9:00:00
9:15:10
4
2020-01-01
0
9:33:00
10:05:05
2
2020-01-01
2
9:05:20
9:25:55
9
...
...
...
...
...
我希望通过 userId
和 date
PIVOT
它并获得将其他列合并为 JSON 数组的内容。预计输出如下所示:
date
userId
data
2020-01-01
0
[{'sessionStartTime':9:00:00, 'SessionEndTime':9:15:10, 'nClicks':4}, {'sessionStartTime':9:33:00, 'SessionEndTime':10:05:05, 'nClicks':2}]
2020-01-01
2
[{'sessionStartTime':9:05:20, 'SessionEndTime':9:25:55, 'nClicks':9}]
...
...
...
关于如何在 SQL (T-SQL) 中实现此目标的任何想法?
您需要为 [date]
和 [userId]
的每个不同组合生成 JSON 内容:
Table:
SELECT *
INTO Data
FROM (VALUES
('2020-01-01', 0, '9:00:00', '9:15:10', 4),
('2020-01-01', 0, '9:33:00', '10:05:05', 2),
('2020-01-01', 2, '9:05:20', '9:25:55', 9)
) v ([date], [userId], [sessionStartTime], [SessionEndTime], [nClicks])
T-SQL:
SELECT DISTINCT [date], [userId], [data]
FROM Data d
OUTER APPLY (
SELECT [sessionStartTime], [SessionEndTime], [nClicks]
FROM Data
WHERE d.[date] = [date] AND d.[userId] = [userId]
FOR JSON PATH
) j (data)
结果:
date
userId
data
2020-01-01
0
[{"sessionStartTime":"9:00:00","SessionEndTime":"9:15:10","nClicks":4},{"sessionStartTime":"9:33:00","SessionEndTime":"10:05:05","nClicks":2}]
2020-01-01
2
[{"sessionStartTime":"9:05:20","SessionEndTime":"9:25:55","nClicks":9}]
不幸的是,SQL 服务器不支持 JSON_AGG
,这本来可以简化事情。
需要自连接,但这实际上可以通过 table 的单次扫描和正常聚合来完成,使用 STRING_AGG
:
SELECT
[date],
[userId],
STRING_AGG(N'[' + [data] + N']', N',')
FROM Data d
CROSS APPLY (
SELECT [sessionStartTime], [SessionEndTime], [nClicks]
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
) j (data)
GROUP BY
[date],
[userId];
我在 SQL 服务器中有一个 table,格式如下:
date | userId | sessionStartTime | SessionEndTime | nClicks |
---|---|---|---|---|
2020-01-01 | 0 | 9:00:00 | 9:15:10 | 4 |
2020-01-01 | 0 | 9:33:00 | 10:05:05 | 2 |
2020-01-01 | 2 | 9:05:20 | 9:25:55 | 9 |
... | ... | ... | ... | ... |
我希望通过 userId
和 date
PIVOT
它并获得将其他列合并为 JSON 数组的内容。预计输出如下所示:
date | userId | data |
---|---|---|
2020-01-01 | 0 | [{'sessionStartTime':9:00:00, 'SessionEndTime':9:15:10, 'nClicks':4}, {'sessionStartTime':9:33:00, 'SessionEndTime':10:05:05, 'nClicks':2}] |
2020-01-01 | 2 | [{'sessionStartTime':9:05:20, 'SessionEndTime':9:25:55, 'nClicks':9}] |
... | ... | ... |
关于如何在 SQL (T-SQL) 中实现此目标的任何想法?
您需要为 [date]
和 [userId]
的每个不同组合生成 JSON 内容:
Table:
SELECT *
INTO Data
FROM (VALUES
('2020-01-01', 0, '9:00:00', '9:15:10', 4),
('2020-01-01', 0, '9:33:00', '10:05:05', 2),
('2020-01-01', 2, '9:05:20', '9:25:55', 9)
) v ([date], [userId], [sessionStartTime], [SessionEndTime], [nClicks])
T-SQL:
SELECT DISTINCT [date], [userId], [data]
FROM Data d
OUTER APPLY (
SELECT [sessionStartTime], [SessionEndTime], [nClicks]
FROM Data
WHERE d.[date] = [date] AND d.[userId] = [userId]
FOR JSON PATH
) j (data)
结果:
date | userId | data |
---|---|---|
2020-01-01 | 0 | [{"sessionStartTime":"9:00:00","SessionEndTime":"9:15:10","nClicks":4},{"sessionStartTime":"9:33:00","SessionEndTime":"10:05:05","nClicks":2}] |
2020-01-01 | 2 | [{"sessionStartTime":"9:05:20","SessionEndTime":"9:25:55","nClicks":9}] |
不幸的是,SQL 服务器不支持 JSON_AGG
,这本来可以简化事情。
STRING_AGG
:
SELECT
[date],
[userId],
STRING_AGG(N'[' + [data] + N']', N',')
FROM Data d
CROSS APPLY (
SELECT [sessionStartTime], [SessionEndTime], [nClicks]
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
) j (data)
GROUP BY
[date],
[userId];