2016-08-10 4 views
0

У меня есть проблема, с которой я боролся некоторое время. Если кто-то может мне помочь, это было бы здорово. Это на SQL Server 2012.Получите транзакции в течение часа друг от друга (не по часам)

У меня есть таблица с определенным количеством операций и идентификатора пользователя в. мне нужно подсчитать все транзакции, которые находятся в часе друг друг и группы по идентификатору пользователя. Он не может быть сгруппирован по датеpart (hh, 1, SomeColumn), потому что тогда он будет принимать транзакции, которые произошли в 16:00 - 16:59.

Поэтому мне нужно сгруппировать его по первой транзакции, которая произошла + 1 час, а затем, если другой пакет транзакций произошел позже, мне также нужно сгруппировать его.

Пример:

Первая сделка была 13:45 - мне нужен подсчет всех сделок, которые произошли с 13:45 - 14:45. Сгруппирован по идентификатору пользователя.

Тогда мне нужно иметь счет всех транзакций, которые произошли в 16:09 - 17:09, сгруппированных по тому же идентификатору пользователя.

Приносим извинения, если он немного запутан.

Таблица:

Пользователь | TransactionTime

0125 | 03/06/2016 12:24:01

0125 | 03/06/2016 12:34:06

0125 | 03/06/2016 13:22:02

0125 | 03/06/2016 16:24:10

0125 | 03/06/2016 17:10:08

Выход:

Пользователь | TransactionTimeStart | TransactionTimeEnd | Сделки

0125 | 03/06/2016 12:24:01 | 03/06/2016 13:22:02 | 3

0125 | 03/06/2016 16:24:10 | 03/06/2016 17:10:08 | 2

+0

Просьба представить некоторые данные образца и ожидаемый вывод – TheGameiswar

+0

Не знаю, как добавить формат таблицы - старался изо всех сил, но –

+0

Возможно, вам стоит подумать о том, чтобы разбить время на другую временную таблицу или переменную таблицы.Вы можете использовать таблицу таблиц или цикл для создания списка дат, используя первую запись в качестве драйвера и просто присоединяйся к этому. Вы также можете достичь этого, используя cte – Charleh

ответ

0

Попробуйте этот запрос (я тест на SQL Server 2012)

CREATE TABLE #tmp (usr INT,TransactionTime DATETIME) 
CREATE TABLE #result (startTime DATETIME , endTime DATETIME) 

INSERT INTO #tmp VALUES 
    (0125,'03/06/2016 12:24:01'),(0125,'03/06/2016 12:34:06') 
    ,(0125,'03/06/2016 13:22:02'),(0125,'03/06/2016 16:24:10') 
    ,(0125,'03/06/2016 17:10:08') 

DECLARE @minTime DATETIME = (SELECT MIN(TransactionTime) FROM #tmp) 
DECLARE @maxTime DATETIME = (SELECT MAX(TransactionTime) FROM #tmp) 

DECLARE @tmp DATETIME = @minTime 

WHILE @tmp < @maxTime 
BEGIN 
    IF @tmp > @maxTime 
     INSERT INTO #result VALUES (@tmp, DATEADD(HOUR,1,@maxTime)) 
    ELSE 
     INSERT INTO #result VALUES (@tmp, DATEADD(HOUR,1,@tmp)) 
    SET @tmp = DATEADD(HOUR,1,@tmp) 
END 

SELECT DISTINCT t.usr 
    ,r.startTime 
    ,r.endTime 
    ,COUNT(1) OVER (PARTITION BY r.startTime,r.endTime,t.usr) AS [cnt] 
FROM #result r 
LEFT JOIN #tmp t ON t.TransactionTime BETWEEN r.startTime AND r.endTime 
WHERE t.usr IS NOT NULL 


DROP TABLE #tmp 
DROP TABLE #result 

Результат:

enter image description here

+0

. Я вижу, что вы там делали, но он по-прежнему использует статический час. Используемая часовая дисперсия должна быть динамической для первого времени транзакции. Спасибо, но –

+0

Извините, я не учитывал дату с моими результатами. Большое спасибо, он работает !!!!! :) –

0

Альтернативно, рекурсивного решения КТР

with dat as (
    -- sample data 
    select * from (
     values 
      (0125,cast('20160306 12:24:01' as datetime)) 
      ,(0125,cast('20160306 12:34:06' as datetime)) 
      ,(0125,cast('20160306 13:22:02' as datetime)) 
      ,(0125,cast('20160306 16:24:10' as datetime)) 
      ,(0125,cast('20160306 17:10:08' as datetime)) 
      ,(0125,cast('20160306 18:24:10' as datetime)) 
      ,(0125,cast('20160306 19:10:08' as datetime)) 
     )t([User],TransactionTime) 
), hdrs as (
    select [User], TransactionTime= min(TransactionTime), rn = cast(0 as bigint) 
    from dat 
    group by [User] 
    union all 
    select dat.[User], dat.TransactionTime 
     , rn = hdrs.rn + row_number() over(partition by hdrs.[user], hdrs.TransactionTime order by dat.TransactionTime) - 1 
    from dat 
    join hdrs on dat.[User]= hdrs.[User] and 
    dat.TransactionTime > dateadd(HOUR,1,hdrs.TransactionTime)  
) 
select hdrs.[User],hdrs.TransactionTime, n = count(*) 
from hdrs 
join dat on rn = 0 and dat.TransactionTime between hdrs.TransactionTime and dateadd(HOUR,1,hdrs.TransactionTime) 
group by hdrs.[User],hdrs.TransactionTime 

 Смежные вопросы

  • Нет связанных вопросов^_^