mysql技术内幕中第二章有几个经典的sql问题。发个博客练习一下
A问题,生日问题,简单的说就是根据当前时间和用户的出生日期,计算他最近的生日(要注意闰月的处理)。
首先导入employees的数据库,从网上找了个教程,引用如下:
MySQL同样提供了employees数据库,但并未随数据库一起安装,其下载链接也极其隐蔽,可能导致许多人没注意到。 下载地址:https://launchpad.net/test-db/employees-db-1/1.0.6 建议大家下载:employees_db-full-1.0.6.tar.bz2,解压缩,进入目录,并导入。安装方法如下:
tar -xjf $HOME/Downloads/employees_db-full-1.0.4.tar.bz2 //解压缩,进入目录 cd employees_db/ //导入数据库root为用户名 mysql -t -u root -p < employees.sql
解决方案如下:
select tmp3.name, tmp3.birth, IF(tmp3.cur2>tmp3.now,tmp3.cur2,tmp3.next2) as birthday from ( select tmp2.*, DATE_ADD(tmp2.cur, INTERVAL IF(DAY(birth)=29&&DAY(cur)=28,1,0) DAY) as cur2, DATE_ADD(tmp2.next,INTERVAL IF(DAY(birth)=29&&DAY(cur)=28,1,0) DAY) as next2 from ( select tmp1.*,DATE_ADD(tmp1.birth,INTERVAL tmp1.diff YEAR) as cur,DATE_ADD(tmp1.birth,INTERVAL tmp1.diff+1 YEAR) as next from ( SELECT CONCAT(t.first_name," ",t.last_name) as name,t.birth_date as birth,now() as now, year(NOW())-YEAR(t.birth_date) as diff from tmp_table t ) tmp1 ) tmp2 )tmp3
B问题为重叠问题。问题是很多时间相关的查询问题要统计和标识出重叠部分。这里涉及三个问题,有标示重叠,分组重叠和最大重叠回话数。
C问题为星期数的问题
1 计算日期是星期几,直接贴查询语句:
set @a="2012-05-24"; SELECT WEEKDAY(@a),DAYOFWEEK(@a),DAYNAME(@a);
结果为 3 5 Thursday
set @a="2012-05-24"; set lc_time_names='zh_CN'; SELECT WEEKDAY(@a),DAYOFWEEK(@a),DAYNAME(@a);
返回结果为:3 5 星期四
set @a="2012-05-24"; SELECT DATEDIFF(@a,'1900-01-04')%7=0;
2按周分组
set @a="2012-05-24"; select @a, DATE_ADD('1900-01-01',INTERVAL floor(DATEDIFF(@a,'1900-01-01')/7*7) DAY) as start, DATE_ADD('1900-01-01',INTERVAL floor(DATEDIFF(@a,'1900-01-01')/7*7+6) DAY) as end
结果为:2012-05-24 2012-05-23 2012-05-29 出现这个结果是因为1900-01-01不是周一。。。
3.计算工作日问题
计算两个日子之间的工作日
直接上代码:
set @s="2005-01-01"; set @e="2006-01-02"; select FLOOR(days/7)*5+days%7-case WHEN 6 BETWEEN wd and wd+days%7-1 then 1 else 0 end-case when 7 BETWEEN wd and wd+days%7-1 then 1 else 0 end from (select DATEDIFF(@e,@s)+1 as days,WEEKDAY(@s)+1 as wd) as A;