У меня есть таблица действий пользователя, у каждого из которых есть связанный пользователь, тип и временная метка.Вот упрощенный пример:
TABLE USER_ACTIONS
------------------------
USER | TYPE | TIMESTAMP
------------------------
a | OPEN | 0
b | OPEN | 1
a | CLOSE | 2
a | OPEN | 3
b | CLOSE | 4
a | CLOSE | 4
a | OPEN | 5 <-- "orphaned" OPEN, with no corresponding CLOSE. Should be ignored.
c | OPEN | 3
c | CLOSE | 5
a | OPEN | 6
a | CLOSE | 8
Я хотел бы получить список времени транзакций из этого.Каждое ЗАКРЫТИЕ должно соответствовать предыдущему ОТКРЫТОМУ для конкретного пользователя.
Результаты, которые я хотел бы получить, будут выглядеть примерно так:
USER | TRANSACTION_TIME
-----------------------
a | 2
b | 3
a | 1
c | 2
a | 2
Меня не волнует порядок.
Я знаю, что это можно сделать программно, но возможно ли это сделать с каким-нибудь умным SQL?
ОБНОВЛЕНИЕ:
Чтобы сделать это программнообщая идея заключается в том, чтобы ...
- Выбрать все действия "ЗАКРЫТЬ", упорядочив по убыванию TIMESTAMP.
- Для каждого из тех, кто в этом списке, попробуйте найтипредыдущее действие «OPEN», выполненное тем же пользователем.Ограничьте значение TIMESTAMP до действия «ЗАКРЫТЬ» TIMESTAMP, сортируйте результаты по TIMESTAMP DESC и ограничьте их значением 1.
- Для этой пары рассчитайте разницу во времени и выведите результат.
Вот некоторый псевдокод, но на самом деле я хотел бы, чтобы SQL делал это умно:
for each CLOSE_ACTION IN ("SELECT USER, TYPE, TIMESTAMP FROM USER_ACTIONS WHERE TYPE='CLOSE' ORDER BY TIMESTAMP DESC;") {
OPEN_ACTION = "SELECT USER, TYPE, TIMESTAMP FROM USER_ACTIONS
WHERE TYPE='OPEN'
AND USER='<CLOSE_ACTION.USER>'
AND TIMESTAMP='<CLOSE_ACTION.TIMESTAMP>'
ORDER BY TIMESTAMP DESC
LIMIT 1";
if OPEN_ACTION != empty/null then {
print CLOSE_ACTION.USER, CLOSE_ACTION.TIMESTAMP - OPEN_ACTION.TIMESTAMP;
}
}