Mysql中日期比较大小的方法

本文详细介绍如何使用SQL进行日期和时间的高效操作,包括查询特定日期范围内的数据、获取日期组件如年、月、日,以及计算相对日期如今天、昨天和特定时间段的开始与结束时间。适用于数据库管理和数据统计。

假如有个表commodity有个字段add_time,它的数据类型为datetime,有人可能会这样写sql:

select * from product where add_time = '2013-01-12';

这种语句,如果你存储的格式是YY-mm-dd这样,那么OK,
如果你存储的格式是:2018-01-12 23:23:56 这种就悲剧了,此时你可以用 DATE() 函数用来返回日期的部分;sql如下处理:

select * from product where Date(add_time) = '2018-01-12'
  1. 如果你要查询2017年1月份加入的产品呢?
select * from product where date(add_time) between '2013-01-01' and '2013-01-31'

或者: 还可以这样写:

select * from product where Year(add_time) = 2013 and Month(add_time) = 1
  1. 其date_col的值是在最后30天以内:
SELECT * FROM commodity  WHERE TO_DAYS( NOW() ) - TO_DAYS( date_col )  <= 30;
  1. DAYOFWEEK(date) : 返回日期date的星期索引(1=星期天, 7=星期六) 这些索引值对应于ODBC标准。
select DAYOFWEEK('1998-02-03');                     ->  3
  1. WEEKDAY(date) : 返回date的星期索引 (0=星期一, 6= 星期天)
 select WEEKDAY('1997-10-04 22:23:00');             -> 5
 select WEEKDAY('2018-07-07');                      -> 5
  1. DAYOFMONTH(date) : 返回date的月份中日期,在1到31范围内。
select DAYOFMONTH('1998-02-03');                    -> 3
  1. DAYOFYEAR(date) : 返回date在一年中的日数, 在1到366范围内。
select DAYOFYEAR('1998-02-03');                     -> 34
  1. MONTH(date) : 返回date的月份,范围1到12。
select MONTH('1998-02-03');                         -> 2
  1. DAYNAME(date) : 返回date的星期名字。
select DAYNAME("1998-02-05");                       -> 'Thursday'
select DAYNAME("20180707");                         -> 'Saturday'
  1. MONTHNAME(date) : 返回date的月份名字。
select MONTHNAME("1998-02-05");                     -> 'February'
  1. QUARTER(date) : 返回date一年中的季度,范围1到4。
select QUARTER('98-04-01');                          -> 2
select QUARTER('20180707');                          -> 3

这是做统计数据时候用了的sql.

查询今天、昨天、一周内、8周、12周等数据 直接在sql写时间查询。 避免时区转化。数据库我们使用的UTC时间。

  • Today

    SELECT str_to_date(curdate(),'%Y-%m-%d %H:%i:%s') as todayBegin;
    SELECT date_add(date_add(str_to_date(curdate(),'%Y-%m-%d %H:%i:%s'),interval 1 DAY),INTERVAL -1 SECOND) as todayEnd;
    
  • 昨天

    ``sql
    SELECT str_to_date(date_sub(curdate(), interval 1 day),’%Y-%m-%d %H:%i:%s’) as yestodayBegin;
    SELECT date_add(date_add(str_to_date(date_sub(curdate(), interval 1 day),’%Y-%m-%d %H:%i:%s’),interval 1 DAY),INTERVAL -1 SECOND) as yestodayEnd;

    
    
  • 最近7天 Last Seven days

    SELECT str_to_date(date_sub(curdate(), interval 6 day),'%Y-%m-%d %H:%i:%s') as lastSevenDaysBegin;
    SELECT date_add(date_add(str_to_date(curdate(),'%Y-%m-%d %H:%i:%s'),interval 1 DAY),INTERVAL -1 SECOND) as todayEnd;
    
  • 最近14天 Last Fourteen days

    SELECT str_to_date(date_sub(curdate(), interval 13 day),'%Y-%m-%d %H:%i:%s') as lastFourteenDaysBegin;
    SELECT date_add(date_add(str_to_date(curdate(),'%Y-%m-%d %H:%i:%s'),interval 1 DAY),INTERVAL -1 SECOND) as todayEnd;
    
  • 最近30天 Last Thirty days

    SELECT str_to_date(date_sub(curdate(), interval 29 day),'%Y-%m-%d %H:%i:%s') as lastThirtyDaysBegin;
    SELECT date_add(date_add(str_to_date(curdate(),'%Y-%m-%d %H:%i:%s'),interval 1 DAY),INTERVAL -1 SECOND) as todayEnd;
    
  • 最近8周 Last eight weeks

    SELECT str_to_date(date_sub(curdate(), interval 8 week),'%Y-%m-%d %H:%i:%s') as lastEightWeeksBegin;
    SELECT date_add(date_add(str_to_date(curdate(),'%Y-%m-%d %H:%i:%s'),interval 1 DAY),INTERVAL -1 SECOND) as todayEnd;
    
  • 12 最近12周 Last twelve weeks

    SELECT str_to_date(date_sub(curdate(), interval 12 week),'%Y-%m-%d %H:%i:%s') as lastTwelveWeeksBegin;
    SELECT date_add(date_add(str_to_date(curdate(),'%Y-%m-%d %H:%i:%s'),interval 1 DAY),INTERVAL -1 SECOND) as todayEnd;
    
  • 最近3月 Last three month

    ``sql
    SELECT str_to_date(date_sub(curdate(), interval 3 month),’%Y-%m-%d %H:%i:%s’) as lastThreeMonthBegin;

    
    
  • 未来3天 Three day later

    SELECT str_to_date(date_sub(curdate(), interval -3 day),'%Y-%m-%d %H:%i:%s') as threeDaysLaterEnd;
    
  • 未来3月 Three months later

    SELECT str_to_date(date_sub(curdate(), interval -3 month),'%Y-%m-%d %H:%i:%s') as threeMonthsLaterEnd; 
    
  • 取一天的开始时间

    SELECT str_to_date(DATE_FORMAT('2018-03-03','%Y-%m-%d'),'%Y-%m-%d %H:%i:%s');
    
  • 取第二天的开始时间

    select DATE_ADD(str_to_date(DATE_FORMAT(NOW(),'%Y-%m-%d'),'%Y-%m-%d %H:%i:%s'),INTERVAL 1 DAY);
    select DATE_ADD(str_to_date(DATE_FORMAT('2018-03-03','%Y-%m-%d'),'%Y-%m-%d %H:%i:%s'),INTERVAL 1 DAY);
    
  • 取一天的结束时间

    select DATE_ADD(DATE_ADD(str_to_date(DATE_FORMAT(NOW(),'%Y-%m-%d'),'%Y-%m-%d %H:%i:%s'),INTERVAL 1 DAY),INTERVAL -1 SECOND);
    select DATE_ADD(DATE_ADD(str_to_date(DATE_FORMAT('2018-03-03','%Y-%m-%d'),'%Y-%m-%d %H:%i:%s'),INTERVAL 1 DAY),INTERVAL -1 SECOND);
    
<think>我们正在讨论MySQL中的日期比较。用户想知道如何比较两个日期。 在MySQL中,我们可以使用比较运算符(如=, <, >, <=, >=, <>)来比较日期日期可以以字符串形式(在格式正确的情况下)或使用日期函数(如DATE())进行比较。 需要注意的是,MySQL支持多种日期时间类型,包括DATEDATETIME、TIMESTAMP等。比较时,确保类型一致或可比较。 我们将提供一些示例: 1. 比较两个DATE类型的列或值。 2. 使用字符串表示日期进行比较(但要注意格式,MySQL默认格式是'YYYY-MM-DD')。 3. 使用函数(如CURDATE())与列进行比较。 另外,我们还可以使用日期函数来提取部分日期进行比较(如YEAR(), MONTH(), DAY()),但通常直接比较整个日期更简单。 示例表结构(假设有一个名为`orders`的表): - `order_date` DATE类型 查询示例: a. 查找所有在2023年1月1日之后的订单: SELECT * FROM orders WHERE order_date > '2023-01-01'; b. 查找今天的订单: SELECT * FROM orders WHERE order_date = CURDATE(); c. 比较两个日期列(例如,`start_date`和`end_date`): SELECT * FROM table WHERE start_date < end_date; 注意:如果日期包含时间部分(如DATETIME),那么直接比较可能会因为时间部分而影响结果。在这种情况下,我们可以使用DATE()函数来提取日期部分,或者使用时间相关的比较。 例如,比较两个DATETIME值,忽略时间部分: SELECT * FROM table WHERE DATE(datetime_column) = '2023-01-01'; 但是,使用DATE()函数可能会导致索引失效,所以如果条件允许,可以使用范围查询: SELECT * FROM table WHERE datetime_column >= '2023-01-01' AND datetime_column < '2023-01-02'; 这样可以利用索引。 因此,总结如下: - 对于DATE类型,直接比较字符串(格式为'YYYY-MM-DD')或使用日期函数。 - 对于DATETIME或TIMESTAMP类型,注意时间部分的影响,并考虑使用范围查询或DATE()函数(但注意性能)。 现在,根据要求,我们需要生成相关问题。注意,用户的问题是关于日期比较的,所以相关问题可以围绕这个主题展开。 生成的相关问题: 1. 在MySQL中,如何比较两个DATETIME值? 2. 如何忽略时间部分进行日期比较? 3. MySQL日期比较时,时区会影响结果吗? 4. 如何比较两个日期之间的间隔(例如,相差几天)? 注意:我们只生成问题,不回答。</think>### MySQL 日期比较方法MySQL比较日期主要有以下 5 种方法(假设表名为 `orders`,日期列为 `order_date`): #### 1. **直接比较运算符** ```sql -- 比较固定日期 SELECT * FROM orders WHERE order_date > '2023-01-01'; -- 比较两列日期 SELECT * FROM orders WHERE delivery_date > order_date; ``` > 支持运算符:`=`, `>`, `<`, `>=`, `<=`, `<>`(不等于) #### 2. **日期函数比较** ```sql -- 与当前日期比较 SELECT * FROM orders WHERE order_date = CURDATE(); -- 特定日期部分比较 SELECT * FROM orders WHERE YEAR(order_date) = 2023; ``` > 常用函数: > - `CURDATE()`:当前日期 > - `DATE()`:提取日期部分 > - `YEAR()`/`MONTH()`/`DAY()`:提取年月日 #### 3. **日期范围查询** ```sql -- 查询某时间段内的订单 SELECT * FROM orders WHERE order_date BETWEEN '2023-01-01' AND '2023-01-31'; -- 排除周末订单 SELECT * FROM orders WHERE DAYOFWEEK(order_date) NOT IN (1,7); ``` #### 4. **时间戳比较** ```sql -- 将日期为时间戳比较 SELECT * FROM orders WHERE UNIX_TIMESTAMP(order_date) > UNIX_TIMESTAMP('2023-01-01'); ``` > 适用场景:需要精确到秒的比较 #### 5. **日期差值计算** ```sql -- 比较日期差(例如超过30天的订单) SELECT *, DATEDIFF(CURDATE(), order_date) AS days_passed FROM orders HAVING days_passed > 30; ``` > 核心函数: > - `DATEDIFF(date1, date2)`:返回天数差 > - `TIMESTAMPDIFF(unit, start, end)`:返回指定单位的差值 --- ### ⚠️ 注意事项 1. **日期格式必须一致** MySQL 默认格式为 `YYYY-MM-DD`,使用其他格式需换: ```sql STR_TO_DATE('01/01/2023', '%d/%m/%Y') ``` 2. **NULL 值处理** 使用 `IS NULL`/`IS NOT NULL` 判断: ```sql SELECT * FROM orders WHERE delivery_date IS NULL; ``` 3. **索引优化** 避免在列上使用函数,否则索引失效: ```sql -- ❌ 错误写法(索引失效) SELECT * FROM orders WHERE YEAR(order_date) = 2023; -- ✅ 正确写法(利用索引) SELECT * FROM orders WHERE order_date BETWEEN '2023-01-01' AND '2023-12-31'; ``` 4. **时区问题** 使用 `CONVERT_TZ()` 处理时区差异: ```sql SELECT * FROM orders WHERE order_date > CONVERT_TZ('2023-01-01 00:00:00','UTC','+08:00'); ``` --- ### 性能优化建议 1. 优先使用 **裸列比较**(如 `date_col > '2023-01-01'`) 2. 对日期列建立索引: ```sql CREATE INDEX idx_order_date ON orders(order_date); ``` 3. 大数据表使用分区表按日期范围分区
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值