SQL - 创建sum函数,它根据时间使用不同的时间间隔

时间:2014-07-14 14:50:23

标签: sql-server tsql datetime sum

我目前正在处理一些我有一个相当有趣的挑战的数据。

简介和问题:

所以我有很多时间序列数据,排列如下:

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.

1 个答案:

答案 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