0
点赞
收藏
分享

微信扫一扫

Mysql中求出生日

知年_7740 2022-01-28 阅读 36


Mysql中求出生日【待完善】

1.需求

给出一个出生表,求出某人的最近生日。

2.背景

  • 创建表employee
CREATE TABLE `employee` (
`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

  • 插入表数据【此处省略】
  • 查看其中表的数据

mysql> select * from employee;
+--------+------------+------------+-----------+--------+------------+
| emp_no | birth_date | first_name | last_name | gender | hire_date |
+--------+------------+------------+-----------+--------+------------+
| 10001 | 1953-09-02 | Georgi | Facello | M | 1986-06-26 |
| 10002 | 1964-06-02 | Bezalel | Simmel | F | 1985-11-21 |
| 10003 | 1959-12-03 | Parto | Bamford | M | 1986-08-28 |
| 10004 | 1954-05-01 | Chirstian | Koblick | M | 1986-12-01 |
| 10005 | 1955-01-21 | Kyoichi | Maliniak | M | 1989-09-12 |
| 10006 | 1953-04-20 | Anneke | Preusig | F | 1989-06-02 |
| 10007 | 1957-05-23 | Tzvetan | Zielinski | F | 1989-02-10 |
| 10008 | 1958-02-19 | Saniya | Kalloufi | M | 1994-09-15 |
| 10009 | 1952-04-19 | Sumant | Peac | F | 1985-02-18 |
| 10010 | 1963-06-01 | Duangkaew | Piveteau | F | 1989-08-24 |
| 10011 | 1972-02-29 | Jiang | David | M | 1990-02-20 |
+--------+------------+------------+-----------+--------+------------+
11 rows in set (0.00 sec)

3.代码

select 
name
,birth_date
,if(now() < cur,cur,next) as result
from
(
select
name
,birth_date
,DATE_ADD(cur,INTERVAL if(day(birth_date)=29 && day(cur) = 28 ,1,0) day) as cur
,DATE_ADD(next,INTERVAL if(day(birth_date)=29 && day(cur) = 28 ,1,0) day) as next
FROM
(
select
name
,birth_date
,date_add(birth_date,interval diff year) as cur
,date_add(birth_date,interval diff+1 year) as next
,date(now())
from
(
select
concat(first_name,' ',last_name) as name
,birth_date
,(year(now())-year(birth_date)) as diff
from employee
)as a
)as b
)as c

4.执行结果

+--------------------+------------+------------+
| name | birth_date | result |
+--------------------+------------+------------+
| Georgi Facello | 1953-09-02 | 2019-09-02 |
| Bezalel Simmel | 1964-06-02 | 2019-06-02 |
| Parto Bamford | 1959-12-03 | 2018-12-03 |
| Chirstian Koblick | 1954-05-01 | 2019-05-01 |
| Kyoichi Maliniak | 1955-01-21 | 2019-01-21 |
| Anneke Preusig | 1953-04-20 | 2019-04-20 |
| Tzvetan Zielinski | 1957-05-23 | 2019-05-23 |
| Saniya Kalloufi | 1958-02-19 | 2019-02-19 |
| Sumant Peac | 1952-04-19 | 2019-04-19 |
| Duangkaew Piveteau | 1963-06-01 | 2019-06-01 |
| Jiang David | 1972-02-29 | 2019-03-01 |
+--------------------+------------+------------+
11 rows in set (0.04 sec)

5.分析

上述代码的精妙之处在于:


  • 没有自己实现一个闰年判断,而是借助系统的日期功能,顺带往后推了一段时间,这样就减少了很多麻烦。归根结底,这里还是用到了一个“构造变量”的思想,重新生成一列,然后重新生成的这列有很大的用处!
  • 当然,这里也使用到了一部分的函数,比如​​if()​​,​​date_add()​​,​​day()​​,​​concat()​​,​​year()​​,​​now()​​等。下面我逐一讲解这些函数的使用。
    • if()函数


mysql> select if(2>1,2,1);
+-------------+
| if(2>1,2,1) |
+-------------+
| 2 |
+-------------+
1 row in set (0.00 sec)

之前,我一直在考虑将日期部分的年取出来,然后我使用​​substring()​​函数,然后再强转成int型,最后做一个减法,就知道当前年到出生年之间的时间间隔了。但是这一切所有的步骤均可以通过一个函数实现: =>year函数:将一个日期取出年部分;同样,day()函数是取出一个日期中的日,month()函数是取出月部分。

  • year()函数
mysql> select year(current_timestamp);
+-------------------------+
| year(current_timestamp) |
+-------------------------+
| 2018 |
+-------------------------+
1 row in set (0.00 sec)
  • month()函数
mysql> select month(current_timestamp);
+--------------------------+
| month(current_timestamp) |
+--------------------------+
| 9 |
+--------------------------+
1 row in set (0.00 sec)
  • day()函数
mysql> select day(current_timestamp);
+------------------------+
| day(current_timestamp) |
+------------------------+
| 9 |
+------------------------+
1 row in set (0.00 sec)

因为最近的生日要么是今年,要么是明年,所以再根据diff+1生成明年的日期【在生成日期时,就考虑到了闰年的问题,根据法律的规定,如果闰年的生日在2/29,那么在平年的生日就是3/1】针对这个规定,就得到了如下的SQL语句。

select 
concat(first_name,' ',last_name) as name
,(year(now())-year(birth_date)) as diff
from employee;

+--------------------+------+
| name | diff |
+--------------------+------+
| Georgi Facello | 65 |
| Bezalel Simmel | 54 |
| Parto Bamford | 59 |
| Chirstian Koblick | 64 |
| Kyoichi Maliniak | 63 |
| Anneke Preusig | 65 |
| Tzvetan Zielinski | 61 |
| Saniya Kalloufi | 60 |
| Sumant Peac | 66 |
| Duangkaew Piveteau | 55 |
| Jiang David | 46 |
+--------------------+------+
11 rows in set (0.00 sec)



举报

相关推荐

0 条评论