通过在MariaDB中显示错误结果来排序

时间:2018-03-30 14:48:31

标签: mysql sql mariadb sql-order-by

在我的查询中,我需要使用当前行获取上一行,然后加入几个表。我在我的开发服务器(MySQL 5.7)中使用SQL变量获得了前一行,一切正常,但在我的生产(MariaDB 10)服务器中,前一行结果不好只是混合,坏部分只是前一行有SQL变量其他查询部分效果很好。在我想到之前,那个问题出现在sql变量的一部分,但是现在我意识到这个问题是在"顺序中由"关键字。

我的查询:

SELECT
   customers.title,
   calendar.start_time, 
   calendar.hours_per_time,
   calendar.self_certification,
   calendar.bulletin_certification,
   calendar.extra,
   DATE_FORMAT(calendar.date, '%d-%m') AS day_month,
   TIME_FORMAT(calendar.start_time, '%H:%i') AS hours_min,
   @previous_start AS previous_start,
   @previous_start := calendar.start_time,
   @previous_end AS previous_end,
   @previous_end := calendar.hours_per_time

        FROM
          (SELECT @previous_start := '00:00', @previous_end := '0.00') AS calendar_prev, calendar

            INNER JOIN relationships ON calendar.relation_id = relationships.relation_id
            INNER JOIN customers ON customers.customer_id = relationships.customer_id

            WHERE relationships.user_id = '$user_id'
            AND DATE_FORMAT(calendar.date, '%m-%Y') = '$date'

        ORDER BY calendar.date, hours_min ASC

如果我按顺序删除hours_min,那么在两台服务器上一切正常,但我失去了我的订购。

这是我的开发服务器绿色部分的结果是来自sql变量,这里工作正常: enter image description here

这是来自生产服务器,红色部分结果不好 enter image description here

那么我怎样才能保住订单并且仍能取得好成绩呢?订单只需按日期(Dato)和hours_min(Fra kl。)列。

1 个答案:

答案 0 :(得分:1)

将查询包装为内联视图,并在外部查询上指定不同的ORDER BY。

作为模式的简单演示:

SELECT v.fee
     , v.fo
     , v.fi
  FROM ( 
         SELECT t.fee
              , t.fi 
              , t.fo
           JOIN t
          ORDER BY t.fi ASC, t.fo ASC
       ) v
 ORDER
    BY v.fee DESC

我们可以按顺序处理行""在内联视图内的查询中,在内部ORDER BY语句中使用SELECT子句。

外部查询的ORDER BY可以重新排序内部查询返回的结果。

注意:

MySQL参考手册警告说,不保证在同一语句中设置和读取的用户定义变量的行为。话虽如此,我们确实观察到了一致的行为。

这是一个操作顺序问题。也就是说,我们正在以一种MySQL执行计划为我们提供可预测的操作顺序的方式精心构建我们的SQL。

我们发现在评估SELECT列表中的表达式之前正在处理ORDER BY。

所以,如果我们需要处理行"按顺序"这样用户定义的变量包含来自" previous"的值。当评估SELECT列表中的表达式时,我们需要有一个ORDER BY来获取所需顺序的行。

如果我们希望结果行的顺序不同,我们需要稍后处理另一个ORDER BY操作。我们可以使用内联视图(MySQL称为"派生表")来实现。这是因为MySQL实现了派生表" v"在处理外部查询之前。

外部查询的SELECT列表可以指定不同的列顺序或省略列。内部查询的SELECT列表中的表达式顺序可以由使用用户定义变量时所需的操作顺序决定:将当前行保存到用户定义变量的赋值必须在用户之后发生 - 定义的变量被评估。

另外,我建议放弃连接操作的逗号语法,并将其替换为JOIN关键字。 CROSS关键字是可选的,但它确实可以作为未来读者的一个指示,即遗漏ON条款是故意的,而不是疏忽。

INNER关键字也是可选的;它没有效果,我宁愿忽略它。

 FROM (SELECT @previous_start := '00:00', @previous_end := '0.00') calendar_prev
CROSS
 JOIN calendar
 JOIN relationships 
   ON calendar.relation_id = relationships.relation_id