0

私は今、しばらくの間苦労してきた問題を抱えています。誰かが私を助けてくれれば、それは素晴らしいことです。SQL Server 2012 上にあります。

一連のトランザクション数とユーザー ID を含むテーブルがあります。1 時間ごとに発生するすべてのトランザクションをカウントし、ユーザー ID でグループ化する必要があります。datepart(hh,1,SomeColumn) でグループ化することもできません。これは、16:00 ~ 16:59 に発生したトランザクションのみが取得されるためです。

したがって、発生した最初のトランザクション + 1 時間でグループ化する必要があり、その後に別の一連のトランザクションが発生した場合は、それによってもグループ化する必要があります。

例:

最初のトランザクションは 13:45 でした。13:45 から 14:45 までに発生したすべてのトランザクションの数が必要です。ユーザー ID ごとにグループ化されます。

次に、16:09 ~ 17:09 に発生したすべてのトランザクションの数を同じユーザー ID でグループ化する必要があります。

少し混乱している場合は申し訳ありません。

テーブル:

ユーザー | 取引時間

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

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

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

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

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

出力:

ユーザー | TransactionTimeStart | トランザクション時間終了 | 取引

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

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

4

2 に答える 2

0

または、再帰的な CTE ソリューション

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 
于 2016-08-10T09:30:01.800 に答える
0

このクエリを試してください(SQLサーバー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

結果 :

ここに画像の説明を入力

于 2016-08-10T08:25:26.807 に答える