2010-10-08 4 views
1

В каждый минутный интервал я хотел бы консолидировать значения в моей таблице SQL для сжатия пространства. Если у меня есть таблица со значениями, такими как:Consoldate Date Range Значения

UserId Value Date 
1  2  10/08/2010 10:30:00 
1  2  10/08/2010 10:30:10 
1  2  10/08/2010 10:30:20 
1  2  10/08/2010 10:30:30 
1  2  10/08/2010 10:30:40 
1  2  10/08/2010 10:30:50 
1  2  10/08/2010 10:31:00 
1  2  10/08/2010 10:31:10 
1  2  10/08/2010 10:31:20 
1  2  10/08/2010 10:31:30 
1  2  10/08/2010 10:31:40 
1  2  10/08/2010 10:31:50 

Каждую минуту я хотел бы сжать значения в одноминутные интервалы. Таким образом, верхний стол будет выглядеть так:

UserId Value Date 
1  12  10/08/2010 10:30:00 
1  12  10/08/2010 10:31:00 

... после того, как запрос был запущен. Предыдущие значения будут удалены и заменены новыми консолидированными значениями.

Как это сделать в TSQL?

+0

(1) Будете ли вы когда-либо вставлять записи, не связанные с предыдущей минутой, или просто нужно посмотреть на предыдущую минуту? (2) Зачем вообще вставлять все эти разные записи? Можете ли вы не просто использовать upsert с помощью слияния, поэтому он будет вставляться только в том случае, если в течение этой минуты нет записи и в противном случае она увеличивается? –

+0

Это для графического отображения значений. При просмотре живой диаграммы значения разбиваются на 10 секундных интервалов. После того, как минута закончилась, значения консолидируются. Через час протоколы объединяются и т. Д. –

ответ

2
With RawData As 
    (
    Select 1 As UserId, 2 As Value, Cast('10/08/2010 10:30:00' As datetime) As [Date] 
    Union All Select 1, 2, '10/08/2010 10:30:10' 
    Union All Select 1, 2, '10/08/2010 10:30:20' 
    Union All Select 1, 2, '10/08/2010 10:30:30' 
    Union All Select 1, 2, '10/08/2010 10:30:40' 
    Union All Select 1, 2, '10/08/2010 10:30:50' 
    Union All Select 1, 2, '10/08/2010 10:31:00' 
    Union All Select 1, 2, '10/08/2010 10:31:10' 
    Union All Select 1, 2, '10/08/2010 10:31:20' 
    Union All Select 1, 2, '10/08/2010 10:31:30' 
    Union All Select 1, 2, '10/08/2010 10:31:40' 
    Union All Select 1, 2, '10/08/2010 10:31:50' 
    ) 
Select UserId, Value, DateAdd(s, -DatePart(s, [Date]), [Date]) 
From RawData 
Group By UserId, Value, DateAdd(s, -DatePart(s, [Date]), [Date]) 
0

Предполагая таблицу с именем Test, следующий скрипт должен работать.

BEGIN TRANSACTION 

UPDATE Test 
SET Test.Value = T2.Value 
FROM Test 
INNER JOIN (
    SELECT UserId, SUM([Value]) as [Value], 
     convert(nvarchar(25), [Date], 100) as [Date] 
    FROM Test 
    GROUP BY UserId, convert(nvarchar(25), [Date], 100) 
) T2 ON Test.UserId = T2.UserId AND Test.[Date] = T2.[Date] 
INNER JOIN (
    SELECT UserId, COUNT([Value]) as ValueCount, 
     convert(nvarchar(25), [Date], 100) as [Date] 
    FROM Test 
    GROUP BY UserId, convert(nvarchar(25), [Date], 100) 
) T3 ON Test.UserId = T3.UserId AND Test.[Date] = T3.[Date] AND ValueCount > 1 

DELETE 
FROM Test 
WHERE datepart(ss, [Date]) <> 0 

COMMIT TRANSACTION 

Путь скрипт работает в том, что в рамках транзакции, он обновляет значение времени «00» путем суммирования всех значений этой минуты, если есть по крайней мере две записи для этого минутного интервала (т.е. 00 секунд, 10 секунд), так что ненужные обновления не выполняются.

Затем запрос удаляет все записи, которые не имеют «00» в течение нескольких секунд, так как все они будут включены в обновление выше.