Итак, у меня есть таблица, в которой регистрируются пользователи, использующие определенные приложения. Он имеет поля ниже
id
time
app
user
server
type (can be IN or OUT)
Таким образом, пользователь начинает использовать определенное приложение, и когда он получает право на использование приложения, в журнал заносится строка, а для столбца типа устанавливается значение «OUT».
Точно так же, когда они перестают использовать приложение, регистрируется еще одна строка, и теперь для столбца типа устанавливается значение «IN».
Поэтому мне нужно создать таблицу сеансов, которая показывает время между использованием приложения определенным пользователем и сервером до тех пор, пока пользователь не перестанет его использовать.
Итак, я сделал следующий запрос, выполняя самосоединение таблицы
SELECT A.time as OutTime, B.time as InTime, A.app,
A.username, A.requestserver
FROM logs A, logs B
WHERE A.app = B.app
AND A.username = B.username
AND A.requestserver = B.requestserver
AND A.type = 'OUT'
AND B.type = 'IN'
AND A.time < B.time
Я не уверен, что логика этого на 100% верна. Что, если есть случай, когда один и тот же пользователь с одного сервера имеет, например, два сеанса:
ВЫХОД (1) -> 10:00
В (1) -> 13:00
ВЫХОД (2) -> 15:00
ВХОД (2) -> 19:00
Теперь с моей логикой есть шанс, что я могу просто создать сеанс с 10:00 до 19:00, что неверно. Как бы я поступил по этому поводу?
@wildplasser я имею в виду порядок добавления строк в таблицу
Я бы сделал это с помощью оконных функций вместо самосоединения. Вы можете установить в окне только строки перед текущей строкой, а также установить максимальную длину сеанса из соображений производительности, если это представляет интерес.
Предполагая, что ваше поле time
представляет собой полную временную метку, а не только время суток:
with sessionized as (
select
*,
last_value(
case when type = 'IN' then time end
ignore nulls
) over (
partition by username, app, requestserver
order by time asc
rows between unbounded preceding and current row
) as session_start
from logs
)
select *
from sessionized
where type = 'OUT'
Какой
order
?ORDER
нет! Кстати: вместо этого вы можете (должны!) использовать оператор соединения.