JSON 每个选定日期的根
JSON with roots for every selected day
我每天都在为嵌套根的问题而苦恼(这是我 table 的一个元素)。我想从 table Day.
获取嵌套的 Key: value 对
这是我的结果:
[
{
"date":"2022-01-10T00:00:00",
"title":"Coloring",
"start_time":"2022-01-10T12:00:00",
"end_time":"2022-01-10T13:00:00"
},
{
"date":"2021-12-28T00:00:00",
"title":"Coloring",
"start_time":"2021-12-27T15:20:00",
"end_time":"2021-12-27T16:00:00"
},
{
"date":"2021-12-28T00:00:00",
"title":"Coloring",
"start_time":"2021-12-27T12:20:00",
"end_time":"2021-12-27T14:00:00"
}
]
预期结果如下:
{
"2022-01-10":[
{
"date":"2022-01-10T00:00:00",
"title":"Coloring",
"start_time":"2022-01-10T12:00:00",
"end_time":"2022-01-10T13:00:00"
}
],
"2021-12-28":[
{
"date":"2021-12-28T00:00:00",
"title":"Coloring",
"start_time":"2021-12-27T15:20:00",
"end_time":"2021-12-27T16:00:00"
},
{
"date":"2021-12-28T00:00:00",
"title":"Coloring",
"start_time":"2021-12-27T12:20:00",
"end_time":"2021-12-27T14:00:00"
}
]
}
天table:
id date
0 2021-12-01 00:00:00.0000000
1 2021-12-02 00:00:00.0000000
2 2021-12-03 00:00:00.0000000
... ...
这是我的活动 Table:
id title start_time end_time day_of_timetable service_id
0 Coloring 2022-01-10 12:00:00.0000000 2022-01-10 13:00:00.0000000 0 0
1 Coloring 2021-12-27 15:20:00.0000000 2021-12-27 16:00:00.0000000 1 0
2 Coloring 2021-12-27 12:20:00.0000000 2021-12-27 14:00:00.0000000 1 0
这是我的 day_of_timetable table:
id day_id end_user_id
0 40 1
1 27 1
这是我的代码
select date, e.title, e.start_time, e.end_time, e.day_of_timetable_id
from day
join day_of_timetable dot on day.id = dot.day_id
join end_user eu on dot.end_user_id = eu.id
join event e on dot.id= e.day_of_timetable_id
where eu.id = 1 for json path
请尝试以下解决方案。
SQL
-- DDL and sample data population, start
DECLARE @tbl TABLE (id INT IDENTITY PRIMARY key, [date] DATETIME, title VARCHAR(20), start_time DATETIME, end_time DATETIME);
INSERT INTO @tbl (date, title, start_time, end_time) VALUES
('2022-01-10T00:00:00', 'Coloring','2022-01-10T12:00:00','2022-01-10T13:00:00'),
('2021-12-28T00:00:00', 'Coloring','2021-12-27T15:20:00','2021-12-27T16:00:00'),
('2021-12-28T00:00:00', 'Coloring','2021-12-27T12:20:00','2021-12-27T14:00:00');
-- DDL and sample data population, end
SELECT * FROM @tbl;
SELECT CONCAT(
N'{',
STUFF(
(
SELECT CONCAT(N',"', CAST(k.[date]AS DATE), '":', c.[Json])
FROM @tbl AS k
CROSS APPLY (
SELECT [date], title, start_time, end_time
FROM @tbl
WHERE [date] = k.[date]
FOR JSON PATH
) c([Json])
GROUP BY [date], c.[Json]
ORDER BY [date] DESC
FOR XML PATH('')
), 1, 1, N''
),
N'}'
)
AS JsonOutput;
输出
{
"2022-01-10": [
{
"date": "2022-01-10T00:00:00",
"title": "Coloring",
"start_time": "2022-01-10T12:00:00",
"end_time": "2022-01-10T13:00:00"
}
],
"2021-12-28": [
{
"date": "2021-12-28T00:00:00",
"title": "Coloring",
"start_time": "2021-12-27T15:20:00",
"end_time": "2021-12-27T16:00:00"
},
{
"date": "2021-12-28T00:00:00",
"title": "Coloring",
"start_time": "2021-12-27T12:20:00",
"end_time": "2021-12-27T14:00:00"
}
]
}
在 SQL 服务器的现代版本中,您可以为此使用 STRING_AGG
,一次按日期聚合,然后再次聚合整个事件。
您还可以获得仅查询一次 table 的好处(APPLY
仅指回外部 table)。
Note that if you are using arbitrary text as the keys, you should use STRING_ESCAPE
to escape them
SELECT
JsonOutput = N'{' + STRING_AGG(N'"' + CAST(t.date AS nvarchar(30)) + N'":' + t.[Json], N',') WITHIN GROUP (ORDER BY [date] DESC) + N'}'
FROM (
SELECT
date = CAST(t.date AS date),
Json = STRING_AGG(N'[' + c.Json + N']', ',') WITHIN GROUP (ORDER BY [date] DESC)
FROM @tbl t
CROSS APPLY (
SELECT t.date, t.title, t.start_time, t.end_time
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
) c(Json)
GROUP BY CAST(t.date AS date)
) t;
分组日table,按id排序,按日期字段的日期部分排序,日期部分作为字段头。每个字段的值是对应组的table个序列,然后我们将它们转化为JSON格式。 SQL 只能assemble 将JSON 字符串按指定格式手动。该声明冗长且难以阅读。一般的替代方法是从数据库中提取原始数据并在 Python 或 SPL 中对其进行处理。 SPL,open-source Java 包,更容易集成到 Java 程序中并生成简单的代码。它只用两行代码就完成了任务:
A
1
=MSSQL.query("select date,title,start_time,end_time from json order by id")
2
=json(transpose(A1.group@o(date(date)).run(~=[date(date)]
我每天都在为嵌套根的问题而苦恼(这是我 table 的一个元素)。我想从 table Day.
获取嵌套的 Key: value 对这是我的结果:
[
{
"date":"2022-01-10T00:00:00",
"title":"Coloring",
"start_time":"2022-01-10T12:00:00",
"end_time":"2022-01-10T13:00:00"
},
{
"date":"2021-12-28T00:00:00",
"title":"Coloring",
"start_time":"2021-12-27T15:20:00",
"end_time":"2021-12-27T16:00:00"
},
{
"date":"2021-12-28T00:00:00",
"title":"Coloring",
"start_time":"2021-12-27T12:20:00",
"end_time":"2021-12-27T14:00:00"
}
]
预期结果如下:
{
"2022-01-10":[
{
"date":"2022-01-10T00:00:00",
"title":"Coloring",
"start_time":"2022-01-10T12:00:00",
"end_time":"2022-01-10T13:00:00"
}
],
"2021-12-28":[
{
"date":"2021-12-28T00:00:00",
"title":"Coloring",
"start_time":"2021-12-27T15:20:00",
"end_time":"2021-12-27T16:00:00"
},
{
"date":"2021-12-28T00:00:00",
"title":"Coloring",
"start_time":"2021-12-27T12:20:00",
"end_time":"2021-12-27T14:00:00"
}
]
}
天table:
id date
0 2021-12-01 00:00:00.0000000
1 2021-12-02 00:00:00.0000000
2 2021-12-03 00:00:00.0000000
... ...
这是我的活动 Table:
id title start_time end_time day_of_timetable service_id
0 Coloring 2022-01-10 12:00:00.0000000 2022-01-10 13:00:00.0000000 0 0
1 Coloring 2021-12-27 15:20:00.0000000 2021-12-27 16:00:00.0000000 1 0
2 Coloring 2021-12-27 12:20:00.0000000 2021-12-27 14:00:00.0000000 1 0
这是我的 day_of_timetable table:
id day_id end_user_id
0 40 1
1 27 1
这是我的代码
select date, e.title, e.start_time, e.end_time, e.day_of_timetable_id
from day
join day_of_timetable dot on day.id = dot.day_id
join end_user eu on dot.end_user_id = eu.id
join event e on dot.id= e.day_of_timetable_id
where eu.id = 1 for json path
请尝试以下解决方案。
SQL
-- DDL and sample data population, start
DECLARE @tbl TABLE (id INT IDENTITY PRIMARY key, [date] DATETIME, title VARCHAR(20), start_time DATETIME, end_time DATETIME);
INSERT INTO @tbl (date, title, start_time, end_time) VALUES
('2022-01-10T00:00:00', 'Coloring','2022-01-10T12:00:00','2022-01-10T13:00:00'),
('2021-12-28T00:00:00', 'Coloring','2021-12-27T15:20:00','2021-12-27T16:00:00'),
('2021-12-28T00:00:00', 'Coloring','2021-12-27T12:20:00','2021-12-27T14:00:00');
-- DDL and sample data population, end
SELECT * FROM @tbl;
SELECT CONCAT(
N'{',
STUFF(
(
SELECT CONCAT(N',"', CAST(k.[date]AS DATE), '":', c.[Json])
FROM @tbl AS k
CROSS APPLY (
SELECT [date], title, start_time, end_time
FROM @tbl
WHERE [date] = k.[date]
FOR JSON PATH
) c([Json])
GROUP BY [date], c.[Json]
ORDER BY [date] DESC
FOR XML PATH('')
), 1, 1, N''
),
N'}'
)
AS JsonOutput;
输出
{
"2022-01-10": [
{
"date": "2022-01-10T00:00:00",
"title": "Coloring",
"start_time": "2022-01-10T12:00:00",
"end_time": "2022-01-10T13:00:00"
}
],
"2021-12-28": [
{
"date": "2021-12-28T00:00:00",
"title": "Coloring",
"start_time": "2021-12-27T15:20:00",
"end_time": "2021-12-27T16:00:00"
},
{
"date": "2021-12-28T00:00:00",
"title": "Coloring",
"start_time": "2021-12-27T12:20:00",
"end_time": "2021-12-27T14:00:00"
}
]
}
在 SQL 服务器的现代版本中,您可以为此使用 STRING_AGG
,一次按日期聚合,然后再次聚合整个事件。
您还可以获得仅查询一次 table 的好处(APPLY
仅指回外部 table)。
Note that if you are using arbitrary text as the keys, you should use
STRING_ESCAPE
to escape them
SELECT
JsonOutput = N'{' + STRING_AGG(N'"' + CAST(t.date AS nvarchar(30)) + N'":' + t.[Json], N',') WITHIN GROUP (ORDER BY [date] DESC) + N'}'
FROM (
SELECT
date = CAST(t.date AS date),
Json = STRING_AGG(N'[' + c.Json + N']', ',') WITHIN GROUP (ORDER BY [date] DESC)
FROM @tbl t
CROSS APPLY (
SELECT t.date, t.title, t.start_time, t.end_time
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
) c(Json)
GROUP BY CAST(t.date AS date)
) t;
分组日table,按id排序,按日期字段的日期部分排序,日期部分作为字段头。每个字段的值是对应组的table个序列,然后我们将它们转化为JSON格式。 SQL 只能assemble 将JSON 字符串按指定格式手动。该声明冗长且难以阅读。一般的替代方法是从数据库中提取原始数据并在 Python 或 SPL 中对其进行处理。 SPL,open-source Java 包,更容易集成到 Java 程序中并生成简单的代码。它只用两行代码就完成了任务:
A | |
---|---|
1 | =MSSQL.query("select date,title,start_time,end_time from json order by id") |
2 | =json(transpose(A1.group@o(date(date)).run(~=[date(date)] |