我通过表实例组中的create_time将每个行rank
赋予(task_id,task_time)作为主键。我的SQL如下所示
SELECT
task_id,
task_time,
create_time,
@rn := CASE WHEN @prev_task_id <> task_id THEN 1
WHEN @prev_task_time <> task_time THEN 1
ELSE @rn + 1 END AS rank,
@prev_task_id := task_id,
@prev_task_time := task_time
FROM instances, (SELECT
@rn := 0,
@prev_task_id := -1,
@prev_task_time := '-1') t
where task_id in (1209, 1211)
having rank = 1
ORDER BY task_id, task_time DESC, create_time DESC;
问题来了我添加having rank = 1
子句后。与没有having rank = 1
的结果相比,返回的结果不准确,并且缺少一些等级为1的记录,例如,大多数task_id = 1211
的记录都丢失了。
据我所知,having
子句是在select
之后启动的,用于将过滤器添加到最终记录中。我想知道我犯过的错误,THX。
答案 0 :(得分:0)
MySQL不保证select
中表达式的评估顺序。因此,您无法分配变量,然后在另一个表达式中使用它 - 并期望它能够执行您想要的任务。
我建议使用子查询:
SELECT x.*
FROM (SELECT task_id, task_time, create_time,
(@rn := (CASE WHEN @p = concat_ws(':', task_id, task_time) THEN 1
WHEN @p := concat_ws(':', task_id, task_time) THEN @rn + 1
ELSE @rn + 1
END)
) AS rank,
FROM instances CROSS JOIN
(SELECT @rn := 0, @p := '') params
WHERE task_id in (1209, 1211)
ORDER BY task_id, task_time DESC, create_time DESC;
) x
WHERE rank = 1 ;
注意:
ORDER BY
不适用于没有子查询的变量。SELECT
中表达式的执行顺序,因此您应该在一个子查询中执行所有赋值。