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

一般须要考虑两个问题

  • 闰年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

再插入一些数据

INSERT INTO `employees` VALUES ('10001', '1953-12-12', 'Georgi', 'Facello', 'M', '1986-06-26');
INSERT INTO `employees` VALUES ('10002', '1953-11-11', 'Bezalel', 'Simmel', 'F', '1985-11-21');
INSERT INTO `employees` VALUES ('10003', '1959-12-03', 'Parto', 'Bamford', 'M', '1986-08-28');
INSERT INTO `employees` VALUES ('10004', '1954-05-01', 'Chirstian', 'Koblick', 'M', '1986-12-01');
INSERT INTO `employees` VALUES ('10005', '1955-01-21', 'Kyoichi', 'Maliniak', 'M', '1989-09-12');
INSERT INTO `employees` VALUES ('10006', '1953-04-20', 'Anneke', 'Preusig', 'F', '1989-06-02');
INSERT INTO `employees` VALUES ('10007', '1957-05-23', 'Tzvetan', 'Zielinski', 'F', '1989-02-10');
INSERT INTO `employees` VALUES ('10008', '1958-02-19', 'Saniya', 'Kalloufi', 'M', '1994-09-15');
INSERT INTO `employees` VALUES ('10009', '1952-04-19', 'Sumant', 'Peac', 'F', '1985-02-18');
INSERT INTO `employees` VALUES ('10010', '1963-06-01', 'Duangkaew', 'Piveteau', 'F', '1989-08-24');
INSERT INTO `employees` VALUES ('10011', '1972-02-29', 'Jiang', 'David', 'M', '1990-02-20');

查看表中现有数据,然后依据出生日期,以及当前日期(2014-10-31)计算近期生日日期。

编写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子查询加入了一个年龄字段diff,用于子查询b,a的查询结果例如以下

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

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

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

SQL编程之生日问题的更多相关文章

  1. sqL编程篇(三) 游标与存储过程

    sql编程2 游标与存储过程 sql编程中的游标的使用:提供的一种对查询的结果集进行逐行处理的一种方式不用游标的处理解决方式:逐行修改工资update salar set 工资=‘新工资’ where ...

  2. SQL编程篇 (二) 定义与流程控制

    分类: sql编程:标准的sql 编程 * 纯sql 在标准的编程中又分为 sqlserver-->T-sql oracle-->pl-sql(扩展) 变量:在使用变量之前先定义 声明变量 ...

  3. 数据库之SQL编程

    定义局部变量 declare @num int 途径一: 途径二: set 和select赋值方式的区别 唯一区别,如果从数据库表中获取数据,只能用 select ) select @name =st ...

  4. SQL Server(六)——索引、视图和SQL编程

    1.索引 添加索引,设计界面,在任何一列前右键--索引/键--点击进入添加某一列为索引 2.视图 视图就是我们查询出来的虚拟表 创建视图:create view 视图名 as SQL查询语句,分组,排 ...

  5. sql编程小结

    对照mysql5.1手册,对这几天学的sql编程进行小结,主要涉及触发器.存储过程.权限管理.主从分离等,权当抛砖引玉,高手请略过. 一.触发器 通俗的说就是在指定的数据表增删改的前或后触发执行特定的 ...

  6. ORACLE PL/SQL编程详解

    ORACLE PL/SQL编程详解 编程详解 SQL语言只是访问.操作数据库的语言,并不是一种具有流程控制的程序设计语言,而只有程序设计语言才能用于应用软件的开发.PL /SQL是一种高级数据库程序设 ...

  7. SQL编程之高级查询(子查询)以及注意事项

    SQL编程之高级查询(子查询)以及注意事项   1.什么是子查询? 当一个查询是另一个查询的条件时,称之为子查询.子查询可以使用几个简单命令构造功能强大的复合命令.子查询最常用于SELECT-SQL命 ...

  8. SQL Server数据库(SQL Sever语言 函数以及SQL编程)

    1.数学函数:操作一个数据,返回一个结果 --去上限: ceiling ☆select ceiling(price) from car --去下限:floor ☆select floor(price) ...

  9. 自从学了SQL编程,哪里不会点哪里!!!

    在学习SQL编程前,先给大家分享几个段子吧,咱先乐呵乐呵! <桃花庵--程序员版> 写字楼里写字间,写字间中程序员:程序人员写程序,又将程序换酒钱: 酒醒只在屏前坐,酒醉还来屏下眠:酒醉酒 ...

随机推荐

  1. OC本学习笔记Foundation框架NSString与NSMutableString

       一.NSString与NSMutableString         相信大家对NSString类都不陌生.它是OC中提供的字符串类.它的对象中的字符串都是不可变的,而它的子类NSMutable ...

  2. solr/solrj原子更新

    lucene原子更新自己不用多介绍,但solr它的包装,下面是一个简单的介绍是:这个操作是用于索引非常有用. 详细在代码中使用例如以下: /** * 原子更新方式 * */ public static ...

  3. Android 布局管理器

    为了更好地管理Android应用程序的用户界面组件,Android它提供了一个布局管理.通过使用布局管理,Android具有良好的平台无关的图形用户界面应用程序. 平时,推荐布局管理器来管理分布式组件 ...

  4. swift 笔记 (十九) —— 协议

    协议(Protocols) 协议仅是用定义某些任务或者是功能必须的方法和属性. 类似于java里的interface的作用.但协议并不会实现详细的功能. 我猜这个名字源于OO中提到的"契约& ...

  5. cocos2d-x由Jni实现Java与C++打电话给对方

    cocos2d-x由Jni实现Java与C++打电话给对方. cocos2d-x与开发商提供一个类JniHelper,提供java与c++之间的互jni解. 笔者所开发的"史上最坑爹的游戏& ...

  6. REST WebService

    REST WebService 前置技能 ① 使用maven来管理java项目 这个技能必须点一级,以便快速配置项目. 本文实际上是我学习Spring的过程中搬的官网上的demo,使用maven配置项 ...

  7. Ubuntu14.04 工作区设置

    记ubuntu您可以切换工作区,但我按住 Ctrl+Alt+方向键 交换器,有没有反应,在这样的使用切换啊. 原来Ubuntu14.04默认并没有开启,仅仅须要设置一下就OK了. 1.打开系统设置.外 ...

  8. Java并发编程:线程池的使用(转)

    Java并发编程:线程池的使用 在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了, ...

  9. Linux IPC(Inter-Process Communication,进程间通信)之管道学习

    1.标准流管道 管道操作支持文件流模式,用来创建链接还有一个进程的管道,通过函数popen和pclose popen的详细介绍在本blog:Linux 多进程学习中有具体介绍 2.无名管道(PIPE) ...

  10. 仿jQuery之链式调用

    链式调用的形式其实就是对象调用一连串的方法.为什么能连续调用这么多的方法?因为调用方法返回调用的对象,于是乎就可以一如既往,一往无前地调用下去.链式调用的原理就是在方法中返回执行上下文this,每次调 ...