Добавление нового столбца в SQL, соответствующего предыдущему столбцу

#sql

#sql

Вопрос:

Я пытаюсь создать новый столбец в существующей таблице SQL (имя: mytable), который, когда пользователь запускает новый проект в течение 20 минут, должен находиться в том же «расписании» (новый столбец)

Пожалуйста, посмотрите пример ниже:

 Name        Date/Time
Candance    2018-09-22 11:20:14
Candance    2018-09-22 11:35:12
Jon         2018-09-23 12:12:13
Jon         2018-09-23 12:20:34
Jon         2018-09-23 12:40:54
 

Что я хотел бы получить:
примечание: пользователь должен быть одинаковым для каждого «расписания»

 Name        Date/Time            Timetable
Candance    2018-09-22 11:20:14  1 
Candance    2018-09-22 11:35:12  1
Jon         2018-09-23 12:12:13  2
Jon         2018-09-23 12:20:34  2
Jon         2018-09-23 12:40:54  3
 

Комментарии:

1. Выберите одну СУБД — либо MySQL, либо PostgreSQL. И укажите точную версию сервера.

2. Я удалил конфликтующие теги СУБД. Пожалуйста, добавьте только тег для продукта базы данных, который вы действительно используете.

3. @user15289436 . , , Если у вас есть чередующиеся данные — например, John at 12:33:00 — как будут выглядеть результаты?

Ответ №1:

Решение для MySQL 8

 WITH cte AS (
SELECT *, CASE WHEN name = LAG(name) OVER (ORDER BY name, date_time)
                AND TIMESTAMPDIFF(MINUTE, LAG(date_time) OVER (ORDER BY name, date_time), date_time) < 20
               THEN 0
               ELSE 1
               END new_timetable
FROM test
)
SELECT name, date_time, SUM(new_timetable) OVER (ORDER BY name, date_time) timetable
FROM cte
ORDER BY name, date_time;
 

скрипка

Комментарии:

1. Привет, Акина, я только что опубликовал продолжение вопроса, просто интересно, можете ли вы помочь, так как мне понравился этот ваш ответ. Спасибо!

Ответ №2:

Логика AKina верна. Однако я бы сформулировал это проще как:

 select t.*,
       sum(case when prev_datetime >= datetime - interval 20 minute
                then 1 else 0
           end) over (order by datetime) as timetable
from (select t.*,
             lag(datetime) over (partition by name) as prev_datetime
      from t
     ) t;
 

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