Mysql

mariadb和mysql之間的行編號差異

  • December 6, 2020

我最近將我的伺服器更新為 docker 設置並從 mysql 切換到 mariadb。不,我在本地機器上的 Mysql 5.7 和伺服器上的 MariaDB 10.5.6 之間遇到了不同行為的問題。

問題是應該返回行號的查詢的不同結果。我將使用一個最小的工作範例進行解釋

考慮以下兩個表:

>SHOW CREATE TABLE cars\G
*************************** 1. row ***************************
      Table: cars
Create Table: CREATE TABLE `cars` (
 `brand` varchar(128) DEFAULT NULL,
 `model` varchar(128) DEFAULT NULL,
 `value` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4

>SHOW CREATE TABLE used_cars\G
*************************** 1. row ***************************
      Table: used_cars
Create Table: CREATE TABLE `used_cars` (
 `brand` varchar(128) DEFAULT NULL,
 `model` varchar(128) DEFAULT NULL,
 `price` int(10) unsigned DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4

還有一些範例數據:

INSERT INTO `cars` (`brand`, `model`, `value`) VALUES
('Volvo', 'S40', 1),
('Porsche', 'Carrera', 4),
('Opel', 'Corsa', 3),
('Renault', 'Clio', 1),
('Renault', 'Megane', 3),
('Volvo', 'V40', 2);
INSERT INTO `used_cars` (`brand`, `model`, `price`) VALUES
('Volvo', 'S40', 2500),
('Porsche', 'Carrera', 7500);

假設我想執行一個查詢,列出所有汽車並返回是否有庫存二手車。我希望以某種方式訂購這些:

SELECT (@row := @row + 1) AS score,
  qry.brand,
  qry.model,
  qry.used_present
FROM
 (SELECT cars.brand,
         cars.model,
         (used_cars.price IS NOT NULL) AS used_present
  FROM cars
  LEFT JOIN used_cars ON used_cars.model = cars.model
                         AND used_cars.brand = cars.brand) AS qry
CROSS JOIN
 (SELECT @row:=0) AS r
ORDER BY qry.used_present DESC,
        qry.brand ASC

這將在 MySQL 中返回以下內容

+-------+---------+---------+--------------+
| score | brand   | model   | used_present |
+-------+---------+---------+--------------+
|     1 | Porsche | Carrera |            1 |
|     2 | Volvo   | S40     |            1 |
|     3 | Opel    | Corsa   |            0 |
|     4 | Renault | Clio    |            0 |
|     5 | Renault | Megane  |            0 |
|     6 | Volvo   | V40     |            0 |
+-------+---------+---------+--------------+

雖然我在 MariaDB 中得到以下資訊

+-------+---------+---------+--------------+
| score | brand   | model   | used_present |
+-------+---------+---------+--------------+
|     2 | Porsche | Carrera |            1 |
|     1 | Volvo   | S40     |            1 |
|     3 | Opel    | Corsa   |            0 |
|     4 | Renault | Clio    |            0 |
|     5 | Renault | Megane  |            0 |
|     6 | Volvo   | V40     |            0 |
+-------+---------+---------+--------------+

誰能幫我解決這個問題?實際上,內部查詢qry要復雜得多,但結果與此 MWE 相似。添加ORDER BY到內部查詢不會改變結果。

db<>小提琴

Mysql 保持子查詢的順序,mariadb 將其優化掉,因為這是標準所告訴的。

您可以為 MAriadb 使用 LIMIT 以便保留訂單

SELECT (@row := @row + 1) AS score,
   qry.brand,
   qry.model,
   qry.used_present
FROM
  (SELECT cars.brand,
          cars.model,
          (used_cars.price IS NOT NULL) AS used_present
   FROM cars
   LEFT JOIN used_cars ON used_cars.model = cars.model
                          AND used_cars.brand = cars.brand
ORDER BY `price` LIMIT 18446744073709551615) AS qry
CROSS JOIN
  (SELECT @row:=0) AS r
ORDER BY qry.used_present DESC,
         qry.brand ASC
分數 | 品牌 | 型號 | used_present
----: | :------ | :------ | -----------:
 1 | 保時捷 | 職業生涯 | 一
 2 | 沃爾沃 | S40 | 1
 3 | 歐寶 | 科薩 | 0
 4 | 雷諾 | 克里奧 | 0
 5 | 雷諾 | 梅甘娜 | 0
 6 | 沃爾沃 | V40 | 0

db<>在這裡擺弄

引用自:https://dba.stackexchange.com/questions/280940