最近用sqlserver+.NET做一个项目,需求是要用图表来显示数据,而且是每时/每天/每月/每年任取一条数据,即如果用户选择时间的区域是同一天,那么按区域的每小时取一条记录,如果区间是一个月,那么每天任取一条数据,如果区间是一年,每个月任取一条数据。。。。。
开始根本毫无头绪,甚至是想用很暴力的方式解决(多写几条sql语句),最后在别人提供的小demo里面发现了解决方法。
闲话不说,看sql语句:
select *
from tempview a
where not exists(
select 1
from tempview
where convert(varchar(13),receiveTime,120)=convert(varchar(13),a.receiveTime,120) and receiveTime>a.receiveTime
);
先解释下convert函数:convert函数是用来格式化日期的方法(还有其他用处,自查)。第一个参数很明显是最后返回的数据类型及类型长度(重要),第二个就是要格式化的对象,第三个就是要化成的格式值,如:这里的120 代表的是:yyyy-mm-dd hh:mi:ss(24h)。
具体的每个参数代表什么含义,可以访问w3c: http://www.w3school.com.cn/sql/func_convert.asp
为什么第一个参数加了个重要呢,因为类型长度的变化,将是解决问题的核心。
每月: 看一下要化成的格式:yyyy-mm-dd hh:mi:ss 当receiveTime只有年份相同时,我们就能够通过比较月份是否相同来选取月份。这时将长度限制到yyyy(4)就能达到效果:所以SQL语句将变为这样:
select *
from tempview a
where not exists(
select 1
from tempview
where convert(varchar(4),receiveTime,120)=convert(varchar(4),a.receiveTime,120) and receiveTime>a.receiveTime
);
那么同理可得:每月:yyyy-mm varchar(7);
每日:yyyy-mm-dd varchar(10);
每日:yyyy-mm-dd hh varchar(13);
PS:注意应该要先把用户选择范围内的数据先筛选出来,然后再基于这些数据选择,所以上面的SQL语句用的是视图。
注意:上面的SQL语句不算随机取,因为他始终取满足条件的最后一条数据。