MySQL查询以查看最近3个月内的变化

时间:2019-02-05 01:06:24

标签: mysql

我想查看最近3个月内的变化。

数据库:

DATABASE

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

结果:

RESULT

可以看到没有1月!

我希望看到最近3个月内的变化。 有人有主意吗?

| 2019 Feb | 50 | 40 | 10 |
| 2019 Jan | 40 | 25 | 15 |
| 2018 Dec | 25 | 20 | 5  |

2 个答案:

答案 0 :(得分: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

Demo on dbfiddle

答案 1 :(得分:1)

由于表不是很复杂,因此您可以使用子查询来代替尝试复杂的联接。另外,由于您不需要从预期结果中显示第1个结果,因此也只需在每个月2号对结果进行过滤。

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

EDIT 根据Nick的观点,我确实假设最大值始终是每月的2号。如果那是错误的,并且表快照恰好没有显示第一个是最大值的月份,那么此修改将给出正确的最大值结果。

JOIN的{​​{1}}和常规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)