Показать две строки, связанные друг с другом как одну на основе даты из той же таблицы

Я пытаюсь написать запрос для сценария ниже. Когда пользователь входит в систему, мы регистрируем событие ВойтиУспех, а когда выходим из системы, мы вычисляем общую продолжительность, в течение которой он был в системе, и регистрируем это как событие Продолжительность.

Я хочу отображать оба журнала для пользователя, когда он входит в систему, и какова была продолжительность события «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

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

Предоставленный вами SQL недействителен, и поскольку вы поместили весь SQL в одну строку, его очень сложно отлаживать. Пробелы и разрывы строк имеют первостепенное значение для создания читаемого текста; не только в коде. Пожалуйста, возьмите в привычку правильно использовать и то, и другое. Плохое/плохое форматирование не поможет ни вам, ни другим, когда вам нужно быстро прочитать и понять код. Использование отступов и разрывов строк действительно помогает легко различать определенные блоки и разделы кода и значительно упрощает поиск ошибок, когда строка содержит только 10 символов, а не 100.

Larnu 21.03.2022 17:04

Спасибо за предложения. Я пробовал отступы и разрывы строк. Дайте мне знать, если это выглядит нормально.

Jahanzaib Rahman 21.03.2022 17:15
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
0
2
23
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете вернуть самый последний успешный вход в систему до или равно длительности действия журнала событий.

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;

Другие вопросы по теме