【发布时间】:2022-10-05 16:42:37
【问题描述】:
我有一个上下文,我需要能够在 MySQL 5 和 8 下运行相同的查询。运行以下 SQL 查询时:
SET
@item_row := 0,
@var_row := 0;
SELECT
*
FROM
(
SELECT
@item_row := @item_row + 1 AS `row_nr`,
`id` AS `order_item_id`
FROM
`order_items`
WHERE
`order_id` = ?
) `items`
INNER JOIN (
SELECT
@var_row := @var_row + 1 AS `row_nr`,
`index_number`
FROM
`recipe_variables`
WHERE
`recipe_variables`.`order_id` = ?
AND `recipe_variables`.`index_number` = 1
) `vars` USING (`row_nr`)
INNER JOIN `order_items`
ON `order_items`.`id` = `items`.`order_item_id`
WHERE
`items`.`order_item_id` = ?
我收到以下警告:
setting user variables within expressions is deprecated and will be removed in a future release
而且结果不正确。然而,只有在一个运行 MySQL 8 的环境下。在另一台运行 MySQL 8 的服务器上它工作正常,而在另一个运行 MySQL 5 的服务器上,它也能正常工作而没有警告。
我知道我可以改用ROW_NUMBER() OVER () 来重写查询以不使用变量,但是旧的 MySQL 5 服务器不支持这一点,我暂时不允许更新。
我检查了它们的完整版本,两个 MySQL 8 数据库都返回 8.0.25(使用 SELECT VERSION())。什么会导致这种差异?以及如何更改我的查询,使其仍然向后兼容 MySQL 5,但在 MySQL 8 下运行时没有警告?
-
您是否尝试过设置像
@item_row := @item_row + 1 as row_nr这样的变量而不是(SELECT @item_row + 1 INTO @item_row) AS row_nr? -
啊,哎呀,我本来打算写
@item_row := @item_row + 1 as row_nr。按照警告的建议,我复制了我尝试使用INTO的测试用例。不幸的是,不允许将SELECT ... INTO查询作为子查询,因此测试失败。 -
该变量应该在两个版本中都有效。正如消息所说,它已被弃用,但尚未删除。结果在哪些方面不正确?您可以在每个版本中发布示例数据和结果吗?
-
在使用变量的任何一个子查询中都没有
ORDER BY,因此分配数字的顺序是不可预测的。没有理由期望跨版本保持一致。 -
你是如何检查版本的?您应该使用
SELECT VERSION();来获取 MySQL 服务器的版本。无论您做什么,都可能返回您使用的客户端版本。
标签: mysql