具有特定@variable值的mysql`has`操作

时间:2017-10-21 00:54:21

标签: mysql sql

我通过表实例组中的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。

1 个答案:

答案 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 ;

注意:

  • 在最新版本的MySQL中,您需要一个额外的子查询。 ORDER BY不适用于没有子查询的变量。
  • MySQL不保证SELECT中表达式的执行顺序,因此您应该在一个子查询中执行所有赋值。
  • 您可以将定义组的表达式合并为单个变量。