sql陈列查询连续不断的两个时间,或者两个日期之间的列表

报表统计时,一张表中的数据往往存在时间间断的情况,报表呈现的效果需要连续不断的,这种情况可以在代码层对缺失的时间数据进行补充。
也可以在sql中查询出连续不断的时间,作为虚拟主表,联表查询报表数据

记录一下sql处理的情况

1. 查询连续不断的小时时间列表

  • 这里是利用储存过程中执行while函数,将0时到当前小时的时间,拼接成连续字符串,然后借用mysql默认的mysql.help_topic表,将字符串以列的形式进行拆分展现
-- 储存过程存在则删除
DROP PROCEDURE IF EXISTS test_while_001;
-- 获取当前最大小时值(24小时制) 
-- SELECT FROM_UNIXTIME( UNIX_TIMESTAMP(), '%k' ); %k %H均表示24小时制小时
-- 当前时间
SET @maxHours = ( SELECT date_format( NOW( ), '%H' ) );
SET @hours = '0';

-- 定义函数,创建储存过程
DELIMITER $$
CREATE PROCEDURE test_while_001 ( ) BEGIN
	DECLARE
		i INT DEFAULT 0;
	WHILE
			i < @maxHours DO
			SET i = i + 1;
			SET @hours := CONCAT(@hours, "," ,i);
	END WHILE;
	
		/*** 此sql陈列小时列表,亦在此写入业务sql***/
		-- 借用mysql中默认表,help_topic将小时字符串,拆分成列表记录
		select substring_index(substring_index( @hours,',',help_topic_id+1),',',-1) as hours
		from mysql.help_topic
		--  此处left join 业务表,即可接入业务
		where help_topic_id<(length( @hours)-length(replace( @hours,',',''))+1);
		//sql结束忘了分号结束,不然sql报错
END $$
DELIMITER;
CALL test_while_001 ( );
  • 以上是以储存过程结合help_topic实现,以下是单独利用mysql的help_topic表,将时间以入参形式传入,效果与上面一样
		--  SET @date =  "1,2,3,4,....";
	   example: #{时间字符串组} = "1,2,3,4,....";

		select substring_index(substring_index( #{时间字符串组},',',help_topic_id+1),',',-1) as businessAt
		from mysql.help_topic
		--  left join 业务表,即可接入业务查询
		where help_topic_id<(length(  #{时间字符串组})-length(replace( #{时间字符串组},',',''))+1)

以下是sql执行的结果
在这里插入图片描述

- 2.sql查询连续不断的日期列表

  • 使用储存过程+help_topic实现
-- 储存过程存在则删除
DROP PROCEDURE IF EXISTS test_while_001;
-- 昨日日期
SET @endDate = (select DATE_SUB(curdate(),INTERVAL 1 DAY)) ;

SET @startDate = (select DATE_SUB(curdate(),INTERVAL 10 DAY)) ;

-- SET @startDate = (SELECT FROM_UNIXTIME(MIN(business_at),"%Y-%m-%d")  FROM ms_score_flow);

SET @dateDistance = (SELECT DATEDIFF(@endDate,@startDate));
SET @varDate=@endDate;

-- 定义函数,创建储存过程
DELIMITER $$
CREATE PROCEDURE test_while_001 ( ) BEGIN
	DECLARE
		i INT DEFAULT 1;
	WHILE
			i < @dateDistance DO
			SET i = i + 1;
			SET @varDate := CONCAT(@varDate, "," ,(select DATE_SUB(curdate(),INTERVAL i DAY)));
	END WHILE;
	
		/*** 此sql陈列日期列表,亦在此写入业务sql ***/
		-- 借用mysql中默认表,help_topic将小时字符串,拆分成列表记录
		select substring_index(substring_index( @varDate,',',help_topic_id+1),',',-1) as hours
		from mysql.help_topic
		-- left join 业务表接入业务数据
		where help_topic_id<(length( @varDate)-length(replace( @varDate,',',''))+1);
	
END $$
DELIMITER;
CALL test_while_001 ( );
  • 以下sql是基于参考博客改动:https://blog.csdn.net/longvs/article/details/22745433
	-- 昨天的日期
SET @MAX_DATE = DATE_SUB( curdate( ), INTERVAL 1 DAY );

-- 业务表中最早的日期
-- SET @MIN_DATE = ( SELECT FROM_UNIXTIME( MIN( created_at ), '%Y-%m-%d' ) FROM 业务 TABLE );
SET @MAX_DATE = DATE_SUB( curdate( ), INTERVAL 7 DAY );

SET @i = - 1;
SET @SQL =
REPEAT
		( " select 1 union all",- datediff( @MIN_DATE, @MAX_DATE ) + 1 );
	
	SET @SQL = LEFT ( @SQL, length( @SQL ) - length( " union all" ) );
	
	-- --业务结合部分  开始----
	SET @SQL = concat( "select date_add(@MIN_DATE,interval @i:=@i+1 day) as businessAt from (", @SQL, ") as tmp" );
	-- --业务结合部分-结束----
	PREPARE stmt 
	FROM
		@SQL;
	EXECUTE stmt 
	
	-- ------不计入上面的sql,替换业务结合部分,即可结合业务查询----------------------
	SET @SQL = concat( "SELECT aws.businessAt,mafd.business_at FROM (
		-- 查询出最大日期与最小日期,之间的全部日期
		select date_add(@MIN_DATE,interval @i:=@i+1 day) as businessAt from (", @SQL, ") as tmp
		) aws
	LEFT JOIN ms_analysis_fans_day mafd ON mafd.business_at = aws.businessAt WHERE mafd.business_at IS NULL" );
	PREPARE stmt 
FROM
	@SQL;
  • 这种写法也可以将查询出的日期列表作为虚拟主表,但是对于加入查询条件有点不友好(个人能力有限没能完美使用)
    以下是查询结果
    在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值