2

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. 谁能澄清“最佳结果”是什么意思?结果要么是预期的,要么不是预期的——在这种情况下,什么是“最好的”?

PS:目标mysql版本是最新的5.5可用和更新。

PPS:说清楚:

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

1 回答 1

-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 必须将所有列值(或索引值,如果有的话)从日期转换为日期时间。

于 2013-08-04T20:28:56.830 回答