съединете само един ред от много възможни редове

имам нужда от помощ с едно запитване.

Подробности: Имам 5 милиона събития с ID и EventID и един начален час [datetime].
ID-EventID не са уникални ключове и могат да се случват няколко пъти на ден.
За всеки ред може да нямам съвпадения, едно съвпадение или дори 10 000 съвпадащи [datetime] крайни часове в рамките на следващите 5 дни.

Това, от което се нуждая, е само едно крайно време, което е най-близо до началното време.

Самата заявка е сравнително проста, но поради факта, че имам няколко милиона събития, като всяко от тях има 10 000 възможни посещения, когато имам нужда само от едно попадение. Става в милиарди и вече не работи добре.

Написах набор от примерни данни, включително примерен резултат. (виж по-долу)

Това, от което се нуждая, е заявка, която включва само един съответстващ ред и оставя останалите сами.

CREATE TABLE #starts(
    [id] [smallint] NULL,
    [event_id] [nvarchar](50) NULL,
    [dt_start] [datetime] NULL
)

INSERT #starts ([id], [event_id], [dt_start]) VALUES (2, N'alpha', CAST(N'2015-05-01 23:06:22.000' AS DateTime))
INSERT #starts ([id], [event_id], [dt_start]) VALUES (2, N'alpha', CAST(N'2015-05-10 23:42:01.000' AS DateTime))
INSERT #starts ([id], [event_id], [dt_start]) VALUES (2, N'alpha', CAST(N'2015-05-28 02:36:44.000' AS DateTime))
INSERT #starts ([id], [event_id], [dt_start]) VALUES (2, N'alpha', CAST(N'2015-05-29 08:56:17.000' AS DateTime))

CREATE TABLE #ends(
    [id] [smallint] NULL,
    [event_id] [nvarchar](50) NULL,
    [dt_end] [datetime] NULL
)


INSERT #ends ([id], [event_id], [dt_end]) VALUES (2, N'alpha', CAST(N'2015-05-01 23:09:32.000' AS DateTime))
INSERT #ends ([id], [event_id], [dt_end]) VALUES (2, N'alpha', CAST(N'2015-05-28 02:40:14.000' AS DateTime))
INSERT #ends ([id], [event_id], [dt_end]) VALUES (2, N'alpha', CAST(N'2015-05-28 08:57:39.000' AS DateTime))
INSERT #ends ([id], [event_id], [dt_end]) VALUES (2, N'alpha', CAST(N'2015-05-28 14:09:39.000' AS DateTime))
INSERT #ends ([id], [event_id], [dt_end]) VALUES (2, N'alpha', CAST(N'2015-06-01 10:18:18.000' AS DateTime))
INSERT #ends ([id], [event_id], [dt_end]) VALUES (2, N'alpha', CAST(N'2015-06-01 14:42:04.000' AS DateTime))
GO

-- one extra step to clarify
select a.id, a.event_id,dt_start, dt_end 
,row_number() over (partition by a.id, a.event_id,dt_start order by dt_end) as rn
from #starts as a
left join #ends as b
on a.id=b.id
and a.event_id=b.event_id
AND a.dt_start<b.dt_end
and datediff(day,dt_start,dt_end) <=5

-- the result
select * from (
select a.id, a.event_id,dt_start, dt_end 
,row_number() over (partition by a.id, a.event_id,dt_start order by dt_end) as rn
from #starts as a
left join #ends as b
on a.id=b.id
and a.event_id=b.event_id
AND a.dt_start<b.dt_end
and datediff(day,dt_start,dt_end) <=5
) as dummy
where rn=1

Благодаря за всяка помощ, която може да имате.


person Metanormal    schedule 12.08.2015    source източник
comment
Има ли някакъв шанс да вземете подмостра от масивната маса?   -  person Tim Biegeleisen    schedule 12.08.2015
comment
Искаш да кажеш като вмъкване с 5000 съвпадащи крайни времена? Ако е така: да, бих могъл да генерирам такава проба, но какво ще помогне и мога ли да добавя няколко хиляди реда sql-код тук?   -  person Metanormal    schedule 12.08.2015
comment
Ако изпълните допълнителната стъпка, ще видите номерирането на съответстващите редове. В реалната маса тези числа лесно надхвърлят хиляди за повечето събития, без изобщо да са необходими. Имам нужда от начин да се присъединя само към номер #1 и да изхвърля останалите от самото начало.   -  person Metanormal    schedule 12.08.2015


Отговори (1)


person    schedule
comment
Здравей фризби, благодаря ти много. Толкова е очевидно. Явно съм се забил в алгоритъма си. Това работи доста добре. Но тъй като понякога се случват няколко хиляди крайни събития в рамките на един час, трябваше да прегледам датата. Първо търсене от 1 минута, от 30 минути, от 5 дни. Така или иначе. Сега работи за по-малко от 10 минути вместо за няколко часа. Благодаря отново. - person Metanormal; 13.08.2015