SQL: вычисление общего изменения за каждый день с использованием даты - PullRequest
0 голосов
/ 29 марта 2019

У меня есть следующая таблица:

Date        |  Store  |  Total
2018-05-02     ABC       56.98
2018-05-02     DEF       60.34 
2018-05-02     XYZ       46.50
2018-05-03     ABC       80.43
2018-05-03     DEF       70.09
2018-05-03     XYZ       95.98
2018-05-04     ABC       43.52
2018-05-04     DEF       90.23
2018-05-04     XYZ       88.12

Я пытаюсь создать запрос, который выведет приведенную выше таблицу с дополнительным столбцом PrevTotal, который для каждого магазина будет иметь итоговое значение за предыдущий день.,Я также хочу игнорировать все записи с первой датой (2018-05-02) в выходной таблице (поскольку вы не можете получить предыдущую сумму за первый день).Например, вывод должен быть:

Date        |   Code   |   Total   |   PrevTotal 
2018-05-03      ABC        80.43       56.98
2018-05-03      DEF        70.09       60.34
2018-05-03      XYZ        95.98       46.50
2018-05-04      ABC        43.52       80.43
2018-05-04      DEF        90.23       60.34
2018-05-04      XYZ        88.12       95.98      

Я не уверен, как мне создать запрос, который поможет мне сделать это.Любые идеи приветствуются.

Ответы [ 5 ]

1 голос
/ 29 марта 2019

Это прекрасно работает для меня.

SELECT s2.*, s1.Total 
FROM Stores s1
LEFT JOIN Stores s2 on s1.Store = s2.Store
     AND DATEDIFF(day, s2.Date, s1.Date) = -1

WHERE s2.Total IS NOT NULL
ORDER BY s1.Date, s1.Store
0 голосов
/ 29 марта 2019

Предполагая, что даты являются последовательными, join делает именно то, что вы хотите:

select t.*, tprev.total as prev_total
from t join
     t tprev
     on tprev.code = t.code and tprev.date = t.date - interval 1 day;

lag() также возможно в MySQL 8+.С правильными индексами я не знаю, что будет быстрее.

0 голосов
/ 29 марта 2019

Полагаю, что предыдущий итог не всегда будет от даты - 1 день, но, возможно, между днями будут пробелы, поэтому вы должны найти предыдущую дату для каждого магазина:

select t.*, tt.total prevtotal
from tablename t inner join tablename tt
on 
  tt.store = t.store 
  and 
  tt.date = (
    select max(date) from tablename where store = t.store and date < t.date
  )

См. демо .Результаты:

| date       | store | total | prevtotal |
| ---------- | ----- | ----- | --------- |
| 2018-05-03 | ABC   | 80.43 | 56.98     |
| 2018-05-03 | DEF   | 70.09 | 60.34     |
| 2018-05-03 | XYZ   | 95.98 | 46.5      |
| 2018-05-04 | ABC   | 43.52 | 80.43     |
| 2018-05-04 | DEF   | 90.23 | 70.09     |
| 2018-05-04 | XYZ   | 88.12 | 95.98     |
0 голосов
/ 29 марта 2019

Если вы используете последнюю версию MySQL, код можно сделать более читабельным, используя windowing function

Тест в реальном времени: https://www.db -fiddle.com / f / pKAbtGWF4paTxkbzA8ieST / 0

with a as 
(
  select 
      date, store, total, 
      lag(total) over(partition by store
                      order by date) as prev_total
  from t
)
select *
from a
where prev_total is not null
order by date, store

Выход:

| date                | store | total | prev_total |
| ------------------- | ----- | ----- | ---------- |
| 2018-05-03 00:00:00 | ABC   | 80.43 | 56.98      |
| 2018-05-03 00:00:00 | DEF   | 70.09 | 60.34      |
| 2018-05-03 00:00:00 | XYZ   | 95.98 | 46.5       |
| 2018-05-04 00:00:00 | ABC   | 43.52 | 80.43      |
| 2018-05-04 00:00:00 | DEF   | 90.23 | 70.09      |
| 2018-05-04 00:00:00 | XYZ   | 88.12 | 95.98      |
0 голосов
/ 29 марта 2019

Вы можете использовать 2-й максимальный идентификатор, как, но нулевые данные, которых вы не можете избежать лучше, вы просто игнорируете данные при извлечении / отображении:

SELECT tbl2.Date, tbl2.Store, tbl2.total, 
(select total from test_table tbl1 where tbl1.Store = tbl2.Store and tbl1.id < tbl2.id) as prev_Total 
FROM `test_table` tbl2

Результат:

Date       |   Store  |  total | prev_Total |
--------------------------------------------
2019-03-21 |   ABC    |  56.98 | NULL       |
--------------------------------------------
2019-03-21 |   DEF    |  60.34 | NULL       |
--------------------------------------------
2019-03-21 |   XYZ    |  46.50 | NULL       |
--------------------------------------------
2019-03-21 |   ABC    |  80.43 | 56.98      |
--------------------------------------------
2019-03-21 |   DEF    |  70.09 | 60.34      |
--------------------------------------------
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...