mysql按天分组统计,没有数据补0的解决方法

1、查询2019-01-10至2019-01-25时间段的数据如下 :

SQL语句为:

SELECT DATE_FORMAT(z.create_date,'%Y-%m-%d') AS days, IFNULL(SUM(z.difMinute)/(SUM(z.dailyLoadTime)*SUM(z.difDays)),0) AS "AR",IFNULL(SUM(z.goodQuant)/(SUM(z.dailyProduceQuant)*SUM(z.difDays)),0) AS "PR", 
			IFNULL(SUM(z.goodQuant)/SUM(z.goodQuant+z.workWasteQuant+z.materialWasteQuant+z.otherQuant),0) AS "QR",z.difDays
FROM (
	SELECT a.id,
		mrfc.create_date,
		IFNULL(mrfc.good_quant,0) AS "goodQuant",
		IFNULL(mrfc.work_waste_quant,0) AS "workWasteQuant",
		IFNULL(mrfc.material_waste_quant,0) AS "materialWasteQuant",
		IFNULL(mrfc.other_quant,0) AS "otherQuant",
		a.device_code,
		a.device_name,
		a.device_status,
		IFNULL(a.daily_load_time,0) AS "dailyLoadTime",
		IFNULL(a.daily_produce_quant,0) AS "dailyProduceQuant",
		a.corp_id,
		a.status_flag,
		(UNIX_TIMESTAMP(mrfc.create_date) - UNIX_TIMESTAMP(b.create_date))/60  AS 'difMinute',
		(DATEDIFF(mrfc.create_date,b.create_date)+1) AS 'difDays'
	FROM mes_report_flow_card mrfc
	LEFT JOIN mes_device a ON a.id = mrfc.device_id1
	LEFT JOIN mes_report_flow_card b ON b.id = mrfc.report_start_id 
	WHERE mrfc.create_date BETWEEN '2019-01-10 10:33' AND '2019-01-25 10:33' 
		AND mrfc.is_report='1' AND mrfc.report_start_id IS NOT NULL AND mrfc.report_start_id != ""
	UNION 
	SELECT a.id,
		mrpwo.create_date,
		IFNULL(mrpwo.good_quant,0) AS "goodQuant",
		IFNULL(mrpwo.work_waste_quant,0) AS "workWasteQuant",
		IFNULL(mrpwo.material_waste_quant,0) AS "materialWasteQuant",
		IFNULL(mrpwo.other_quant,0) AS "otherQuant",
		a.device_code,
		a.device_name,
		a.device_status,
		IFNULL(a.daily_load_time,0) AS "dailyLoadTime",
		IFNULL(a.daily_produce_quant,0) AS "dailyProduceQuant",
		a.corp_id,
		a.status_flag,
		(UNIX_TIMESTAMP(mrpwo.create_date) - UNIX_TIMESTAMP(b.create_date))/60  AS 'difMinute',
		(DATEDIFF(mrpwo.create_date,b.create_date)+1) AS 'difDays'
	FROM mes_report_part_work_order mrpwo
	LEFT JOIN mes_device a ON a.id = mrpwo.device_id
  LEFT JOIN mes_report_part_work_order b ON b.id = mrpwo.report_start_id 
	WHERE mrpwo.create_date BETWEEN '2019-01-10 10:33' AND '2019-01-25 10:33'
		AND mrpwo.is_report='1' AND mrpwo.report_start_id IS NOT NULL AND mrpwo.report_start_id != ""
) AS z 
WHERE z.status_flag = '0' AND z.corp_id ='c81e820bb5874031addd8ceb7f5baf44' 
AND z.device_status = '1' AND z.id = '9360f9fbc41d4f72a6df1f6aa0500f37'
GROUP BY days;

查询结果显示:如果哪天没有数据,那天就没有记录 。而我需要用数据来展示echarts的Line图,还要根据有记录那天的数据去推算它前几天的数据。总结来说,我所要的是如果哪天没有数据,就要补0!

2、下面就是解决方法

我先生成一个日历表calendar,在原来数据的基础上再右外连接日历表。这样就能展示where条件中时间段内每天的数据,没有数据的用IFNULL(字段,0)函数就能用0代替空数据。

2.1 执行sql生成从1900-01-01起的十万条数据

CREATE TABLE num (i int);-- 创建一个表用来储存0-9的数字
INSERT INTO num (i) VALUES (0), (1), (2), (3), (4), (5), (6), (7), (8), (9);-- 生成0-9的数字,方便以后计算时间
CREATE TABLE  if not exists calendar(datelist date); -- 生成一个存储日期的表,datalist是字段名
-- 这里是生成并插入日期数据
INSERT INTO calendar(datelist) SELECT
	adddate(
			(   -- 这里的起始日期,你可以换成当前日期
					DATE_FORMAT("1900-1-1", '%Y-%m-%d') 
			),
			numlist.id
	) AS `date`
FROM
	(
			SELECT
					n1.i + n10.i * 10 + n100.i * 100 + n1000.i * 1000+ n10000.i * 10000 AS id
			FROM
					num n1
			CROSS JOIN num AS n10
			CROSS JOIN num AS n100
			CROSS JOIN num AS n1000
			CROSS JOIN num AS n10000
	) AS numlist;

 生成calendar表后,删除num的临时表。

2.2  最后联合查询的SQL语句

SELECT DATE_FORMAT(c.datelist,'%Y-%m-%d') AS "days", IFNULL(SUM(z.difMinute)/(SUM(z.dailyLoadTime)*SUM(z.difDays)),0) AS "AR",IFNULL(SUM(z.goodQuant)/(SUM(z.dailyProduceQuant)*SUM(z.difDays)),0) AS "PR", 
	IFNULL(SUM(z.goodQuant)/SUM(z.goodQuant+z.workWasteQuant+z.materialWasteQuant+z.otherQuant),0) AS "QR",z.difDays
FROM (
	SELECT * FROM (
		SELECT a.id,
		mrfc.create_date,
		IFNULL(mrfc.good_quant,0) AS "goodQuant",
		IFNULL(mrfc.work_waste_quant,0) AS "workWasteQuant",
		IFNULL(mrfc.material_waste_quant,0) AS "materialWasteQuant",
		IFNULL(mrfc.other_quant,0) AS "otherQuant",
		a.device_code,
		a.device_name,
		a.device_status,
		IFNULL(a.daily_load_time,0) AS "dailyLoadTime",
		IFNULL(a.daily_produce_quant,0) AS "dailyProduceQuant",
		a.corp_id,
		a.status_flag,
		(UNIX_TIMESTAMP(mrfc.create_date) - UNIX_TIMESTAMP(b.create_date))/60  AS 'difMinute',
		(DATEDIFF(mrfc.create_date,b.create_date)+1) AS 'difDays'
	FROM mes_report_flow_card mrfc
	LEFT JOIN mes_device a ON a.id = mrfc.device_id1
	LEFT JOIN mes_report_flow_card b ON b.id = mrfc.report_start_id 
	WHERE mrfc.is_report='1' AND mrfc.report_start_id IS NOT NULL AND mrfc.report_start_id != ""
	UNION
	SELECT a.id,
		mrpwo.create_date,
		IFNULL(mrpwo.good_quant,0) AS "goodQuant",
		IFNULL(mrpwo.work_waste_quant,0) AS "workWasteQuant",
		IFNULL(mrpwo.material_waste_quant,0) AS "materialWasteQuant",
		IFNULL(mrpwo.other_quant,0) AS "otherQuant",
		a.device_code,
		a.device_name,
		a.device_status,
		IFNULL(a.daily_load_time,0) AS "dailyLoadTime",
		IFNULL(a.daily_produce_quant,0) AS "dailyProduceQuant",
		a.corp_id,
		a.status_flag,
		(UNIX_TIMESTAMP(mrpwo.create_date) - UNIX_TIMESTAMP(b.create_date))/60  AS 'difMinute',
		(DATEDIFF(mrpwo.create_date,b.create_date)+1) AS 'difDays'
	FROM mes_report_part_work_order mrpwo
	LEFT JOIN mes_device a ON a.id = mrpwo.device_id
		LEFT JOIN mes_report_part_work_order b ON b.id = mrpwo.report_start_id 
	WHERE mrpwo.is_report='1' AND mrpwo.report_start_id IS NOT NULL AND mrpwo.report_start_id != ""
	) AS y
	WHERE y.create_date BETWEEN '2019-01-10 10:33' AND '2019-01-25 10:33'
		AND y.status_flag = '0' AND y.corp_id ='c81e820bb5874031addd8ceb7f5baf44' 
		AND y.device_status = '1' AND y.id = '9360f9fbc41d4f72a6df1f6aa0500f37'
) AS z 
RIGHT JOIN calendar c ON c.datelist = DATE(z.create_date)
WHERE c.datelist BETWEEN DATE('2019-01-10 10:33') AND DATE('2019-01-25 10:33')
GROUP BY days

查询结果为:

mysql按天分组统计,没有数据补0的解决方法_第1张图片

关键行:RIGHT JOIN calendar c ON c.datelist = DATE(z.create_date)

 

 

 

你可能感兴趣的:(数据库)