1

イベントを記録するテーブルがあります:

create table #events
(  intRowId int identity(1,1),
   intItemId int,
   intUserId int,
   datEvent datetime)

これは、数百万行の大きなテーブルであり、数千のアイテムと数万のユーザーに対するイベントを記録します。

探したい 10 個の itemID の選択グループがありますが、それらが特定のパターンで発生した場合のみです。これらの 10 個すべてのアイテムに、同じユーザー ID に対して登録されたイベントがあり、時間的に近い行を見つけようとしています。 、5分と言います。

どうすればいいのか、私にはまったくわかりません。パーティショニングがどこかに関係していると思われるかもしれませんが、どこかで始めるだけでも助けていただければ幸いです。

乾杯、マット

4

2 に答える 2

0

わかりましたので、以下に、必要なことを実行する実際の例を示します。イベントは 10 単位で表示される必要はないと想定しています。

しかし、ソリューションは非常に粗雑であり、特にアイテム/ユーザーの数を増やすと、実行が遅くなります。とにかく、これについて私にあまり反対票を投じないでください。適切な解決策が見つかることを願っています:)。

事前に選択されたイベントを含む一時テーブルは、私のソリューションのパフォーマンスに役立ちますが、本当に必要なのは Oracle のようなウィンドウ関数です..

DROP TABLE #events
GO

create table #events
(  intRowId int identity(1,1),
   intItemId int,
   intUserId int,
   datEvent datetime)
 GO 

insert into #events (intUserId,intItemId,  datEvent)
select '1','1','2013-05-01 10:25' union all --group1
select '1','2','2013-05-01 10:25' union all --group1
select '1','3','2013-05-01 10:26' union all --group1
select '1','7','2013-05-01 10:25' union all
select '1','8','2013-05-01 10:25' union all
select '1','9','2013-05-01 10:26' union all
select '1','1','2013-05-01 10:50' union all --group2
select '1','2','2013-05-01 10:52' union all --group2
select '1','3','2013-05-01 10:59' union all 
select '1','1','2013-05-01 11:10' union all --group3
select '1','1','2013-05-01 11:12' union all --group3
select '1','3','2013-05-01 11:17' union all --group3
select '1','2','2013-05-01 11:25' union all
select '1','1','2013-05-01 11:31' union all
select '1','7','2013-05-01 11:32' union all
select '1','2','2013-05-01 11:50' union all --group4
select '1','2','2013-05-01 11:50' union all --group4
select '1','3','2013-05-01 11:50' union all --group4
select '1','1','2013-05-01 11:56'
GO 

DROP TABLE #temp
GO
select 
     e1.intRowId as intRowId_1, e1.intItemId as intItemId_1, e1.intUserId as intUserId_1, e1.datEvent as datEvent_1
    ,e2.intRowId as intRowId_2, e2.intItemId as intItemId_2, e2.intUserId as intUserId_2, e2.datEvent as datEvent_2
into #temp
from #events e1
join #events e2
    on e1.intUserId=e2.intUserId
    and e1.datEvent<=e2.datEvent
    and e1.intRowId<>e2.intRowId
where 1=1
    and e1.intUserId=1
    and e2.intUserId=1
    and e1.intItemId in (1,2,3)
    and e2.intItemId in (1,2,3)
    and datediff(minute,e1.datevent,e2.datevent)<6
order by 
    e1.intRowId, e2.intRowId
GO

select distinct
    * 
from (
    select 
        intRowId_1 as intRowId, intItemId_1 as intItemId, intUserId_1 as intUserId, datEvent_1 as datEvent
    from #temp

    UNION ALL

    select 
        intRowId_2 as intRowId, intItemId_2 as intItemId, intUserId_2 as intUserId, datEvent_2 as datEvent
    from #temp
) x
order by 
    datEvent, intRowId
于 2013-05-21T14:56:16.063 に答える