我观察到这种类型的表达式跳过行很多次,并且总是想知道这是一个错误还是有意义 - 至少在技术上。查询的目的是生成顺序表内容。主要是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'
但请注意 - 这是一个为什么问题 - 而不是一个怎样的问题。
答案 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可能会以错误的顺序给出结果。