我目前正在处理一些我有一个相当有趣的挑战的数据。
简介和问题:
所以我有很多时间序列数据,排列如下:
time | price
------------------------------
'2014-07-07 06:00:00' | 1100
'2014-07-07 07:00:00' | 900
我基本上对制作一个取决于当前时间的和函数感兴趣。应该是这样的,在13时,应该将6-12的价格相加。然后在16小时,应该加上6-12的总和,其中12-15的总和,如下所示:
time | price | sum function
------------------------------------
'2014-07-07 08:00:00' | 1000 | NULL
'2014-07-07 09:00:00' | 1200 | NULL
'2014-07-07 10:00:00' | 1300 | NULL
'2014-07-07 11:00:00' | 700 | NULL
'2014-07-07 12:00:00' | 800 | NULL
'2014-07-07 13:00:00' | 2000 | 6000
'2014-07-07 14:00:00' | 3500 | 6000
'2014-07-07 15:00:00' | 2500 | 6000
'2014-07-07 16:00:00' | 1000 | 14000
'2014-07-07 17:00:00' | 500 | 14000
这意味着假设时间是12:00:00,那么我想制作一个当时(和前进)从06:00-12:00过度价格值的功能。三个小时的步骤前进。我不确定解决这个问题的最佳方法我想到的是:
解决方案
创建一个函数,该函数接收当前时间和最后12小时的价格数据,并简单地生成逻辑并返回该函数。然后逻辑将如所讨论的那样。如果时间在00:00到12:00之间,则返回为NULL。
你有更好的建议吗?
系统:
MS SQL 2008 + MS Management Studi Express
问题:
如何制作一个根据时间汇总价格数据的功能?
更新
基于Kevins的回答(谢谢凯文)我最终使用了OUTER APPLY
并让它在这个简单的例子中工作。由于我没有表格而只有选择语句,因此将其调整为满量程仍然会导致我出现问题:
Select allValues.*, CASE WHEN DATEPART (HOUR, allValues.UTCHour) > 12 THEN bVal.lessThan12 ELSE 0
from
(**A VERY large select statment**) allValues
OUTER APPLY
(
SELECT
sum(CASE WHEN DATEPART (HOUR, allValues.UTCHour) <= 12 THEN allValues.Measurement ELSE 0 END) lessThan12
) bVal
不幸的是,这会返回错误消息:Msg 4101 Aggregates on the right side of an APPLY cannot reference columns from the left side.
答案 0 :(得分:1)
DECLARE @TimeSeries TABLE
(
SeriesTime DATETIME,
SeriesPrice INT
)
INSERT INTO @TimeSeries
( SeriesTime, SeriesPrice )
VALUES
('2014-07-07 06:00:00', 1100),
('2014-07-07 07:00:00', 900),
('2014-07-07 08:00:00', 1000),
('2014-07-07 09:00:00', 1200),
('2014-07-07 10:00:00', 1300),
('2014-07-07 11:00:00', 700),
('2014-07-07 12:00:00', 800),
('2014-07-07 13:00:00', 2000),
('2014-07-07 14:00:00', 3500),
('2014-07-07 15:00:00', 2500),
('2014-07-07 16:00:00', 1000),
('2014-07-07 17:00:00', 500);
SELECT
t.*,
CASE WHEN DATEPART(HOUR, t.SeriesTime) > 15 THEN e.LessThan15
WHEN DATEPART(HOUR, t.SeriesTime) > 12 THEN d.LessThan12 ELSE NULL END AS SumFunction
FROM @TimeSeries t
OUTER APPLY
(
SELECT
SUM(CASE WHEN DATEPART(HOUR, SeriesTime) <= 12 THEN SeriesPrice ELSE 0 END) LessThan12
FROM @TimeSeries
) d
OUTER APPLY
(
SELECT
SUM(CASE WHEN DATEPART(HOUR, SeriesTime) <= 15
THEN SeriesPrice ELSE 0 END) LessThan15
FROM @TimeSeries
) e
我有两个查询总和,然后我使用case语句根据小时拉第3列。在你的情况下,你得到了不同的结果但是当我总结从0到12pm的所有值时,我得到7000而不是6000,这就像你的结果是1000关(你的帖子可能是一个错字?)这里是我的输出:
SeriesTime SeriesPrice SumFunction
2014-07-07 06:00:00.000 1100 NULL
2014-07-07 07:00:00.000 900 NULL
2014-07-07 08:00:00.000 1000 NULL
2014-07-07 09:00:00.000 1200 NULL
2014-07-07 10:00:00.000 1300 NULL
2014-07-07 11:00:00.000 700 NULL
2014-07-07 12:00:00.000 800 NULL
2014-07-07 13:00:00.000 2000 7000
2014-07-07 14:00:00.000 3500 7000
2014-07-07 15:00:00.000 2500 7000
2014-07-07 16:00:00.000 1000 15000
2014-07-07 17:00:00.000 500 15000