Нахождение разницы между последовательными строками в MySQL без ЗАДЕРЖЕК?

#mysql #sql

Вопрос:

За каждый месяц (кроме января) Я хотел бы найти разницу в количестве по сравнению с предыдущим месяцем.

У меня есть столик:

Месяц Кол-во
Январь 4
Февраль 3
Март 9
Апрель 3
Май 7

и я хотел бы вернуться:

Месяц Разница
Февраль -1
Март 6
Апрель -6
Май 4

Я использую более старую версию MySQL, поэтому я не могу использовать для этого ОПЕРЕЖЕНИЕ/ЗАДЕРЖКУ.

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

1. У вас в таблице всего 12 строк, по 1 на каждый месяц?

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

3. Опубликуйте свои фактические данные.

4. У вас всегда есть строка за любой предыдущий месяц или могут быть пробелы? Что следует делать, если есть пробел? У вас тоже есть колонка с годом?

Ответ №1:

 SELECT t1.`Month`, COALESCE(t1.Qty - t2.Qty, 'Unknown') Difference
FROM table t1
LEFT JOIN table t2 
    ON STR_TO_DATE(CONCAT(t1.`Month`, ' 01 2021'), '%M %d %Y')
     = STR_TO_DATE(CONCAT(t2.`Month`, ' 01 2021'), '%M %d %Y')   INTERVAL 1 MONTH
 

Ответ №2:

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

 select t.*, (qty - prev_qty) as difference
from (select t.*,
             (select t2.qty
              from t t2
              where t2.month < t.month
              order by t2.month desc
              limit 1
             ) as prev_qty
      from t
     ) t
where prev_qty is not null;
 

Если вы действительно храните месяцы в виде строкового имени, то вам нужно преобразовать их во что-то упорядоченное:

 select t.*, (qty - prev_qty) as difference
from (select t.*,
             (select t2.qty
              from t t2
              where str_to_date(concat(t2.month, ' 1 2000', '%M %d %Y') < str_to_date(concat(t.month, ' 1 2000', '%M %d %Y')
              order by str_to_date(concat(t2.month, ' 1 2000', '%M %d %Y') desc
              limit 1
             ) as prev_qty
      from t
     ) t
where prev_qty is not null;