在MySQL查询中计算一个人的年龄——续

DATE_ADD来救援

MySQL知道如何使用Gregorian日历,我相信让MySQL更容易完成工作,而不是试图弄清楚如何实现不同的情况。我选择实施“月末最后一天”技术。在这种情况下,我们将通过创建基于当年3月1日的mysql日期,并从中减去一天来到达2月的最后一天。

如果您使用mysql日期函数阅读我的文章“查找下一个星期一”,您会看到如何使用DATE_ADD()来帮助解决许多问题,即使在您实际使用它减去时该名称可能会产生误导。使用以下测试日期证明mysql已经完全实现了闰年逻辑:

mysql > 选择 DATE_ADD (‘2011-03-01‘,INTERVAL -1 DAY ) ; 
+ ----------------------------------------- + 
| DATE_ADD (‘2011-03-01‘,INTERVAL -1 DAY ) | 
+ ----------------------------------------- + 
| 2011 -02- 28                              | 
+ ----------------------------------------- + 
1行中 集合 (0.00秒)

mysql > 选择 DATE_ADD (‘2012-03-01‘,INTERVAL -1 DAY ) ; 
+ ----------------------------------------- + 
| DATE_ADD (‘2012-03-01‘,INTERVAL -1 DAY ) | 
+ ----------------------------------------- + 
| 2012 -02- 29                              | 
+ ----------------------------------------- + 
1行中 集合 (0.00秒)

mysql > 选择 DATE_ADD (‘2000-03-01‘,INTERVAL -1 DAY ) ;  
+ ----------------------------------------- + 
| DATE_ADD (‘2000-03-01‘,INTERVAL -1 DAY ) | 
+ ----------------------------------------- + 
| 2000 -02- 29                              | 
+ ----------------------------------------- + 
1行中 集合 (0.00秒)

mysql > 选择 DATE_ADD (‘1900-03-01‘,INTERVAL -1 DAY ) ;    
+ ----------------------------------------- + 
| DATE_ADD (‘1900-03-01‘,间隔-1 DAY ) | 
+ ----------------------------------------- + 
| 1900 -02- 28                              | 
+ ----------------------------------------- + 
1行中 集合 (0.00秒)

所以我们需要做的是使用CONCAT()构建正确的字符串以传递给DATE_ADD,我们可以使用YEAR()和我们的硬连线3月1日轻松完成。

SELECT CONCAT ( YEAR ( CURDATE ()),‘ - 03-01‘ ) ; 
+ ----------------------------------- + 
| CONCAT ( YEAR ( CURDATE ()),‘-03-01‘ ) | 
+ ----------------------------------- + 
| 2011年 03                         月1日| 
+ ----------------------------------- + 
1行中 集合 (0.00秒)

这将始终生成相当于当年3月1日的有效mysql日期字符串。现在我们将它替换为DATE_ADD()函数:

SELECT DATE_ADD ( CONCAT ( YEAR ( CURDATE ()),‘ - 03-01‘ ),INTERVAL -1 DAY ) ; 
+ ------------------------------------------------- ------------- + 
| DATE_ADD ( CONCAT ( YEAR ( CURDATE ()),‘-03-01‘ ),间隔-1 DAY ) | 
+ ------------------------------------------------- ------------- + 
| 2011 -02- 28                                                   | 
+ ------------------------------------------------- ------------- + 
1行中 集合 (0.00秒)

当我们在查询中实际使用它时,我们只需要DAY():

SELECT DAY ( DATE_ADD ( CONCAT ( YEAR ( CURDATE ()),‘ - 03-01‘ ),INTERVAL -1 DAY )) ; 
+ ------------------------------------------------- ------------------ + 
| DAY ( DATE_ADD ( CONCAT ( YEAR ( CURDATE ()),‘-03-01‘ ),间隔-1 DAY )) |
+ ------------------------------------------------- ------------------ + 
|                                                                28 | 
+ ------------------------------------------------- ------------------ +

然后我们需要添加一个条件,因此如果用户的生日是2月29日,我们只返回此计算。

SELECT *,IF (个月(生日) = 2和日(生日) = 29,‘飞跃‘,‘正常‘ ) 为弹跳FROM用户; 
+ ---- + --------- + ------------ + -------- + 
| id | 名字     | 生日   | leaper | 
+ ---- + --------- + ------------ + -------- + 
|  1 | 弗兰     | 1967 - 10 - 31 | 正常| 
|  2 | 比尔     | 1964年 - 05 - 07年| 正常| 
|  3 | 吉米   | 1965 -04- 27 | 正常| 
|  4 | Stacy   | 2002 - 11 - 30 | 正常| 
|  5 | 乔治   | 2007 - 10 - 25 | 正常| 
|  6 | Leapie   | 2008 -02-29 | 飞跃   | 
|  7 | BadLeap | 0000-00-00 | 正常| 
+ ---- + --------- + ------------ + -------- + 
7行中 集合 (0.00秒)

由于我们可以看到我们的条件正常工作,剩下的就是插入适当的函数来代替‘Leap‘和‘Normal‘。跳跃将是我们的“3月1日前一天”计算,而“正常”将是原始的DAY(生日)。完成后它可能看起来很神秘,但你可以把它分解成它的组成部分,正如我在本文中所展示的那样,并且希望很明显你可以使用mysql在需要时使用一系列简单的函数来解决相对复杂的问题三元函数。

SELECT *, YEAR ( CURDATE ()) - 
  YEAR (出生日期) - 
     IF ( STR_TO_DATE ( CONCAT ( YEAR ( CURDATE ()), ‘ - ‘ ,月(生日), ‘ - ‘ , 
       IF (个月(生日) = 2 和 DAY (生日) = 29 , 
         DAY( DATE_ADD ( CONCAT ( YEAR ( CURDATE ()), ‘-03-01‘ ), INTERVAL - 1 DAY )),        DAY (出生日期))),‘%Y-%C-%E‘ )> CURDATE (),1 ,0 )AS年龄FROM用户;

+ ---- + --------- + ------------ + ------ + 
| id | 名字     | 生日   | 年龄   | 
+ ---- + --------- + ------------ + ------ + 
|  1 | 弗兰     | 1967 - 10 - 31 |   43 | 
|  2 | 比尔     | 1964年 - 05 - 07年|   47 | 
|  3 | 吉米   | 1965 -04- 27 |   46 | 
|  4 | Stacy   | 2002 - 11 - 30 |    8 | 
|  5 | 乔治   | 2007 - 10 - 25 |    3 | 
|  6 | Leapie   | 2008 -02- 29 |    3 | 
|  7 | BadLeap | 0000-00-00 | 2011 | 
+ ---- + --------- + ------------ + ------ + 
7行中 集合 (0.00秒)

测试边缘情况

有点难以证明这对我们的边缘情况实际上是正确的,所以我们必须人为地用闰年代替curdate()来测试它,这很烦人但是必要。搜索和替换肯定有帮助。

SELECT *,YEAR (‘2011-02-28‘ ) - 
YEAR (出生日期) - 
IF ( STR_TO_DATE ( CONCAT ( YEAR (‘2011-02-28‘ ), ‘ - ‘,MONTH (出生日期),‘ - ‘,
IF (个月(生日) = 2和日(生日) = 29,
DAY ( DATE_ADD ( CONCAT( YEAR (‘2011-02-28‘ ), ‘-03-01‘ ),INTERVAL -1DAY )),
DAY (出生日期))
),‘%Y-%C-%E‘ ) > “2011-02 -28‘,1,0 ) 
AS年龄FROM用户,其中,ID = 6 ; 
+ ---- + -------- + ------------ + ------ + 
| id | 名字   | 生日   | 年龄   | 
+ ---- + -------- + ------------ + ------ + 
|  6 | Leapie | 2008 -02- 29 |    3 | 
+ ---- + -------- + ------------ + ------ + 
1行中 集合 (0.00秒)

这表明即使日期是非闰年的第28天,计算也正确地确定它应该被视为用户的生日。

那么2012年是闰年呢?

SELECT *,YEAR (‘2012-02-28‘ ) - 
YEAR (出生日期) - 
IF ( STR_TO_DATE ( CONCAT ( YEAR (‘2012-02-28‘ ), ‘ - ‘,MONTH (出生日期),‘ - ‘,
IF (个月(生日) = 2和日(生日) = 29,
DAY ( DATE_ADD ( CONCAT( YEAR (‘2012-02-28‘ ), ‘-03-01‘ ),INTERVAL -1DAY )),
DAY (出生日期))
),‘%Y-%C-%E‘ ) > “2012-02 -28‘,1,0 ) 
AS年龄FROM用户,其中,ID = 6 ; 
+ ---- + -------- + ------------ + ------ + 
| id | 名字   | 生日   | 年龄   | 
+ ---- + -------- + ------------ + ------ + 
|  6 | Leapie | 2008 -02- 29 |    3 | 
+ ---- + -------- + ------------ + ------ + 
1行中 集合 (0.00秒)

它正确地确定‘Leapie‘仍然是3!第二天,Leapie享受闰年生日派对:

SELECT *,YEAR (‘2012-02-29‘ ) - 
YEAR (出生日期) - 
IF ( STR_TO_DATE ( CONCAT ( YEAR (‘2012-02-29‘ ), ‘ - ‘,MONTH (出生日期),‘ - ‘,
IF (个月(生日) = 2和日(生日) = 29,
DAY ( DATE_ADD ( CONCAT( YEAR (‘2012-02-29‘ ), ‘-03-01‘ ),INTERVAL -1DAY )),
DAY (出生日期))
),‘%Y-%C-%E‘ ) > “2012-02 -29‘,1,0 ) 
AS年龄FROM用户,其中,ID = 6 ; 
+ ---- + -------- + ------------ + ------ + 
| id | 名字   | 生日   | 年龄   | 
+ ---- + -------- + ------------ + ------ + 
|  6 | Leapie | 2008 -02- 29 |    4 | 
+ ---- + -------- + ------------ + ------ + 
1行中 集合 (0.00秒)

概要

MySQL可用于自动计算任何一天的人的准确年龄,即使对于在闰年2月29日出生的人也是如此。它很快,并且允许您利用MySQL日期类型和相关功能的强大功能,这样您就不必在服务器端代码中执行这些计算。这是查询一次:

SELECT *, YEAR ( CURDATE ()) - 
YEAR (出生日期) - 
IF ( STR_TO_DATE ( CONCAT ( YEAR ( CURDATE ()), ‘ - ‘ ,月(生日), ‘ - ‘ , 
IF (个月(生日) = 2 和 DAY (生日) = 29 , 
DAY (DATE_ADD ( CONCAT ( YEAR ( CURDATE ()), ‘-03-01‘ ), INTERVAL - 1 DAY )), DAY (出生日期))),‘%Y-%C-%E‘ )> CURDATE (),1 ,0 )AS年龄来自用户;

原文地址:https://www.cnblogs.com/xjsp/p/9723249.html

时间: 2024-08-03 07:10:07

在MySQL查询中计算一个人的年龄——续的相关文章

mysql查询中通配符的使用

mysql查询中通配符的使用     在mysql查询中经常会使用通配符,并且mysql的通配符和pgsql的存在区别(稍候再讨论),而且mysql中还可以使用正则表达式. SQL模式匹配: “_” 匹配单个字符,”\_” 匹配”_” “%” 匹配任意个字符,包括零个字符 sql模式下的匹配,缺省是忽略大小写的,并且sql模式下的模糊匹配不能使用“=”或”!=”,而使用 like 或 not like. 例如: SELECT * FROM [user] WHERE u_name LIKE ‘%三

计算一个人的年龄(年月日时分秒),有不对的地方希望大家指出!

想想我们可以做一个计时器,记录一下我们走过了多少时光.看了一下网上别人的一些代码,记录年月的都并不科学,甚至很麻烦,自己倒腾了一上午,总算弄出来了一个. 自己觉得还比较科学,暂时没有发现BUG,如果哪里有错,希望大家指出来! 上代码: <!doctype html><html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /&

mysql查询中限制的表

在mysql中,查询最多七张表 源码后续

在MySQL数据库中创建一个完整的表

1.登陆成功后,首先进入某一个数据库 (不是指数据库服务器) use t1; //t1是数据库名 如图所示: 2.在此数据库中建立数据库表 2.1 先建立表结构(可以理解为表的列名,也就是字段名)在实际生产过程中,表结构是需要经过精心设计的. 通用的语法格式为: 1 CREATE TABLE table_name (column_name column_type); 举例如下: 1 create table tb3( 2 id smallint unsigned auto_increment p

osg::NodeVisitor中计算一个节点对应的世界变换矩阵、法向量、顶点坐标

class MyNodeVisitor:public osg::NodeVisitor { pulic: MyNodeVisitor():osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {} void apply(osg::Geode& geode) { //计算当前geode节点对应的世界变换矩阵,用来计算geode中顶点对应的世界坐标 osg::Matrix geodeMatrix=osg::computeLocalToWo

mysql查询中字符串转换成数字

在操作mysql时,经常需要将字符转换成数字,这一步虽然简单,但不常用的话也很容易忘记,现将在网上找到的方法记录如下: 1.将字符的数字转成数字,比如'0'转成0可以直接用加法来实现例如:将pony表中的d 进行排序,可d的定义为varchar,可以这样解决select * from pony order by (d+0)2.在进行ifnull处理时,比如 ifnull(a/b,'0') 这样就会导致 a/b成了字符串,因此需要把'0'改成0,即可解决此困扰3.比较数字和varchar时,比如a

java中计算一个方法执行时长,耗费单位(秒)

long startTime=System.currentTimeMillis(); //执行方法 long endTime=System.currentTimeMillis(); float excTime=(float)(endTime-startTime)/1000; System.out.println("执行时间:"+excTime+"s");

生产要不要开启MySQL查询缓存

一.前言在当今的各种系统中,缓存是对系统性能优化的重要手段.MySQL Query Cache(MySQL查询缓存)在MySQL Server中是默认打开的,但是网上各种资料以及有经验的DBA都建议生产环境中把MySQL Query Cache关闭.按道理,MySQL Server默认打开,是鼓励用户使用缓存,但是大拿们却建议关闭此功能,并且国内各个云厂商提供的MySQL云服务中默认都是关闭这个功能,这是为什么?他们在使用中遇到了什么坑?本文将会从以下几方面来详解MySQL Query Cach

批量in查询中可能会导致的sql注入问题

有时间我们在使用in或者or进行查询时,为了加快速度,可能会经常这样来使用sql之间的拼接,然后直接导入到一个in中,这种查询实际上性能上还是可以的, 例如如下: update keyword set stats=? where taskid in ('"+CollUtil.toString(list, "','")+"') " 当然这个in里面包含的是一些列的数据()但是如果这些数据中包含一些sql比较敏感的关键词或者符号就会出现sql注入,例如如果in