欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

求给定的起始和结束字符串中间的时间字符串集合 博客分类: 数据库 起始结束时间中间时间跨表查询union all 

程序员文章站 2024-03-12 10:52:14
...

如题,在数据量比较大的表中,我们常常需要按时间(年、月或日)分表,加上一个日期的字符串后缀。而这种情形下,当用户给定了起始和结束的时间字符串时,我们就需要根据这2个字符串

判断中间到底跨越了几张同类型的按时间作为后缀的表。。

通常,用union all直接将多个表的查询语句拼接在一条sql里面,而非每张表都分别查询一次,再把结果集给addAll,这样造成跟db的多次交互,影响效率,不太建议……

 

跨表查询的sql拼接思想:

1)先判断起始和结束字符串代表的时间是不是在同一张表,若是,sql里面不用union all操作,一张表的时间between 起始时间and结束时间 即可;

2)若不是同一张表,判断起始和结束之间隔了几张按时间命名的同类型表,sql里循环拼接union all,并只需在起始表里的时间大于等于起始字符串;结束表的时间小于等于结束字符串;中间

拼接的几张表不需要时间过滤;但结束表的也需要union all;

3)每张表的select语句都需用()围起来,再union all成一条sql语句。

 

问题的关键在于,如何搞定如题所示的需求~~  以下为关键的测试代码,特此记录下,以便以后用得着:

public static String DAY_DIMEN = "day";
	public static String MONTH_DIMEN = "month";
	public static String YEAR_DIMEN = "year";
	
	public static List<String> getIntervalPeriods(String startDate, String endDate, String dimen) throws ParseException {
		SimpleDateFormat sdf = new SimpleDateFormat();
		int cVal = 0;
		if(StringUtils.equals(dimen, DAY_DIMEN)) {
			sdf = new SimpleDateFormat("yyyyMMdd");
			cVal = Calendar.DATE;
		}else if(StringUtils.equals(dimen, MONTH_DIMEN)) {
			sdf = new SimpleDateFormat("yyyyMM");
			cVal = Calendar.MONTH;
		}else if(StringUtils.equals(dimen, YEAR_DIMEN)) {
			sdf = new SimpleDateFormat("yyyy");
			cVal = Calendar.YEAR;
		}
		
		Calendar c_begin = Calendar.getInstance();
		Calendar c_end = Calendar.getInstance();
		
		Date d_begin = sdf.parse(startDate);
		Date d_end = sdf.parse(endDate);
		c_begin.setTime(d_begin);
		c_end.setTime(d_end);
		
		List<String> dates = new ArrayList<String>();
		dates.add(startDate);
		while(c_begin.before(c_end)) {
			c_begin.add(cVal, 1);
			String dateStr = sdf.format(c_begin.getTime());
			dates.add(dateStr);
		}
//		dates.add(endDate);
		
		return dates;
	}

 我们使用main方法测试一番:

 

1.测试"天"

List<String> strs = getIntervalPeriods("20151128","20151128",DAY_DIMEN);//测不跨天
System.out.println(strs);
strs = getIntervalPeriods("20150908","20150910",DAY_DIMEN);//测不跨月的天
System.out.println(strs);
strs = getIntervalPeriods("20151128","20151205",DAY_DIMEN);//测跨年跨月的天
System.out.println(strs);

 

运行结果:

[20151128]

[20150908, 20150909, 20150910]

[20151128, 20151129, 20151130, 20151201, 20151202, 20151203, 20151204, 20151205]

 

2.测试"月"

List<String> strs = getIntervalPeriods("201511","201603",MONTH_DIMEN);//测跨年的月
System.out.println(strs);
strs = getIntervalPeriods("201509","201509",MONTH_DIMEN);//测不跨月
System.out.println(strs);
strs = getIntervalPeriods("201509","201512",MONTH_DIMEN);//测不跨年的月
System.out.println(strs);

 

运行结果:

[201511, 201512, 201601, 201602, 201603]

[201509]

[201509, 201510, 201511, 201512]

 

3.测试"年"

List<String> strs = getIntervalPeriods("2015","2018",YEAR_DIMEN);//测跨年
System.out.println(strs);
strs = getIntervalPeriods("2015","2015",YEAR_DIMEN);//测不跨年
System.out.println(strs);

 运行结果:

[2015, 2016, 2017, 2018]

[2015]

 

测试成功,以上的工具代码是十分有用滴,可以准确求出给定起始和结束时间字符串中间的时间字符串(如不需要头尾,remove即可)。而这常常应用在跨同类型的、按时间划分(时间作为字符串)

的表查询中。时间字符串的格式依实际情况而定~