edo*_*edo 0 sql-server aggregate date-math
我需要用 TS 聚合表的值的“总和”,每个半小时(60 分钟)的值列,即 00:30、01:30、02:30 等
样本数据:
Val TS
1 2019-08-12 00:00:00.013
3 2019-08-12 00:10:00.013
2 2019-08-12 00:20:00.013
2 2019-08-12 00:30:00.013
0 2019-08-12 00:40:00.013
0 2019-08-12 00:50:00.013
1 2019-08-12 01:00:00.013
7 2019-08-12 01:10:00.013
0 2019-08-12 01:20:00.013
1 2019-08-12 01:30:00.013
2 2019-08-12 01:40:00.013
0 2019-08-12 01:50:00.013
2 2019-08-12 02:00:00.013
0 2019-08-12 02:10:00.013
0 2019-08-12 02:20:00.013
0 2019-08-12 02:30:00.013
1 2019-08-12 02:40:00.013
0 2019-08-12 02:50:00.013
4 2019-08-12 03:00:00.013
3 2019-08-12 03:20:00.013
1 2019-08-12 03:30:00.013
Run Code Online (Sandbox Code Playgroud)
我们应该得到这个:
Val TS
10 2019-08-12 00:30:00
5 2019-08-12 01:30:00
8 2019-08-12 02:30:00
Run Code Online (Sandbox Code Playgroud)
有人可以就此提出建议吗?
谢谢,
鉴于数据:
CREATE TABLE #Demo
(
Val integer NOT NULL,
TS datetime2(3) NOT NULL
);
INSERT #Demo
(Val, TS)
VALUES
(1, '2019-08-12 00:00:00.013'),
(3, '2019-08-12 00:10:00.013'),
(2, '2019-08-12 00:20:00.013'),
(2, '2019-08-12 00:30:00.013'),
(0, '2019-08-12 00:40:00.013'),
(0, '2019-08-12 00:50:00.013'),
(1, '2019-08-12 01:00:00.013'),
(7, '2019-08-12 01:10:00.013'),
(0, '2019-08-12 01:20:00.013'),
(1, '2019-08-12 01:30:00.013'),
(2, '2019-08-12 01:40:00.013'),
(0, '2019-08-12 01:50:00.013'),
(2, '2019-08-12 02:00:00.013'),
(0, '2019-08-12 02:10:00.013'),
(0, '2019-08-12 02:20:00.013'),
(0, '2019-08-12 02:30:00.013'),
(1, '2019-08-12 02:40:00.013'),
(0, '2019-08-12 02:50:00.013'),
(4, '2019-08-12 03:00:00.013'),
(3, '2019-08-12 03:20:00.013'),
(1, '2019-08-12 03:30:00.013');
Run Code Online (Sandbox Code Playgroud)
一种方法是:
这显示在下面的代码中:
SELECT
TS = CONVERT(char(19), Timeslot.TS, 120),
Val = SUM(D.Val)
FROM #Demo AS D
CROSS JOIN (VALUES(CONVERT(datetime2(3), '20190101', 112))) AS Base(FixedDate)
CROSS APPLY(VALUES((DATEDIFF(MINUTE, Base.FixedDate, D.TS) + 30) / 60 * 60)) AS Slot(InMins)
CROSS APPLY(VALUES(DATEADD(MINUTE, Slot.InMins - 30, Base.FixedDate))) AS Timeslot(TS)
GROUP BY
Timeslot.TS
ORDER BY
Timeslot.TS;
Run Code Online (Sandbox Code Playgroud)
输出:
CREATE TABLE #Demo
(
Val integer NOT NULL,
TS datetime2(3) NOT NULL
);
INSERT #Demo
(Val, TS)
VALUES
(1, '2019-08-12 00:00:00.013'),
(3, '2019-08-12 00:10:00.013'),
(2, '2019-08-12 00:20:00.013'),
(2, '2019-08-12 00:30:00.013'),
(0, '2019-08-12 00:40:00.013'),
(0, '2019-08-12 00:50:00.013'),
(1, '2019-08-12 01:00:00.013'),
(7, '2019-08-12 01:10:00.013'),
(0, '2019-08-12 01:20:00.013'),
(1, '2019-08-12 01:30:00.013'),
(2, '2019-08-12 01:40:00.013'),
(0, '2019-08-12 01:50:00.013'),
(2, '2019-08-12 02:00:00.013'),
(0, '2019-08-12 02:10:00.013'),
(0, '2019-08-12 02:20:00.013'),
(0, '2019-08-12 02:30:00.013'),
(1, '2019-08-12 02:40:00.013'),
(0, '2019-08-12 02:50:00.013'),
(4, '2019-08-12 03:00:00.013'),
(3, '2019-08-12 03:20:00.013'),
(1, '2019-08-12 03:30:00.013');
Run Code Online (Sandbox Code Playgroud)
与问题中显示的输出相比,这会产生几个额外的时间段,但在我看来它仍然是正确的。
如果您更喜欢(有点慢)FORMAT功能,则以下等效:
SELECT
TS = Slot.TS,
Val = SUM(D.Val)
FROM #Demo AS D
CROSS APPLY
(
VALUES
(
-- Remove 30 minutes
DATEADD(MINUTE, -30,
CONVERT(datetime2(3),
FORMAT(
-- Add 30 minutes
DATEADD(MINUTE, 30, D.TS),
-- Truncate to hour
N'yyyy-MM-dd HH:00:00',
N'en-us'
), 120
)
)
)
) AS Slot (TS)
GROUP BY
Slot.TS
ORDER BY
Slot.TS;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
89 次 |
| 最近记录: |