Mysql выберите порядок сортировки как подзапрос и запрос в 5.7.x

0

Позвольте мне изложить это, сказав, что то, что я описываю здесь, отлично работает в Mysql 5.6.x и ниже. Теперь мы пытаемся обновить mysql 5.7 и найти проблему с этим оператором UPDATE.

У нас есть таблица, которая выглядит так:

imagefile
----------
id      int
itemId  int
...
sequenceNumber int
updatedDate    date

В нашем приложении пользователям необходимо изменить порядок изображений в элементе Item. Наш SQL для этого выглядит следующим образом:

UPDATE imageFile f1 
  JOIN ( 
        SELECT f2.id, (@row:=@row+1) rowNum 
          FROM imageFile f2, (SELECT @row:=0) dm 
         WHERE f2.itemId = 8035323
         ORDER BY f2.sequenceNumber, f2.updatedDate 
        ) rs ON f1.id = rs.id 
SET f1.sequenceNumber = rs.rowNum;

Если я запускаю только часть select в качестве автономного запроса, она производит следующее:

SELECT f2.id, f2.sequenceNumber, sqNum (@row:=@row+1) rowNum, updatedDate 
  FROM imageFile f2, (SELECT @row:=0) dm 
 WHERE f2.itemId = 8035323
 ORDER BY f2.sequenceNumber, f2.updatedDate;

 id   sqNum   rowNum   updatedDate
| 9 |   1   |   1   |2018-04-16 18:39:12
| 8 |   2   |   2   |2018-04-16 18:38:42
| 7 |   3   |   3   |2018-04-16 18:37:03
| 6 |   4   |   4   |2018-04-16 18:37:28
| 5 |   5   |   5   |2018-04-16 18:36:37
| 4 |   6   |   6   |2018-04-16 18:38:16
| 3 |   7   |   7   |2017-09-12 16:59:20

Что правильно и точно, что я ожидаю... После запуска UPDATE с SELECT в качестве подзапроса/соединения я получаю следующее:

 id   sqNum  rowNum   updatedDate
| 3 |   1   |   1   |2017-09-12 16:59:20
| 4 |   2   |   2   |2018-04-16 18:38:16
| 5 |   3   |   3   |2018-04-16 18:36:37
| 6 |   4   |   4   |2018-04-16 18:37:28
| 7 |   5   |   5   |2018-04-16 18:37:03
| 8 |   6   |   6   |2018-04-16 18:38:42
| 9 |   7   |   7   |2018-04-16 18:39:12

Что совершенно неправильно и, похоже, не соответствует каким-либо приказом, о чем я сказал. Очевидно, что что-то изменилось в новой версии mysql. Когда я делаю EXPLAIN для этого запроса в каждой версии, он тоже отличается...

5.6.34

id  select_type table   type    possible keys   key key length  ref rows    extra
1   PRIMARY <derived2>  ALL NULL    NULL    NULL    NULL    35  NULL
1   PRIMARY i1  eq_ref  PRIMARY PRIMARY 4   rs.id   1   NULL
2   DERIVED <derived3>  system  NULL    NULL    NULL    NULL    1   Using filesort
2   DERIVED i2  ref uc_ItemNumber, in_workspaceId   uc_ItemNumber   4   const   35  Using where
3   DERIVED NULL    NULL    NULL    NULL    NULL    NULL    NULL    No tables used

5.7.18

id  select_type table   type    possible_keys   key key_len ref rows    extra
1   PRIMARY <derived2>  ALL                 35  
1   UPDATE  i1  eq_ref  PRIMARY PRIMARY 4   rs.id   1   
2   DERIVED i2  ref uc_ItemNumber, in_workspaceId   uc_ItemNumber   4   const   35  Using temporary; Using filesort
2   DERIVED <derived3>  ALL                 1   Using join buffer (Block Nested Loop)
3   DERIVED                             No tables used

Мой вопрос: как мне заставить это вернуться к предыдущему/желаемому поведению?

  • 0
    Кажется, я вспоминаю, что переменные сеанса не должны использоваться в выражениях DML или, по крайней мере, такое поведение не гарантировано (как вы сейчас говорите). Позвольте мне попытаться найти ссылку на документ.
Теги:
sql-update
join

1 ответ

1
Лучший ответ

Я, кажется, помню, что переменные сеанса не должны использоваться/полагаться на операторы MySQL DML. Но хорошей новостью является то, что мы можем переписать ваш запрос без переменных сеанса:

UPDATE imageFile f1 
INNER JOIN
( 
    SELECT
        f2.id, 
        (SELECT COUNT(*) 
         FROM imageFile t
     WHERE t.itemId = 8035323 AND
           (t.sequenceNumber < f2.sequenceNumber OR
            t.sequenceNumber = f2.sequenceNumber AND
            (t.updatedDate < f2.updatedDate OR
            (t.updatedDate = f2.updatedDate AND t.id < f2.id)))) rowNum
    FROM imageFile f2
    WHERE f2.itemId = 8035323
) rs
    ON f1.id = rs.id 
SET f1.sequenceNumber = rs.rowNum;
  • 0
    Спасибо за ответ. может быть, я плотный, но этот запрос дает мне ошибку SQL. ему не нравится что-то в области "f2.updatedDate FROM imageFile t)"
  • 0
    Извините, у меня была опечатка, попробуйте еще раз.
Показать ещё 7 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню