2015-09-08 2 views
1

У меня есть следующая таблицабыстрый способ расчета периодов времени средневзвешенное в SQL Server

timestamp     parameter  value 
    --------------------------------------------------- 
    2015-09-04 10:00:00.000 par01   1 
    2015-09-04 10:03:00.000 par02   2 
    2015-09-04 10:06:00.000 par03   3 
    2015-09-04 10:09:00.000 par04   4 
    2015-09-04 10:12:00.000 par05   5 
    2015-09-04 10:15:00.000 par06   6 
    2015-09-04 10:18:00.000 par01   7 
    2015-09-04 10:21:00.000 par02   8 
    2015-09-04 10:24:00.000 par03   9 
    2015-09-04 10:27:00.000 par04   10 

Я хотел бы вычислить средневзвешенные каждые 15 минут. Результат должен быть таким:

timestamp     parameter  value 
    --------------------------------------------------- 
    2015-09-04 10:00:00.000 result1  3 
    2015-09-04 10:15:00.000 result2  8 

Какой самый быстрый способ? Возможно ли избежать циклов?

+0

случае, когда минутная часть между 0 и 14, когда ... конец – jarlh

+1

В какой колонке содержится вес? –

+0

График времени – JosepB

ответ

2

Это даст вам результат вы запрашиваете:

DECLARE @t table(timestamp datetime, parameter char(5), value int) 

INSERT @t values 
('2015-09-04 10:00:00.000','par01',1), 
('2015-09-04 10:03:00.000','par02',2), 
('2015-09-04 10:06:00.000','par03',3), 
('2015-09-04 10:09:00.000','par04',4), 
('2015-09-04 10:12:00.000','par05',5), 
('2015-09-04 10:15:00.000','par06',6), 
('2015-09-04 10:18:00.000','par01',7), 
('2015-09-04 10:21:00.000','par02',8), 
('2015-09-04 10:24:00.000','par03',9), 
('2015-09-04 10:27:00.000','par04',10) 

SELECT 
    dateadd(minute, datediff(minute, 0,timestamp)/15*15, 0) timestamp, 
    'Result' + cast(row_number() over (order by datediff(minute, 0,timestamp)/15) 
    as varchar(10)) parameter, 
    avg(value) value 
FROM @t 
GROUP BY datediff(minute, 0,timestamp)/15 

Результат:

timestamp   parameter value 
2015-09-04 10:00 Result1 3 
2015-09-04 10:15 Result2 8 

EDIT - это метод расчета средневзвешенного значения. Был опыт обучения для меня:

;WITH CTE as 
(
    SELECT 
    cast(coalesce(lead(timestamp) over (order by timestamp), 
     dateadd(minute, datediff(minute, 0,timestamp)/15*15, '00:15')) 
     - timestamp as float)*24*60/15*value x, 
    dateadd(minute, datediff(minute, 0,timestamp)/15*15, 0) truncatedtime 
FROM @t 
) 
SELECT 
    sum(x) weighted_average, 
    truncatedtime 
FROM 
    cte 
GROUP BY 
    truncatedtime 
+0

Результатом этой формулы является Average. Я хотел бы средневзвешенное по времени. – JosepB

+0

@JosepBacardit средневзвешенный без описания веса просто средний –

+0

Я вижу небольшую ошибку в моих расчетах, пытаясь исправить ее –

2

попробовать это:

SELECT MIN(timestamp) as timestamp, 
     'result' + cast(count(*) over(order by min(timestamp)) as varchar(10)) as parameter,  
     AVG(value) as value 
FROM tbl 
GROUP BY CAST(timestamp as Date), 
     DATEPART(Hour, timestamp), 
     DATEPART(Minute, timestamp)/15 

see fiddle here

+1

Хотел бы добавить +1 из-за красоты простоты, но поскольку запрос только группируется в минутах каждого часа, это даст неверные результаты, когда метка времени будет распределена в течение нескольких часов. Возможно, немного неортодоксально, но что-то вроде группировки на 'датиффе (минута, метка времени, '20000101')/15'? –

+1

@ Me.Name: Хорошая добыча! самое простое решение, о котором я мог думать, находится в моем отредактированном ответе. –

+0

Синтаксис по-прежнему недействителен. Вы не можете использовать порядок по min (timestanp). Более простая * группа * может быть найдена в моем ответе –

2

Попробуйте это:

CREATE TABLE #t1 
(
    [Timestamp] datetime, 
    Parameter VARCHAR(50), 
    Value int 
) 

INSERT INTO #t1 
VALUES ('2015-09-04 10:00:00.000', 'par01',1), 
    ('2015-09-04 10:03:00.000', 'par02',2), 
    ('2015-09-04 10:06:00.000', 'par03',3), 
    ('2015-09-04 10:09:00.000', 'par04',4), 
    ('2015-09-04 10:12:00.000', 'par05',5), 
    ('2015-09-04 10:15:00.000', 'par06',6), 
    ('2015-09-04 10:18:00.000', 'par01',7), 
    ('2015-09-04 10:21:00.000', 'par02',8), 
    ('2015-09-04 10:24:00.000', 'par03',9), 
    ('2015-09-04 10:27:00.000', 'par04',10) 


;WITH CTE 
As 
(
    SELECT 
      DATEADD(minute, 
        (DATEDIFF(minute, CONVERT(char(8),[Timestamp],112), [Timestamp])/15) * 15, 
        CONVERT(char(8),[Timestamp],112)) as Timestamp_truncated, 
      [Timestamp], 
      parameter, 
      value 
    FROM #t1 
) 
SELECT Timestamp_truncated AS [Timestamp], AVG(Value) as Value 
FROM CTE 
GROUP BY Timestamp_truncated 
Смежные вопросы