SELECT在MySQL上的奇怪行为

时间:2014-05-10 18:18:43

标签: mysql

我观察到这种类型的表达式跳过行很多次,并且总是想知道这是一个错误还是有意义 - 至少在技术上。查询的目的是生成顺序表内容。主要是DATE或DATETIME。

t只是包含至少30行的任何表格。

此版本按预期生成结果:

set @date = "2012-01-01";

select
    @date := date_add(@date, interval 1 day) as d
from t
#having d < "2012-01-31"
limit 30
;

输出:

'2012-01-02'
'2012-01-03'
'2012-01-04'
...
'2012-01-31'

现在包括HAVING条件(因此我不必使用数字来限制我想要生成的行数,但可以简单地指定一个上部boudary):

set @date = "2012-01-01";

select
    @date := date_add(@date, interval 1 day) as d
from t
having d < "2012-01-31"
limit 30
;

输出:

'2012-01-03'
'2012-01-05'
'2012-01-07'
...
'2012-01-29'
'2012-01-31'

但请注意 - 这是一个为什么问题 - 而不是一个怎样的问题。

1 个答案:

答案 0 :(得分:2)

问题在于,当您在d子句中调用列HAVING时,它会再次计算表达式@date := date_add(@date, interval 1 day)。这意味着interval 1 day已添加两次到初始@date变量,因此您的条目中存在空白。您可以通过添加额外条件来验证此事实,例如HAVING d < '2012-01-31' AND d > '2012-01-01'

正确的查询如下:

SET @date = '2012-01-01';
SELECT @date := date_add(@date, interval 1 day) as d
FROM t
WHERE date_add(@date, interval 1 day) < '2012-01-31'
ORDER BY d
LIMIT 30;

请注意,HAVING子句应与聚合函数一起使用,并且使用不带ORDER BY子句的LIMIT可能会以错误的顺序给出结果。