在我的查询中,我需要获得当前行和前一行,然后连接几个表。我在开发服务器中使用SQL变量获得了前一行(MySQL 5.7),一切都很好,但在我的产品中(MariaDB 10)服务器上的前一行结果不好只是混合,坏的部分只是前一行与SQL变量其他查询部分工作良好.之前我想,那个问题是在sql变量部分,但现在我意识到问题是在"order by"关键字。
我的疑问:
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
如果我从order by part中删除hours_min,那么两个服务器上的一切都很正常,但是我会丢失我的订单。
这是我从开发服务器的结果绿色部分是从SQL变量和这里的工作很好:
这里是生产服务器,红色部分
显示错误结果
那么我怎样才能保持我的顺序并且仍然有好的结果呢?只有日期(Dato)和小时_分钟(Fra kl.)列需要顺序。
2条答案
按热度按时间lzfw57am1#
将查询 Package 为内联视图,并在外部查询上指定不同的ORDER BY。
下面是该模式的简单演示:
我们可以在内部
SELECT
语句上使用ORDER BY
子句,在内联视图中"按顺序"处理查询中的行。外部查询上的
ORDER BY
可以对内部查询返回的结果重新排序。注:
MySQL参考手册警告说,在同一条语句中设置和读取的用户定义变量的行为是不能保证的。尽管如此,我们还是观察到了一致的行为。
这是一个操作顺序的问题,也就是说,我们小心地构建SQL,使MySQL执行计划能够为我们提供一个可预测的操作顺序。
我们发现ORDERBY在SELECT列表中的表达式求值之前被处理。
因此,如果我们需要"按顺序"处理行,以便在计算SELECT列表中的表达式时,用户定义的变量包含"前一"行的值,那么我们需要有一个ORDER BY,它可以按所需的顺序获取行。
如果我们希望得到的行有不同的顺序,我们需要另一个ORDER BY操作在后面处理。我们可以使用内联视图(MySQL称之为"派生表")来获得它。这是因为MySQL在处理外部查询之前物化了派生表"v"。
外部查询的SELECT列表可以指定不同的列顺序或省略列。内部查询的SELECT列表中表达式的顺序可以由使用用户定义变量时所需的操作顺序来指定:将当前行保存到用户定义变量的赋值操作必须在用户定义变量求值之后进行。
另外,我建议放弃join操作的逗号语法,用
JOIN
关键字代替它,CROSS
关键字是可选的,但它确实可以向未来的读者表明,省略ON
子句是有意的,而不是疏忽。INNER
关键字也是可选的;它没有任何作用,我倾向于忽略它。insrf1ej2#
在MariaDB中将ORDER BY与变量结合使用有点麻烦。您能否复制一个已经由calendar.date,hours_min ASC排序的表,并在不使用ORDER BY的情况下对该副本运行查询?