Эффективно найти следующее событие в SQL - PullRequest
1 голос
/ 20 июля 2011

Основная суть моей проблемы заключается в том, что для каждого события A мне нужно найти самое раннее следующее событие B, связанное с тем же пользователем. В настоящее время у меня есть:

SELECT e.UserID, e.date, min(e2.date) 
FROM Event e INNER JOIN 
    Event e2 ON e.UserID = e2.UserID AND e.date <= e2.date
WHERE e.Event LIKE 'A' AND e2.Event LIKE 'B'

Однако, для каждого события A (которое может произойти для пользователя любое количество раз), происходит множество событий B, поэтому внутреннее объединение создает множество дополнительных строк, которые затем необходимо прополотить в функции min. Есть ли более эффективный / быстрый способ сделать это?

(сервер MSSQL Server 2008)

UPDATE: Будет ли это быстрее с Rank ()?

Select UserID, date, date2 
from (
    Select e.UserID, e.date, e2.date as date2, rank() OVER (PARTITION BY e.date, e.UserID ORDER BY e2.date) as rank
    FROM Event e INNER JOIN Event e2 on e.UserID = e2.UserID
    WHERE e.Event = 'A' and e2.Event = 'B' and e.date <= e2.date
)
WHERE rank = 1

Или оптимизация выведет их к практически эквивалентным?

Ответы [ 2 ]

0 голосов
/ 20 июля 2011

Быстрее присоединиться в третий раз, вот так? Наверное, нет, но, возможно, стоит попробовать. Здесь любые данные, возвращаемые в таблицу "e3", представляют даты между датой e и датой e2. Таким образом, мы оставили соединение с этим и захватили значения NULL.

SELECT e.UserID, e.date, e2.date 
FROM Event e 
INNER JOIN Event e2 ON (e.UserID = e2.UserID AND e.date <= e2.date)
 LEFT JOIN Event e3 ON (e.UserID = e3.UserID AND e.date <= e3.date AND e3.date <= e2.date AND e3.Event = 'B')
WHERE e.Event = 'A' AND e2.Event = 'B'
AND e3.date IS NULL

Я думаю, что это, вероятно, использует ту же стратегию, что и ваш MIN запрос, но, возможно, нет? Мне любопытно узнать в любом случае.

0 голосов
/ 20 июля 2011

Единственный известный мне более быстрый способ сделать это - обработать каждое событие A в цикле и найти первое событие B, используя отдельный запрос, который использует TOP и ORDER BY, что позволяет ему найти ответ в подходящеминдекс.Это может быть сделано в хранимой процедуре для максимальной эффективности.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...