SQL编程之生日问题,sql编程生日
在学习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的查询结果如下:
最后,需要判断当前日期是否大于今年的生日(今年是否过完了生日),然后选取最近的生日,最后的答案是:
没看明白,按我的理解做吧
我也不怎么会,有的语句位置可能不对
begin
@cc int
@dd int
@s int
set cc=1
set dd=1
while cc<=5
begin
s=cc*dd
cc=cc+1
dd=dd+1
end
print s
end
用下面的语句来试试吧:
create table classname
(
id int identity(100,1) primary key,
name char(8) not null,
number char(13),
sex char(6),
)
就是这么简单,上面的程序可以按照你的意愿定制。下面我来描述一下定制时需要注意的问题:
第一,自动编号增加用identity(a,b)这个语句,其中a代表初始值,b代表每次增加量,上例中identity(100,1)表示,从100开始加起,每次加一,这样以后就是100,101,102....。需要注意的是identity(a,b)这句话只适用于以下类型:tinyint、smallint、int、decimal(p,0)、numeric(p,0),如果用于其它类型会报错误,还要注意的是一个表中只允许一个列声明为identity属性。
第二:not null表示此列不允许为空,如果后面没有写not null,则表示数据库系统不对此列追加空属约束,也就是这列可以为空,就是什么都不记录也可以。
第三:primary key语句用来声明为主键值。需要注意以下几点问题,每一个表仅能有一个主键值;主键值不可以为null;主键值的列不可以再被声明为unique constraint的约束;image和text类型的列不能当作主键值的列;主键值具有索引的作用,可以用来快速查询表内的数据。
好了,这里只是简单的讲解,我觉得上面的讲解中肯定有很多专业名词或许大家没有见过,那么留给大家自己学习吧,建表的语句庞大而丰富,上面的例子只是最基础最常用的写法,除此之外我们还可以利用其他语句建出各种满足自己需求的表来。大家可以针对上面的不懂的专业名词和建表的其他语句上网查找,会有很丰富的讲解。
祝你好运