Sql-запрос на разницу между строками

У меня есть таблица с датами, я бы хотел вычесть первую дату со второй, вторую с третьей и так далее до последнего n-1 с n.

Как мне написать для этого запрос?

Таблица будет называться Случайная, а имя столбца - дата.

 date       
+------------+
| 2009-06-20 |
| 2010-02-12 |
| 2012-03-14 |
| 2013-09-10 |
| 2014-01-01 |
| 2015-04-10 |
| 2015-05-01 |
| 2016-01-01 |
+------------+

Какая версия MySQL?

Thorsten Kettner 25.07.2018 21:46
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
0
2
77
3

Ответы 3

Тебе нужно назначить следующее свидание. Я бы использовал коррелированный подзапрос:

select t.date,
       (select min(t2.date)
        from t t2
        where t2.date > t.date
       ) as next_date
from t;

Вам просто нужно использовать datediff(), чтобы получить разницу в днях.

Я не заметил тег mysql, когда сначала написал свой ответ, поэтому сейчас обновляю его со ссылкой на скрипт MySQL 8.0

https://www.db-fiddle.com/f/myUJYeFrMXmU1piQXAmnv4/0

/* tested against MySQL v8.0 */
WITH T(d) AS (
    SELECT '2009-06-20' as d 
    UNION
    SELECT '2010-02-12'
    UNION
    SELECT '2012-03-14'
    UNION
    SELECT '2013-09-10'
    UNION
    SELECT '2014-01-01'
    UNION
    SELECT '2015-04-10'
    UNION
    SELECT '2015-05-01'
    UNION
    SELECT '2016-01-01'
), LAGGED(d, next_d) AS (
    SELECT d, LEAD(d) OVER (ORDER BY d ASC) AS next_d
    FROM T
)
/* datediff args are in opposite order to SQL server.  Also,
  only day part is considered */
SELECT l.d, l.next_d, DATEDIFF(l.next_d, l.d) AS n_days
 FROM LAGGED AS l

Вот мой первоначальный ответ, ориентированный на SQL Server:

WITH T(d) AS (
  SELECT d FROM (
  VALUES 
  ('2009-06-20'),
  ('2010-02-12'),
  ('2012-03-14'),
  ('2013-09-10'),
  ('2014-01-01'),
  ('2015-04-10'),
  ('2015-05-01'),
  ('2016-01-01')
  ) AS T1(d)
), LAGGED(d, next_d) AS (
   SELECT d, LEAD(d) OVER (ORDER BY d ASC) AS next_d
   FROM T
)
SELECT l.d, l.next_d, DATEDIFF(DAY, l.d, l.next_d) AS n_days
FROM LAGGED AS l

и производит этот результат (по модулю суетливого ручного редактирования, которое я сделал):

 
  d              next_d     n_days
  2009-06-20    2010-02-12  237
  2010-02-12    2012-03-14  761
  2012-03-14    2013-09-10  545
  2013-09-10    2014-01-01  113
  2014-01-01    2015-04-10  464
  2015-04-10    2015-05-01  21
  2015-05-01    2016-01-01  245
  2016-01-01    NULL    NULL

Я не заметил тега mysql. Я обновил свой ответ формулировкой, специфичной для MySQL.

Paul Harrington 25.07.2018 22:21

Используйте ROW_NUMBER Для нумерации строк, а затем используйте подзапрос для вычисления разницы

SELECT  column_date 
,DATEDIFF( D , column_date 
,(SELECT column_date FROM
    (
    SELECT  column_date , ROW_NUMBER() OVER ( ORDER BY column_date) AS RowMum
     FROM table_Random AS tBL_1
    ) AS tbl_2
       WHERE tbl_2.RowMum= tBL_1.RowMum-1
 )
         ) DIFF
FROM 
(
SELECT  column_date , ROW_NUMBER() OVER ( ORDER BY column_date) AS RowMum
FROM table_Random
) AS tBL_1

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