代码之家  ›  专栏  ›  技术社区  ›  Puggan Se

为什么五的和1=4

  •  1
  • Puggan Se  · 技术社区  · 14 年前

    基本查询的工作原理与inteden一样,但当我尝试对第一列求和时,结果是5,但我得到了4,为什么?

    基本查询:

    SET @last_task = 0;
    SELECT 
      IF(@last_task = RobotShortestPath, 0, 1) AS new_task,
      @last_task := RobotShortestPath
    FROM rob_log
    ORDER BY rog_log_id;
    
    1   1456
    0   1456
    0   1456
    1   1234
    0   1234
    1   1456
    1   2556
    1   1456
    

    总和查询

    SET @last_task = 0;
    SELECT SUM(new_task) AS tasks_performed
    FROM (
      SELECT 
        IF(@last_task = RobotShortestPath, 0, 1) AS new_task,
        @last_task := RobotShortestPath
      FROM rob_log
      ORDER BY rog_log_id
    ) AS tmp
    
    4
    

    表格结构

    CREATE TABLE rob_log (
      rog_log_id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
    #  RobotPosX FLOAT NOT NULL,
    #  RobotPosY FLOAT NOT NULL,
    #  RobotPosDir TINYINT UNSIGNED NOT NULL,
      RobotShortestPath MEDIUMINT UNSIGNED NOT NULL,
      PRIMARY KEY(rog_log_id),
      KEY (rog_log_id, RobotShortestPath)
    );
    
    INSERT INTO rob_log(RobotShortestPath) SELECT 1456;
    INSERT INTO rob_log(RobotShortestPath) SELECT 1456;
    INSERT INTO rob_log(RobotShortestPath) SELECT 1456;
    INSERT INTO rob_log(RobotShortestPath) SELECT 1234;
    INSERT INTO rob_log(RobotShortestPath) SELECT 1234;
    INSERT INTO rob_log(RobotShortestPath) SELECT 1456;
    INSERT INTO rob_log(RobotShortestPath) SELECT 2556;
    INSERT INTO rob_log(RobotShortestPath) SELECT 1456;
    

    在sqlfiddle上进行测试: http://sqlfiddle.com/#!2/e80f5/3 作为对 Counting changes in timeline with MySQL 但很困惑

    2 回复  |  直到 9 年前
        1
  •  4
  •   Jake Feasel    14 年前

    原因如下(如上所述 Twitter )以下为:

    变量@last_task是在一个单独的查询“batch”中定义的。我将SQL Fiddle上的查询分解为单独的批处理,分别执行。我这样做是为了让您可以在下面看到每个批次的输出作为一个不同的结果集。在Fiddle中,您可以看到有两组输出: http://sqlfiddle.com/#!2/e80f5/3/0 http://sqlfiddle.com/#!2/e80f5/3/1 。这些映射到您正在运行的两个语句(set和select)。问题是,您的set语句定义了一个仅存在于第一批中的变量;当select语句运行时,它是一个单独的批处理,并且您的变量没有在该上下文中定义。

    要纠正这个问题,您所要做的就是定义一个不同的查询终止符。请注意架构和查询面板下的下拉框/按钮([;])-单击它,您可以选择分号(默认值)以外的内容。然后,您的两个语句将作为同一批的一部分包含在一起,您将得到所需的结果。例如: http://sqlfiddle.com/#!2/e80f5/9

        2
  •  2
  •   Omesh    14 年前

    这可能是旧版本MySQL中的一个bug。

    我在MySQL 5.5上尝试过,它运行得很好。