Mysql-利用union实现全外连接,获取[本月,上月]数据进行对比

收到业务需求需要分析各业务类型本月和上月的数据对比,查询数据的过程中主要需要处理一个问题:需要将本月、上月产生数据的业务类型全部显示,但有一部分上月产生数据的业务类型在本月还没有产生数据
效果图

  1. 将时间字段格式化为“2020-01”格式
DATE_FORMAT(CREATE_DATE_, '%Y-%m')
  1. 为数据源添加“上月”时间标识 LAST_DATE_
SELECT
	DATE_FORMAT(CREATE_DATE_, '%Y-%m') AS DATE_,
	DATE_FORMAT(date_sub(CREATE_DATE_,interval 1 MONTH), '%Y-%m') AS LAST_DATE_,
	a.MESSAGE_,
	COUNT(a.ID_) AS NUM_
FROM
	t_project_comment a
WHERE
	a.STATUS_ > 0
GROUP BY
	DATE_,
	MESSAGE_
ORDER BY
	DATE_,
	MESSAGE_
  1. 利用left join将“数据源”用时间和类型连接,获取当前时间业务数据及对应的上月业务数据
SELECT
	a.DATE_,
	a.MESSAGE_,
	a.NUM_,
	a.LAST_DATE_,
	IFNULL(b.NUM_, 0) AS LAST_NUM_
FROM
	(
		SELECT
			DATE_FORMAT(CREATE_DATE_, '%Y-%m') AS DATE_,
			DATE_FORMAT(
				date_sub(
					CREATE_DATE_,
					INTERVAL 1 MONTH
				),
				'%Y-%m'
			) AS LAST_DATE_,
			a.MESSAGE_,
			COUNT(a.ID_) AS NUM_
		FROM
			t_project_comment a
		WHERE
			a.STATUS_ > 0
		GROUP BY
			DATE_,
			MESSAGE_
		ORDER BY
			DATE_,
			MESSAGE_
	) a
LEFT JOIN (
	SELECT
		DATE_FORMAT(CREATE_DATE_, '%Y-%m') AS DATE_,
		DATE_FORMAT(
			date_sub(
				CREATE_DATE_,
				INTERVAL 1 MONTH
			),
			'%Y-%m'
		) AS LAST_DATE_,
		a.MESSAGE_,
		COUNT(a.ID_) AS NUM_
	FROM
		t_project_comment a
	WHERE
		a.STATUS_ > 0
	GROUP BY
		DATE_,
		MESSAGE_
	ORDER BY
		DATE_,
		MESSAGE_
) b ON a.LAST_DATE_ = b.DATE_
AND a.MESSAGE_ = b.MESSAGE_
  1. 为数据源添加“下月”时间标识 NEXT_DATE_
SELECT
	DATE_FORMAT(CREATE_DATE_, '%Y-%m') AS DATE_,
	DATE_FORMAT(date_add(CREATE_DATE_,interval 1 MONTH), '%Y-%m') AS NEXT_DATE_,
	a.MESSAGE_,
	COUNT(a.ID_) AS NUM_
FROM
	t_project_comment a
WHERE
	a.STATUS_ > 0
GROUP BY
	DATE_,
	MESSAGE_
ORDER BY
	DATE_,
	MESSAGE_
  1. 利用left join将“数据源”用时间和类型连接,获取当前时间业务数据及对应的下月业务数据
    注意:DATE_为NEXT_DATE_
SELECT
	a.NEXT_DATE_ AS DATE_,
	a.MESSAGE_,
	IFNULL(b.NUM_, 0) AS NUM_,
	a.DATE_ AS LAST_DATE_,
	IFNULL(a.NUM_, 0) AS LAST_NUM_
FROM
	(
		SELECT
			DATE_FORMAT(CREATE_DATE_, '%Y-%m') AS DATE_,
			DATE_FORMAT(
				date_add(
					CREATE_DATE_,
					INTERVAL 1 MONTH
				),
				'%Y-%m'
			) AS NEXT_DATE_,
			a.MESSAGE_,
			COUNT(a.ID_) AS NUM_
		FROM
			t_project_comment a
		WHERE
			a.STATUS_ > 0
		GROUP BY
			DATE_,
			MESSAGE_
		ORDER BY
			DATE_,
			MESSAGE_
	) a
LEFT JOIN (
	SELECT
		DATE_FORMAT(CREATE_DATE_, '%Y-%m') AS DATE_,
		DATE_FORMAT(
			date_add(
				CREATE_DATE_,
				INTERVAL 1 MONTH
			),
			'%Y-%m'
		) AS NEXT_DATE_,
		a.MESSAGE_,
		COUNT(a.ID_) AS NUM_
	FROM
		t_project_comment a
	WHERE
		a.STATUS_ > 0
	GROUP BY
		DATE_,
		MESSAGE_
	ORDER BY
		DATE_,
		MESSAGE_
) b ON a.NEXT_DATE_ = b.DATE_
AND a.MESSAGE_ = b.MESSAGE_
  1. 用union将“上月数据表”和“下月数据表”合并
SELECT
	a.DATE_,
	a.MESSAGE_,
	a.NUM_,
	a.LAST_DATE_,
	IFNULL(b.NUM_, 0) AS LAST_NUM_
FROM
	(
		SELECT
			DATE_FORMAT(CREATE_DATE_, '%Y-%m') AS DATE_,
			DATE_FORMAT(
				date_sub(
					CREATE_DATE_,
					INTERVAL 1 MONTH
				),
				'%Y-%m'
			) AS LAST_DATE_,
			a.MESSAGE_,
			COUNT(a.ID_) AS NUM_
		FROM
			t_project_comment a
		WHERE
			a.STATUS_ > 0
		GROUP BY
			DATE_,
			MESSAGE_
		ORDER BY
			DATE_,
			MESSAGE_
	) a
LEFT JOIN (
	SELECT
		DATE_FORMAT(CREATE_DATE_, '%Y-%m') AS DATE_,
		DATE_FORMAT(
			date_sub(
				CREATE_DATE_,
				INTERVAL 1 MONTH
			),
			'%Y-%m'
		) AS LAST_DATE_,
		a.MESSAGE_,
		COUNT(a.ID_) AS NUM_
	FROM
		t_project_comment a
	WHERE
		a.STATUS_ > 0
	GROUP BY
		DATE_,
		MESSAGE_
	ORDER BY
		DATE_,
		MESSAGE_
) b ON a.LAST_DATE_ = b.DATE_
AND a.MESSAGE_ = b.MESSAGE_
UNION
	SELECT
		a.NEXT_DATE_ AS DATE_,
		a.MESSAGE_,
		IFNULL(b.NUM_, 0) AS NUM_,
		a.DATE_ AS LAST_DATE_,
		IFNULL(a.NUM_, 0) AS LAST_NUM_
	FROM
		(
			SELECT
				DATE_FORMAT(CREATE_DATE_, '%Y-%m') AS DATE_,
				DATE_FORMAT(
					date_add(
						CREATE_DATE_,
						INTERVAL 1 MONTH
					),
					'%Y-%m'
				) AS NEXT_DATE_,
				a.MESSAGE_,
				COUNT(a.ID_) AS NUM_
			FROM
				t_project_comment a
			WHERE
				a.STATUS_ > 0
			GROUP BY
				DATE_,
				MESSAGE_
			ORDER BY
				DATE_,
				MESSAGE_
		) a
	LEFT JOIN (
		SELECT
			DATE_FORMAT(CREATE_DATE_, '%Y-%m') AS DATE_,
			DATE_FORMAT(
				date_add(
					CREATE_DATE_,
					INTERVAL 1 MONTH
				),
				'%Y-%m'
			) AS NEXT_DATE_,
			a.MESSAGE_,
			COUNT(a.ID_) AS NUM_
		FROM
			t_project_comment a
		WHERE
			a.STATUS_ > 0
		GROUP BY
			DATE_,
			MESSAGE_
		ORDER BY
			DATE_,
			MESSAGE_
	) b ON a.NEXT_DATE_ = b.DATE_
	AND a.MESSAGE_ = b.MESSAGE_

Ps:因为mysql没有全外连接,所以需要用union代替

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值