2013-08-01 2 views
2

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

Порядок записей по дате, и я фильтрую другой столбец.

например.

id other_col date  days_between_dates 
1 abc  2013-05-01  0 
2 abc  2013-05-07  6 
3 abc  2013-05-09  2 
4 abc  2013-05-19  10 
5 abc  2013-05-25  6 
6 abc  2013-06-03  9 
7 abc  2013-06-14  11 

Очевидно, так как первая строка не имеет ничего, чтобы сравнить с, он должен показать 0.

Я знаю, что могу получить разницу между двумя датами с помощью функции MySQL datediff.

select datediff('2013-06-03','2013-05-25'); 

Мой основной запрос select * from mytable where other_col = 'something' order by date; , но как я могу сделать запрос непосредственно получить результат, как в примере? (Мне нужна дополнительная колонка «days_between_dates»).

Также обратите внимание, что обычно идентификаторы упорядочены и без пробелов, но я не могу этого гарантировать. только то, что я буду сортировать по восходящей дате и фильтровать столбец «other_col».

+0

Являются ли идентификаторы в таблице гарантированно последовательными (т. Е. Они являются значениями автоинкремента, и вы никогда не удаляете строки или не изменяете значение автоинкремента)? –

+0

Да, они секвенциальны, но я не знаю, можно ли их удалить, создав таким образом «пробелы» в идентификаторах. В идеале (и во всех случаях, которые я видел) идентификаторы всегда последовательны и без пробелов, но, возможно, не всегда. Для этого случая давайте предположим, что они действительно последовательны. – DiegoDD

ответ

3

Вы можете сделать что-то вдоль этих линий:

SELECT T.id, 
     T.other_col, 
     T.yourdate, 
     IFNULL(datediff(T.yourdate,(select MAX(TT.yourdate) 
            FROM yourtable TT 
            WHERE TT.yourdate < T.yourdate 
            AND TT.other_col = 'abc')),0) 
FROM yourtable T 
where other_col = 'abc'; 

Вы можете увидеть его в этом fiddle

Это работает путем вычисления разности между датой текущей записи в (T.date) и датой, которая является (MAX(TT.date)), которые меньше, чем текущая дата записи (WHERE TT.date < T.date).

Когда нет более мелкой даты, есть COALESCE, чтобы оно было 0, а не null.

Редактировать. добавили коалесценцию, чтобы дать 0 в первой строке

+0

похоже работа! Не могли бы вы объяснить это дальше? особенно внутренний выбор внутри второго аргумента датиффа, и почему использовать дату MAX. – DiegoDD

+0

Обновление, это не работает, когда у меня есть несколько разных значений «other_col», и их даты не являются последовательными между ними, [см. Эту скрипту] (http://sqlfiddle.com/#!2/cdef8/1/0). Думаю, мне просто нужно добавить условие 'where' для обоих вариантов. Дай мне попробовать. – DiegoDD

+0

Да.вам нужно, иначе внутренний запрос будет проверять всю таблицу на дату, которая является самой большой датой, которая меньше даты текущей записи. Если вы укажете, где находится внутренний запрос, он будет работать так, как вы этого хотите. О том, как это работает, я обновляю свой ответ с небольшим объяснением. –

2

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

SELECT t1.id, t1.other_col, t1.date, DATEDIFF(t2.date,t1.date) 
FROM table AS t1 
LEFT_JOIN table AS t2 ON t1.id = t2.id - 1 

Обратите внимание, что я использую LEFT JOIN здесь таким образом, что первый ряд и последние строки на t1 (основная таблица).

Смежные вопросы