如题,在数据量比较大的表中,我们常常需要按时间(年、月或日)分表,加上一个日期的字符串后缀。而这种情形下,当用户给定了起始和结束的时间字符串时,我们就需要根据这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即可)。而这常常应用在跨同类型的、按时间划分(时间作为字符串)
的表查询中。时间字符串的格式依实际情况而定~
相关推荐
(b)改进程序,当第一个字符串包含在第二个字符串中时,显示第一个字符串在第二个字符串中的起始位置。 (c)改进程序,即使当用户输入顺序错误时(第一个是长字符串,第二个是短字符串),能自动在长字符串中搜寻短字符...
设s和t是给定的两个串,在主串s中找到等于子串t的过程称为模式匹配,如果在s中找到等于t的子串,则称匹配成功,函数返回t在s中的首次出现的存储位置(或序号),否则匹配失败,返回-1。t也称为模式。 简单的模式匹配...
如果子字符串存在,则该函数返回子字符串的起始索引,否则如果在字符串(URL)中找不到子字符串,则返回False。 注:strpos() 函数对大小写敏感,区分大小写。 示例:使用strpos()函数在URL中查找特定字符串。 &...
自己写的一个给定两个字符串a和b,及数字n,写出一个函数查找b在a中的第n次出现,成功即返回b第n次出现的起始位置,失败则返回-1。请采用最有效率的方法。在Java和C语言中任选一种,不要使用任何库函数。实现方法
给定一个字符串 s 和一个非空字符串 p,在 s 中找到 p 的字谜的所有起始索引。 字符串仅由小写英文字母组成,字符串 s 和 p 的长度都不会大于 20,100。 输出顺序无关紧要。 示例 1: 输入: s: "cbaebabacd" p: "abc...
6)boolean startsWith(String str):用来判断当前字符串是否是以给定的字符串起始的 boolean endsWith(String str):用来判断当前字符串是否是以给定的字符串结尾的。 7)String toUpperCase() String ...
这是通过为每个小于或等于n的长度确定字典上最后一个子串的S的起始索引和结束索引来完成的,它确定所有O(n)时间中所有此类长度(总计)的S的起始索引和结束索引。 但是,从理论上讲,将所有这些子字符串打印出来...
Example: L:“fooo”, “barr”, “wing”, “ding”, “wing” S:“lingmindraboofooowingdingbarrwingmonkeypoundcake” fooowingdingbarrwing Answer:13 L:“mon”, “key” S:“monkey” ...
438题目:给定一个字符串s和一个非空字符串p,字符串全部由小写字母子组成。 在S中找出所有p对应的anagrams(颠倒)字符串的子串,返回这些子串的起始索引 如s="cbaebabacd" p="abc", 返回结果[0,6] 如s="abab" p=...
#Description 当给定可能的范围时,此模块生成字符串中设置位置内所有可能的字符排列。 ##Usage 要插入字符的位置用“@”表示。 每个位置都必须有一个相应的范围放置在一个平面阵列中。 这些范围可以是任何形式的...
返回字符串中指定表达式的起始位置。 语法 CHARINDEX ( e­xpression1 , e­xpression2 [ , start_location ] ) 参数 e­xpression1 一个表达式,其中包含要寻找的字符的次序。e­xpression1 是一个短...
CHARINDEX 返回字符串中指定表达式的起始位置。...在 expression2 中搜索 expression1 时的起始字符位置。如果没有给定 start_location,而是一个负数或零,则将从 expression2 的起始位置开始搜索。 返回类型 int
1) 起始地址为 string 的主存单元中存放一个字符串(长度大于 6),把 该字符串中的第 1 个和第 6 个字符(字节量)传送给 DX 寄存器; 2) 从主存 buffer 开始的 4 字节中保存了 4 个非压缩 BCD 码,现按低(高) ...
# 给定一个字符串 s 和一些长度相同的单词 words。在 s 中找出可以恰好串联 words 中所有单词的子串的起始位置 # 注意子串要与 words 中的单词完全匹配,中间不能有其他字符,但不需要考虑 words 中单词串联的顺序 #...
给定一个起始值a和一个结束值b ,它在域[0,1]中采用参数t并返回a和b之间的对应插值。 内插器通常返回等效的值,以一个在t = 0和相当于B在t = 1的值。 您不仅可以内插数字,还可以进行内插。 要找到蓝色和棕色之间...
给定一个字符串 s 和一个非空字符串 p,找到 s 中所有是 p 的字母异位词的子串,返回这些子串的起始索引。 字符串只包含小写英文字母,并且字符串 s 和 p 的长度都不超过 20100。 说明: 字母异位词指字母...
():给定起始词、结束词和有效中间词列表,返回最小长度变换,将起始词一次一个字母转换为仅使用有效中间词的结束词。 ():给定城市数量、可用航班列表、起点城市、终点城市和最大中途停留次数,找出从起点城市到...
因此,使用 memcpy 和 strcpy 拷贝字符串在性能上应该没有什么大的差别。 对于非字符串类型的数据的复制来说,strcpy 和 snprintf 一般就无能为力了,可是对 memcpy 却没有什么影响。但是,对于基本数据类型来说...
用 dateutil 灵活的解析 datetime 字符串 给定起始日期后的连续日期 给定起始日期后连续的月末日期 dateutil 灵活的解析 datetime 字符串 使用 Python 内容的 date 或 datetime, 构造它们的实例时需要逐个的传入...
字符串“PAYPALISHIRING”在给定的行数上以锯齿形图案书写 delete_dup_nodes.py - 删除所有具有重复编号的节点 topn_toy.py - 来自推文的 Yopn 玩具 僵尸人类.py - 2D 网格,每个单元格要么是僵尸 1,要么是人类 0 ...