Я пытаюсь написать запрос для сценария ниже. Когда пользователь входит в систему, мы регистрируем событие ВойтиУспех, а когда выходим из системы, мы вычисляем общую продолжительность, в течение которой он был в системе, и регистрируем это как событие Продолжительность.
Я хочу отображать оба журнала для пользователя, когда он входит в систему, и какова была продолжительность события «Arg» для этого соответствующего входа в систему.
Ниже приведены образцы данных и выходные данные.
CREATE TABLE [logs_table]
([AccountId] [uniqueidentifier] NULL,
[UtcActionDate] [datetime] NULL,
[ActionType] [nvarchar](255) NULL,
[ActionSubType] [nvarchar](255) NULL,
[Arg] [nvarchar](255) NULL);
INSERT INTO logs_table
(AccountId,UtcActionDate,ActionType,ActionSubType,Arg)
VALUES ('7DADAEDB-A0E5-4290-8D94-8D3C8144A662','2022-03-10 17:32:19.000', 'Login','LoginSuccess',null),
('7DADAEDB-A0E5-4290-8D94-8D3C8144A662','2022-03-10 21:54:56.000', 'Exchange','Duration','01:03:41),
('7DADAEDB-A0E5-4290-8D94-8D3C8144A662','2022-03-11 23:00:38.000', 'Login','LoginSuccess',null),
('7DADAEDB-A0E5-4290-8D94-8D3C8144A662',2022-03-14 17:39:47.000', 'Exchange','Duration','00:00:17'),
('7DADAEDB-A0E5-4290-8D94-8D3C8144A662','2022-03-14 17:40:30.000', 'Login','LoginSuccess',null),
('7DADAEDB-A0E5-4290-8D94-8D3C8144A662','2022-03-14 21:10:08.000', 'Exchange','Duration','00:00:25')
Пример вывода будет выглядеть так
AccoundId LoginStartDate LoginStartTime Arg
7DADAEDB-A0E5-4290-8D94-8D3C8144A662 2022-03-10 17:32:19.000 01:03:41
7DADAEDB-A0E5-4290-8D94-8D3C8144A662 2022-03-11 23:00:38.000 00:00:17
7DADAEDB-A0E5-4290-8D94-8D3C8144A662 2022-03-14 17:40:30.000 00:00:25
Пользователь может входить в систему несколько раз в день, и перед журналами событий продолжительности может быть несколько событий входа в систему, и мне нужно сделать это внутри представления, чтобы не было курсоров или временных таблиц.
Спасибо за предложения. Я пробовал отступы и разрывы строк. Дайте мне знать, если это выглядит нормально.
Вы можете вернуть самый последний успешный вход в систему до или равно длительности действия журнала событий.
CREATE TABLE logs_table ( [AccountId] [uniqueidentifier] NULL,
[UtcActionDate] [datetime] NULL,
[ActionType] [nvarchar](255) NULL,
[ActionSubType] [nvarchar](255) NULL,
[Arg] [nvarchar](255) NULL
);
INSERT INTO logs_table
(AccountId,UtcActionDate,ActionType,ActionSubType,Arg)
VALUES
('7DADAEDB-A0E5-4290-8D94-8D3C8144A662','2022-03-10 17:32:19.000', 'Login','LoginSuccess',null),
('7DADAEDB-A0E5-4290-8D94-8D3C8144A662','2022-03-10 21:54:56.000', 'Exchange','Duration','01:03:41'),
('7DADAEDB-A0E5-4290-8D94-8D3C8144A662','2022-03-11 23:00:38.000', 'Login','LoginSuccess',null),
('7DADAEDB-A0E5-4290-8D94-8D3C8144A662','2022-03-14 17:39:47.000', 'Exchange','Duration','00:00:17'),
('7DADAEDB-A0E5-4290-8D94-8D3C8144A662','2022-03-14 17:40:30.000', 'Login','LoginSuccess',null),
('7DADAEDB-A0E5-4290-8D94-8D3C8144A662','2022-03-14 21:10:08.000', 'Exchange','Duration','00:00:25');
WITH logins
AS
(
SELECT *
FROM logs_table
WHERE ActionType = 'Login'
AND ActionSubType = 'LoginSuccess'
),
durations
AS
(
SELECT *
FROM logs_table
WHERE ActionType = 'Exchange'
AND ActionSubType = 'Duration'
),
both
AS
(
SELECT x.AccountId
,x.UtcActionDate
,y.Arg
,MAX(x.UtcActionDate) OVER (PARTITION BY y.AccountId, y.UtcActionDate, y.Arg) AS max_login_date
FROM logins x
INNER JOIN durations y ON x.AccountId = y.AccountId AND x.UtcActionDate <= y.UtcActionDate
)
SELECT AccountId
,CAST(UtcActionDate AS date) AS "Login Start Date"
,CAST(UtcActionDate AS time) AS "Login Start Time"
,Arg AS Duration
FROM both
WHERE UtcActionDate = max_login_date;
Предоставленный вами SQL недействителен, и поскольку вы поместили весь SQL в одну строку, его очень сложно отлаживать. Пробелы и разрывы строк имеют первостепенное значение для создания читаемого текста; не только в коде. Пожалуйста, возьмите в привычку правильно использовать и то, и другое. Плохое/плохое форматирование не поможет ни вам, ни другим, когда вам нужно быстро прочитать и понять код. Использование отступов и разрывов строк действительно помогает легко различать определенные блоки и разделы кода и значительно упрощает поиск ошибок, когда строка содержит только 10 символов, а не 100.