MySQL запрос, чтобы увидеть изменения в течение месяца за последние 3 месяца

0

Я хочу видеть изменения в течение месяца за последние 3 месяца.

База данных:

Изображение 174551

MySQL:

SELECT DATE_FORMAT(CUR.time, '%Y %b') AS thisTime,
   MAX(CUR.value) AS thisValue,
   MAX(PRE.value) AS prevValue,
   MAX(CUR.value)-MAX(PRE.value) AS compValue
FROM test CUR
INNER JOIN test PRE
ON MONTH(PRE.time) = (SELECT MAX(MONTH(XXX.time))
                      FROM test XXX
                      WHERE MONTH(XXX.time) < MONTH(CUR.time))
WHERE CUR.time > DATE_SUB(NOW(), INTERVAL 3 MONTH)
GROUP BY MONTH(CUR.time)
ORDER BY CUR.id

Результат:

Изображение 174551

Можно увидеть, что нет января!

Я хочу видеть изменения в течение месяца за последние 3 месяца, как это. У кого-нибудь есть идеи?

| 2019 Feb | 50 | 40 | 10 |
| 2019 Jan | 40 | 25 | 15 |
| 2018 Dec | 25 | 20 | 5  |
Теги:

2 ответа

1
Лучший ответ

Проблема с попыткой использовать MONTH в состоянии JOIN заключается в переходе от 12 к 1 в конце года. Проще всего использовать дату в качестве строки YEARMONTH:

SELECT DATE_FORMAT(t1.time, '%b %Y') AS thisTime,
       MAX(t1.value) AS thisValue,
       MAX(t2.value) AS prevValue,
       MAX(t1.value) - MAX(t2.value) AS compValue
FROM test t1
JOIN test t2 ON DATE_FORMAT(t2.time, '%Y%m') = (SELECT MAX(DATE_FORMAT('time', '%Y%m')) 
                                                FROM test t3 
                                                WHERE DATE_FORMAT(t3.time, '%Y%m') < DATE_FORMAT(t1.time, '%Y%m'))
GROUP BY thisTime
ORDER BY STR_TO_DATE(CONCAT('1 ', thisTime), '%d %b %Y') DESC

Выход:

thisTime    thisValue   prevValue   compValue
Feb 2019    50          40          10
Jan 2019    40          25          15
Dec 2018    25          20          5

Демо на dbfiddle

  • 0
    Я обновил новую базу данных. Вы можете попробовать еще раз?
  • 0
    @JamesKmutnb Я обновил свой ответ. Пожалуйста, в будущем постарайтесь предоставить всю информацию, которая необходима для решения проблемы.
Показать ещё 3 комментария
1

Вместо того, чтобы пытаться выполнить сложное объединение, вы можете просто использовать подзапросы, поскольку таблица не очень сложна. Также просто отфильтруйте результаты 2-го числа каждого месяца, так как вам не нужно 1-е число из того, что показывает ожидаемый результат.

SELECT
  DATE_FORMAT(cur.time,'%Y %b') AS thisTime,
  cur.value AS thisValue,
  (SELECT value FROM test WHERE time = DATE_SUB(cur.time,INTERVAL 1 MONTH)) AS prevValue,
  (SELECT cur.value - value FROM test WHERE time = DATE_SUB(cur.time,INTERVAL 1 MONTH)) AS compValue
FROM
  test AS cur
WHERE
  cur.time >= DATE_SUB(CURDATE(),INTERVAL 3 MONTH)
AND DATE_FORMAT(cur.time,'%d') = 2

Результат:

thisTime    thisValue   prevValue    compValue
2019 Feb    50          40           10
2019 Jan    40          25           15
2018 Dec    25          20           5

РЕДАКТИРОВАТЬ На точку Ник ниже, я предположил, что максимум всегда будет 2-го числа каждого месяца. Если это значение false и снимок таблицы просто не показывают месяц, в котором 1-е число было максимальным, то это изменение даст правильный максимальный результат.

JOIN от monthMax и обычная test таблица гарантируют, что вы всегда получите максимальное значение за месяц, независимо от количества дат в этом месяце. Затем просто используйте тот же метод подзапроса, что и мой первоначальный запрос.

SELECT
  DATE_FORMAT(t.time,'%Y %b') AS thisTime,
  t.value AS thisValue,
  (SELECT MAX(value) FROM test WHERE DATE_FORMAT(time,'%Y-%m') = DATE_FORMAT(DATE_SUB(t.time,INTERVAL 1 MONTH),'%Y-%m')) AS prevValue,
  (SELECT t.value - MAX(value) FROM test WHERE DATE_FORMAT(time,'%Y-%m') = DATE_FORMAT(DATE_SUB(t.time,INTERVAL 1 MONTH),'%Y-%m')) AS compValue
FROM
  (SELECT DATE_FORMAT(time,'%Y-%m') AS 'timeFix', MAX(value) AS 'maxValue' FROM test GROUP BY timeFix) AS monthMax
JOIN (test AS t) ON (monthMax.maxValue = t.value AND monthMax.timeFix = DATE_FORMAT(t.time,'%Y-%m'))
WHERE
  t.time > DATE_SUB(CURDATE(),INTERVAL 3 MONTH)

Результат:

thisTime    thisValue   prevValue    compValue
2019 Feb    50          40           10
2019 Jan    40          25           15
2018 Dec    25          20           5
  • 0
    Этот запрос не выбирает максимальные значения для каждого месяца для сравнения.
  • 0
    Это правильно, но я предполагаю, что из его структуры таблицы он мог только хотеть Макса, потому что он не был уверен, как подойти к вопросу? Предполагая, что 2-е число каждого месяца является максимумом каждого месяца, это всегда должно быть хорошо.
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню