我想查看最近3个月内的变化。
数据库:
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
结果:
可以看到没有1月!
我希望看到最近3个月内的变化。 有人有主意吗?
| 2019 Feb | 50 | 40 | 10 |
| 2019 Jan | 40 | 25 | 15 |
| 2018 Dec | 25 | 20 | 5 |
答案 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
答案 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)