与另一张表的条件不同的总和

时间:2019-09-16 09:15:34

标签: sql sql-server

有一个timeRanges表,类似于

+---+------------------+------------------+
|   | FromTime         | ToTime.          |
+---+------------------+------------------+
| 1 | 06:00:00.0000000 | 08:00:00.0000000 |
| 2 | 08:00:00.0000000 | 09:00:00.0000000 |
| 3 | 09:00:00.0000000 | 17:00:00.0000000 |
| 4 | 17:00:00.0000000 | 20:00:00.0000000 |
+---+------------------+------------------+

此外,以下是一些原始数据

+---+-------------------------+-------+--------+
|   | Time                    | Value | Member |
+---+-------------------------+-------+--------+
| 1 | 2019-10-11 06:18:29.000 | 10000 | 000001 |
| 2 | 2019-10-11 07:10:10.000 | 20000 | 000001 |
| 3 | 2019-10-12 08:30:20.000 | 30000 | 000002 |
| 4 | 2019-10-12 15:16:29.000 | 50000 | 000001 |
| 5 | 2019-11-13 18:00:29.000 | 70000 | 000002 |
| 6 | 2019-11-13 19:18:29.000 | 60000 | 000002 |
+---+-------------------------+-------+--------+

我试图每天汇总不同时间范围内的多个数据。  第1行和第2行在06:00〜08:00,需要一起计算。

我期望的结果:

+---+-------------------------+-------+--------+
|   | Time                    | Value | Member |
+---+-------------------------+-------+--------+
| 1 | 2019-10-11 06:00:00.000 | 30000 | 000001 |
| 2 | 2019-10-12 08:00:00.000 | 30000 | 000002 |
| 3 | 2019-10-12 09:00:00.000 | 50000 | 000001 |
| 4 | 2019-11-13 17:00:00.000 | 130000| 000002 |
+---+-------------------------+-------+--------+

有人可以给我一个关键词吗?我曾尝试使用partition by,但我想注意它。

已更新: 我想通过时间绑定将原始数据放入结果中。

2 个答案:

答案 0 :(得分:1)

以下似乎有效。我已经在最终结果中保留了日期和时间,但是如果您需要完全匹配最终要求,将它们组合起来应该不太困难。

With TimeRanges AS
(
SELECT ID
, CAST(FromTime AS TIME(0)) AS FromTime
, CAST(ToTime AS TIME(0)) AS ToTime
FROM (VALUES 
 ( 1,  '06:00:00.0000000' , '08:00:00.0000000' )
,( 2,  '08:00:00.0000000' , '09:00:00.0000000' )
,( 3,  '09:00:00.0000000' , '17:00:00.0000000' )
,( 4,  '17:00:00.0000000' , '20:00:00.0000000' )) AS T(ID,FromTime,ToTime)
),
RawData AS
(
SELECT ID,CAST(Time as datetime2(0)) AS Time,Value,Member
FROM (VALUES
 ( 1 , '2019-10-11 06:18:29.000',10000,'000001' )
,( 2 , '2019-10-11 07:10:10.000',20000,'000001' )
,( 3 , '2019-10-12 08:30:20.000',30000,'000002' )
,( 4 , '2019-10-12 15:16:29.000',50000,'000001' )
,( 5 , '2019-11-13 18:00:29.000',70000,'000002' )
,( 6 , '2019-11-13 19:18:29.000',60000,'000002' )
) AS V(ID,Time,Value,Member)
)
SELECT 
CAST(RD.Time as date) AS DataDate
,TR.FromTime
,SUM(RD.Value) AS Value
,RD.Member
FROM RawData AS RD
INNER JOIN TimeRanges AS TR
    ON CAST(RD.Time as time(0)) between TR.FromTime and TR.ToTime
GROUP BY
CAST(RD.Time as date)
,TR.FromTime
,RD.Member

答案 1 :(得分:1)

内部加入是您的朋友在这里

SELECT ranges.FromTime,
       ranges.ToTime,
       sum(raw.value),
       raw.member
FROM timeRanges ranges
INNER JOIN raw
           ON convert(time, raw.time) between ranges.FromTime and ranges.ToTime
GROUP BY raw.member,
         ranges.fromtime,
         ranges.totime

示例:

http://sqlfiddle.com/#!18/0b3d6/5