显式日期/日期时间

时间:2013-07-23 09:03:51

标签: mysql datetime mysql-5.5

BETWEEN文档说明(http://dev.mysql.com/doc/refman/5.5/en/comparison-operators.html#operator_between)中,我注意到一个我无法完全理解的奇怪表达:

  

为了将BETWEEN与日期或时间值一起使用时获得最佳结果,请使用CAST()将值显式转换为所需的数据类型。示例:如果将DATETIME与两个DATE值进行比较,请将DATE值转换为DATETIME值。如果在与DATE的比较中使用字符串常量(如“2001-1-1”),则将字符串强制转换为DATE。

所以我有以下问题:

  1. 任何人都可以提供一个示例非常必要(有解释),以及cast何时会显着改变结果或性能。假设我们使用mysql定义的日期文字数量之一(http://dev.mysql.com/doc/refman/5.5/en/date-and-time-literals.html)。为简单起见,请使用YYYY-MM-DD'2013-07-26')格式(您喜欢的任何日期)

  2. 有人能澄清“最佳结果”是什么意思吗?结果是预期的,或者不是 - 在这种情况下“最佳”是什么?

  3. PS:目标mysql版本是最新的5.5版本和更新版本。

    PPS:明确说明:

    • 问题假设我们使用日期时间/日期兼容列,而不是varchars等
    • 问题是关于扩展类型,而不是缩小范围

1 个答案:

答案 0 :(得分:-1)

看一下简单的例子(MySql 5.6):

drop table dattes;
create table dattes(
   id  int,
   da_te  date,
   name varchar(200)
);

set @x = 0;
insert into dattes
select (@x:=@x+1),
       '2013-5-1' + interval @x day,
       t.column_name
from information_schema.columns t
;

这是一个查询:

Set @start_date = cast( '2013-5-2' as date);
Set @start_datetime = cast( '2013-5-2 15:00' as datetime);
Set @end_date = cast( '2013-5-10' as date);

select   (Select sum( id ) from dattes
          where da_te between @start_date and @end_date) da_test1,

         (Select sum( id ) from dattes
          where da_te between @start_datetime and @end_date) da_test2,

         (Select sum( id ) from dattes
          where da_te between cast( @start_datetime as date) 
                and @end_date) da_test3
;
+ ------------- + ------------- + ------------- +
| da_test1      | da_test2      | da_test3      |
+ ------------- + ------------- + ------------- +
| 45            | 44            | 45            |
+ ------------- + ------------- + ------------- +

可以预料,在第二种情况下,MySql会隐含地将@start_datetime转换为日期(因为表中的列da_te是日期) - >但是MySql做了相反的事情,它扩展了日期时间的其他参数。由于此表中的一条记录被跳过('2013-5-2 00:00'<'2013-5-2 15:00')。

这会影响性能当然(可能不会显着,但有点),因为MySql必须将所有列值(或索引值,如果有的话)从日期转换为日期时间。