Существует несколько способов решения этой проблемы.
Прежде всего, я должен сказать, что не могу дать вам полного решения этой проблемы.Количество входов в систему очень просто, но для продолжительности входа в систему каждого пользователя мне потребуется дополнительная информация.Исходя из имеющихся данных, неясно, какая из дат означает время выхода из системы .Если предположить, что это последнее появление «Некоторого действия» перед новым входом в систему, решение будет возможным, но я не знаю, верно ли это предположение или нет.Если пользователь открывает несколько сеансов параллельно, это предположение будет нарушено, а также, если время выхода из системы не будет записано (например, когда время сеанса истекает после некоторой точки, а время не сохраняется), вы не сможете сделать многое.
В любом случае, я хочу сделать три замечания:
- Общий аргумент запросов на основе множеств по сравнению с курсорами
- Рекомендуемый запрос для количества логинов
- Советы о том, как действовать в течение времени входа в систему
Первый пункт: вы предлагаете использовать курсоры и хранимую процедуру для определения количества входов в систему.Это решение будет работать, но, как правило, вы будете действовать на обычном языке программирования, таком как, например, C или Pascal: определите цикл for для данных и выполните расчет или процедуру для каждой строки.В SQL обычно желательно думать иначе.Используйте курсоры и циклы только тогда, когда это действительно необходимо, а в противном случае используйте решение на основе множеств.Причина в том, что запросы на основе множеств проще оптимизировать для интерпретатора SQL.Этот аргумент убедительно сделан в нескольких статьях в других местах, например, здесь: Почему запросы на основе реляционных множеств лучше курсоров?
Так как же действовать на основе множеств?Начиная с количества логинов, вы можете сделать что-то вроде:
SELECT user, COUNT(*)
FROM YourTable
WHERE Action = 'Login'
GROUP BY user
Это вернет количество логинов на пользователя.Если вы хотите количество входов в систему за определенный период времени, вы можете добавить критерий даты в поле WHERE
, и если вы хотите, например,.количество входов в систему на клиента или в день, вам нужно добавить поле Client
или CAST(Date) AS DATE
в оба предложения SELECT
и GROUP BY
.
Наконец, о продолжительности входа в систему, ваш вопрос , как рассчитать разницу во времени между двумя последовательными записями , и это действительно, как это должно быть сделано.В MSSQL я бы сделал это с помощью ROW_NUMBER()
(хотя для вашего конкретного случая могут быть найдены лучшие решения):
WITH NumberedTable AS (
SELECT User, Date, ROW_NUMBER() OVER (PARTITION BY User ORDER BY Date) AS LoginOccurrenceSortedByDate
FROM YourTable
WHERE Action = 'Login'
)
SELECT L.User, L.Date, DATEDIFF(seconds, R.Date, L.Date) AS DifferenceWithPreviousLogin
FROM NumberedTable L
LEFT JOIN NumberedTable R
ON R.LoginOccurrenceSortedByDate = L.LoginOccurrenceSortedByDate - 1
Вы в основном LEFT JOIN
каждой записи с предыдущим вхождением и рассчитываете разницу во времени,