Необходимость между строками диапазона между использованием предыдущей конечной_даты и следующей начальной_даты

Пока работает белый Наличие ресурсов. У меня есть структура здесь. Позвольте мне объяснить, так что ожидайте получить помощь здесь.

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

CREATE TABLE availibility ( 
   id int NOT NULL,
   start_date date NOT NULL, 
   end_date date DEFAULT NULL, 
   status tinyint NOT NULL DEFAULT '1'
) ENGINE=InnoDB;

INSERT INTO availibility (id, start_date, end_date, status) VALUES (1,'2024-02-01', '2024-02-10', 1), (2,'2024-02-21','2024-02-29',1);

Теперь он возвращает результат, как показано ниже:

ИДЕНТИФИКАТОР Дата начала Дата окончания Положение дел 1 2024-02-01 2024-02-10 1 2 2024-02-21 2024-02-29 1

Хотя я ожидаю, что вернусь и в промежуточный ряд. Образец ниже.

ИДЕНТИФИКАТОР Дата начала Дата окончания Положение дел 1 2024-02-01 2024-02-10 1 НУЛЕВОЙ 2024-02-11 20 февраля 2024 г. 0 2 2024-02-21 2024-02-29 1

Помощь будет оценена по достоинству. Спасибо

в заголовке есть логика - читайте Lead , date_add и date_sub

P.Salmon 27.02.2024 11:47
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
0
1
79
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

я изменил свой ответ

Конечно! Если вы изменили запрос так, что идентификатор больше не играет роли и возможно, что меньший идентификатор появится намного позже в последовательности, давайте проверим это. Не могли бы вы предоставить измененный запрос или какие-либо конкретные изменения, которые вы в него внесли? Как только я получу эту информацию, я смогу помочь вам в дальнейшем и протестировать ее соответствующим образом.

(SELECT * FROM availibility order by start_date)
  UNION ALL
( WITH ranked_end_date AS (
    SELECT *,LEAD(start_date) OVER (ORDER BY start_date) AS next_start_date
    FROM availibility
)
SELECT NULL AS id, end_date + INTERVAL 1 DAY , next_start_date - INTERVAL 1 DAY, 0 AS status
FROM ranked_end_date
WHERE next_start_date is not null
AND DATEDIFF(next_start_date, end_date) > 1 )
ORDER BY start_date;

https://dbfiddle.uk/5oi4khgB

да, вы также можете использовать внутреннее соединение

Bernd Buffen 27.02.2024 12:26

Благодарим за ваш ответ, он работает только с заданными данными, но если я добавляю еще одну строку, как показано ниже, это не сработает, я ожидаю, что он вернет фиктивные данные для всех между строками. Я предоставил образец тестового примера только для понимания. ВСТАВИТЬ В availibility (id, start_date, end_date, status) ЗНАЧЕНИЯ ('4', '2024-03-08', '2024-03-10', '1');

Rushabh Madhu 27.02.2024 12:45

@RushabhMadhu Затем вы можете использовать ROW_NUMBER для создания непрерывного набора для соединения - dbfiddle.uk/_FAALRkL

user1191247 27.02.2024 12:47

Спасибо @user1191247 и Бернду Буффену за вашу быструю помощь, это делает мой день лучше.

Rushabh Madhu 27.02.2024 12:51

С доступностью AS ( SELECT *, ROW_NUMBER() OVER (ORDER BY start_date ASC) AS rn FROM доступности ) (SELECT * FROM доступности) UNION ALL (выберите нулевой идентификатор AS, a.end_date + INTERVAL 1 DAY AS start_date, b.start_date - ИНТЕРВАЛ 1 ДЕНЬ AS end_date , 0 AS статус ОТ доступности a INNER JOIN доступность b ON b.rn = a.rn+1 WHERE DATEDIFF(b.start_date, a.end_date) > 1) ORDER BY start_date; Вот мое окончательное решение.

Rushabh Madhu 27.02.2024 12:52

@Rushabh Madhu - я изменил свой ответ, не используя поле идентификатора

Bernd Buffen 27.02.2024 13:34

Другой способ — использовать UNION:

SELECT 
  id,
  start_date,
  end_date,
  status
FROM availibility

UNION ALL

SELECT 
  NULL, 
  DATE_ADD(a1.end_date,INTERVAL 1 DAY),
  DATE_ADD(a2.start_date, INTERVAL -1 DAY),
  0
FROM availibility a1 
INNER JOIN availibility a2 ON a2.id=2
WHERE a1.id=1
ORDER BY start_date

см.: DBFIDDLE

Обновлено: добавлен комментарий от @RushabhMadhu в читаемом формате:

(SELECT * FROM availibility order by start_date) 
  UNION ALL 
( WITH ranked_end_date AS ( 
     SELECT *,LEAD(start_date) OVER (ORDER BY start_date) AS next_start_date 
     FROM availibility ) 
SELECT 
  NULL AS id, 
  end_date + INTERVAL 1 DAY , 
  next_start_date - INTERVAL 1 DAY, 
  0 AS status 
FROM ranked_end_date 
WHERE next_start_date is not null AND DATEDIFF(next_start_date, end_date) > 1 ) 
ORDER BY start_date

см.: DBFIDDLE2

Я проверил, но, похоже, вышеприведенное требует некоторых улучшений, поскольку мой запрос также является динамическим и может содержать несколько строк, в которых отсутствуют некоторые даты. но ниже приведен идеальный ответ на мой вопрос. (ВЫБРАТЬ * ИЗ порядка доступности по начальной_дате) СОЕДИНЕНИЕ ВСЕ ( С ранжированной_конечной_датой КАК ( ВЫБРАТЬ *,LEAD(начальная_дата) НАД (ОРДЕР ПО начальной_дате) КАК следующая_начальная_дата ИЗ доступности ) ВЫБРАТЬ NULL КАК id, конечная_дата + ИНТЕРВАЛ 1 ДЕНЬ, следующая_начальная_дата - ИНТЕРВАЛ 1 ДЕНЬ , 0 Статус AS ОТ Ranked_end_date ГДЕ next_start_date не равно нулю И DATEDIFF(next_start_date, end_date) > 1 ) ORDER BY start_date

Rushabh Madhu 27.02.2024 14:12

Комментарии довольно трудно читать, когда они содержат код, поэтому я добавил ваше утверждение в ответ.

Luuk 27.02.2024 15:36

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