Как перебрать несколько входов в систему и рассчитать количество и время входа в SQL 2005? - PullRequest
1 голос
/ 16 ноября 2010

Я новичок в SQL, и я надеюсь, что вы, люди, поможете мне пройти через это испытание.

Приведенные ниже данные должны быть сгруппированы по клиенту, дате и идентификатору пользователя (чего я уже достиг).

Client User ID Date Action Module
Moha Mother 01/10/2010 12:35:36 PM Login PP
Moha Voodoo 02/10/2010 05:15:28 PM Login PP
Moha Panther 04/10/2010 04:36:42 PM Login PP
Moha Mother 01/10/2010 12:42:35 PM Some Action PP
Moha Mother 01/10/2010 12:55:14 PM Some Action PP
Moha Voodoo 02/10/2010 06:35:46 PM Login PP
Moha Panther 04/10/2010 04:53:24 PM Some Action PP
Moha Deuce 05/10/2010 09:13:42 PM Login PP
Moha Deuce 05/10/2010 09:19:42 PM Some Action PP
Moha Panther 06/10/2010 08:11:22 PM Login PP
Moha Deuce 05/10/2010 09:27:49 PM Some Action PP
Moha Panther 06/10/2010 08:15:18 PM Some Action PP
Moha Panther 06/10/2010 08:44:53 PM Some Action PP
Moha Deuce 05/10/2010 09:27:49 PM Login PP
Moha Rabbit 05/20/2010 09:27:49 PM Login PP
Moha Voodoo 02/10/2010 06:57:35 PM Some Action PP
Moha Deuce 06/10/2010 08:30:59 AM Login PP
Moha Rabbit 05/21/2010 09:27:49 PM Login PP
Moha Mother 03/10/2010 01:04:54 PM Login PP
Moha Mother 03/10/2010 01:23:55 PM Some Action PP
Moha Mother 03/10/2010 02:25:46 PM Login PP
Moha Mother 03/10/2010 02:45:54 PM Some Action PP

Как только это будет сделано, я хочу знать, достижима ли нижеследующая информация через SQL.

Клиент ID пользователя Дата Войти Cnt Логин Amt (мин) Моха Мама 01/10/2010 1 19,6 (00:06:59 + 00:12:39) - Информация о скобках не требуется Моха Мать 03/10/2010 2 39,2 (00:19:01 + 00:20:08) Моха Водоо ……… Моха …………

Я уже написал процедуру, которая будет динамически принимать необязательные параметры для клиента, даты начала, даты окончания и идентификатора пользователя. Моя процедура сначала преобразует дату в формат varchar и извлекает только дату для целей группировки, а затем вычисляет количество входов в систему с использованием оператора case. Но..!! Как рассчитать разницу во времени между двумя последовательными записями и получить количество входов в систему в соответствии с правилами группировки? Можно ли добиться того же, используя курсоры?

Пожалуйста, не стесняйтесь задавать любые вопросы и давать любые предложения по вышеупомянутой теме, так как это одно из моих критических требований. Спасибо всем заранее.

Спасибо CS

1 Ответ

1 голос
/ 16 ноября 2010

Существует несколько способов решения этой проблемы.

Прежде всего, я должен сказать, что не могу дать вам полного решения этой проблемы.Количество входов в систему очень просто, но для продолжительности входа в систему каждого пользователя мне потребуется дополнительная информация.Исходя из имеющихся данных, неясно, какая из дат означает время выхода из системы .Если предположить, что это последнее появление «Некоторого действия» перед новым входом в систему, решение будет возможным, но я не знаю, верно ли это предположение или нет.Если пользователь открывает несколько сеансов параллельно, это предположение будет нарушено, а также, если время выхода из системы не будет записано (например, когда время сеанса истекает после некоторой точки, а время не сохраняется), вы не сможете сделать многое.

В любом случае, я хочу сделать три замечания:

  • Общий аргумент запросов на основе множеств по сравнению с курсорами
  • Рекомендуемый запрос для количества логинов
  • Советы о том, как действовать в течение времени входа в систему

Первый пункт: вы предлагаете использовать курсоры и хранимую процедуру для определения количества входов в систему.Это решение будет работать, но, как правило, вы будете действовать на обычном языке программирования, таком как, например, 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 каждой записи с предыдущим вхождением и рассчитываете разницу во времени,

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