【问题标题】:sql what is the order of variable evaluationsql变量求值的顺序是什么
【发布时间】:2020-11-01 20:40:09
【问题描述】:
SET @rowse := -1;
  SELECT
      @rowse := @rowse + 1 AS rowses ,
      STATION.LAT_N AS LAT_N
   FROM
      STATION
   ORDER BY STATION.LAT_N

变量的求值顺序和排序依据是什么。

1. 是否会先执行 order by,然后再执行 @rowse := @rowse + 1 的评估?因此导致排序的 LAT_N 并且所有行都是连续的。

  1. 或首先评估 @rowse := @rowse + 1 并将其分配给每一行,然后在 station.lat_n 上进行排序,从而导致 LAT_N 排序,但可能出现非连续行。

在 MySQL 中发生了第 1 次,但我无法理解在 SELECT 之后根据 MA​​NUAL 评估 ORDER BY 的时间,那么情况 1 是如何发生的。 非常感谢任何帮助。

【问题讨论】:

    标签: mysql sql


    【解决方案1】:

    文档对您提出的问题并不准确。我发现通常先对子查询中的行进行排序,然后使用变量更安全;

    set @rowse := -1; 
    select @rowse := @rowse + 1 as rowses , lat_n 
    from (select * from station order by lat_n) s
    

    请注意,您不需要单独的语句来初始化变量:

    select @rowse := @rowse + 1 as rowses , lat_n  
    from (select * from station order by lat_n) s
    cross join (select @rowse := 0) r
    

    用户变量很难使用。它们现在正式计划在未来的 MySQL 版本中弃用。如果您有幸运行 MySQL 8.0,那么使用窗口函数可以更简单、更安全且规范地完成:

    select row_number() over(order by lat_n) - 1 as rowses , lat_n as lat_n 
    from station
    

    【讨论】:

      【解决方案2】:

      使用row_number():

      SELECT ROW_NUMBER() OVER (ORDER BY STATION.LAT_N) - 1 as rowses,
             STATION.LAT_N AS LAT_N
      FROM STATION
      ORDER BY STATION.LAT_N;
      

      自 8.0 版本以来,MySQL SELECT 语句中的变量赋值已被弃用。

      旧版本的 MySQL 在变量赋值是否尊重排序方面不一致。因此,使用子查询是最安全的——它实现了订单:

      SELECT @rowse := @rowse + 1 AS 行, S.LAT_N 作为 LAT_N 从(选择 S.* 从车站 S 由 S.LAT_N 订购 ) s;

      顺便说一句,GROUP BY 也是如此。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-06-16
        • 1970-01-01
        • 2022-12-06
        • 2019-01-28
        • 2019-01-22
        • 1970-01-01
        • 1970-01-01
        • 2020-05-05
        相关资源
        最近更新 更多