程序员人生 网站导航

SQL编程之生日问题

栏目:互联网时间:2014-11-03 08:22:55

在学习MySQL的时候,1个较为经典的SQL编程题目就是生日问题,已知某个用户的诞生日期和当前日期,计算他最近的生日。

1般需要斟酌两个问题

  • 闰年2月是29天
  • 今年的生日是不是过完

例如:某人的生日是1992年2月29日,当前若当前日期是2004年1月2日,那末他的最近生日是2004年2月29日;若当前日期是2004年3月3日,那末他最近的生日则是2005年3月1日。

现在,利用SQL编程解决这个求生日的问题。

创建employees表

Create Table: CREATE TABLE `employees` ( `emp_no` int(11) NOT NULL, `birth_date` date NOT NULL, `first_name` varchar(14) NOT NULL, `last_name` varchar(16) NOT NULL, `gender` enum('M','F') NOT NULL, `hire_date` date NOT NULL, PRIMARY KEY (`emp_no`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1

再插入1些数据

INSERT INTO `employees` VALUES ('10001', '1953⑴2⑴2', 'Georgi', 'Facello', 'M', '1986-06⑵6'); INSERT INTO `employees` VALUES ('10002', '1953⑴1⑴1', 'Bezalel', 'Simmel', 'F', '1985⑴1⑵1'); INSERT INTO `employees` VALUES ('10003', '1959⑴2-03', 'Parto', 'Bamford', 'M', '1986-08⑵8'); INSERT INTO `employees` VALUES ('10004', '1954-05-01', 'Chirstian', 'Koblick', 'M', '1986⑴2-01'); INSERT INTO `employees` VALUES ('10005', '1955-01⑵1', 'Kyoichi', 'Maliniak', 'M', '1989-09⑴2'); INSERT INTO `employees` VALUES ('10006', '1953-04⑵0', 'Anneke', 'Preusig', 'F', '1989-06-02'); INSERT INTO `employees` VALUES ('10007', '1957-05⑵3', 'Tzvetan', 'Zielinski', 'F', '1989-02⑴0'); INSERT INTO `employees` VALUES ('10008', '1958-02⑴9', 'Saniya', 'Kalloufi', 'M', '1994-09⑴5'); INSERT INTO `employees` VALUES ('10009', '1952-04⑴9', 'Sumant', 'Peac', 'F', '1985-02⑴8'); INSERT INTO `employees` VALUES ('10010', '1963-06-01', 'Duangkaew', 'Piveteau', 'F', '1989-08⑵4'); INSERT INTO `employees` VALUES ('10011', '1972-02⑵9', 'Jiang', 'David', 'M', '1990-02⑵0');

查看表中现有数据,然后根据诞生日期,和当前日期(2014⑴0⑶1)计算最近生日日期。



编写SQL,计算最近生日日期

select name,birthday, if(cur>today,cur,next) as birth_day from ( select name,birthday,today, date_add(cur , interval if( day(birthday) = 29 && day(cur) = 28 , 1 , 0 ) day ) as cur, date_add(next , interval if( day(birthday) = 29 && day(cur) = 28 , 1 , 0 ) day ) as next from ( select name,birthday,today, date_add(birthday,interval diff year) as cur, date_add(birthday,interval diff+1 year) as next from ( select concat(last_name,' ',first_name) as name, birth_date as birthday, ( year(now()) - year(birth_date) ) as diff, now() as today from employees ) as a ) as b ) as c;

以上这段SQL程序的输出



分析:

其中使用了3个子查询a、b、c

a子查询添加了1个年龄字段diff,用于子查询b,a的查询结果以下



子查询b计算了,今年的生日日期cur和明年的生日日期next,b的查询结果以下:



注意:这里对闰月的处理是2月28日(依照法律规定,闰年29日的生日在非闰年应当为3月1日),所以子查询c用于处理闰月的问题,c的查询结果以下:



最后,需要判断当前日期是不是大于今年的生日(今年是不是过完了生日),然后选取最近的生日,最后的答案是:





------分隔线----------------------------
------分隔线----------------------------

最新技术推荐