Используйте CTE для ОБНОВЛЕНИЯ или УДАЛЕНИЯ в MySQL - PullRequest
0 голосов
/ 11 июня 2018

Новая версия MySQL, 8.0, теперь поддерживает Общие табличные выражения .

Согласно инструкции:

AПредложение WITH допускается в начале операторов SELECT, UPDATE и DELETE:

WITH ... SELECT ...
WITH ... UPDATE ...
WITH ... DELETE ...

Итак, я подумал, учитывая следующую таблицу:

ID lastName firstName
----------------------
1  Smith    Pat
2  Smith    Pat
3  Smith    Bob

Я могу использоватьследующий запрос:

;WITH ToDelete AS 
(
   SELECT ID,
          ROW_NUMBER() OVER (PARTITION BY lastName, firstName ORDER BY ID) AS rn
   FROM mytable
)   
DELETE FROM ToDelete

, чтобы удалить дубликаты из таблицы, как я мог бы сделать в SQL Server .

ItОказывается, я был неправ.Когда я пытаюсь выполнить элемент DELETE из MySQL Workbench, я получаю сообщение об ошибке:

Код ошибки: 1146. Таблица 'todelete' не существует

Iтакже появляется сообщение об ошибке, когда я пытаюсь выполнить UPDATE с помощью CTE.

Итак, мой вопрос: как можно использовать предложение WITH в контексте UPDATE или * 1038?* заявление в MySQL (как указано в руководстве к версии 8.0)?

Ответы [ 2 ]

0 голосов
/ 12 июня 2018

Поскольку CTE не обновляется, вам необходимо обратиться к исходной таблице для удаления строк.Я думаю, что вы ищете что-то вроде этого:

WITH ToDelete AS 
(
   SELECT ID,
          ROW_NUMBER() OVER (PARTITION BY lastName, firstName ORDER BY ID) AS rn
   FROM mytable
)   
DELETE FROM mytable USING mytable JOIN ToDelete ON mytable.ID = ToDelete.ID
WHERE ToDelete.rn > 1; 
0 голосов
/ 11 июня 2018

Это похоже на опубликованную ошибку в MySQL 8.x.Из этого отчета об ошибках :

В версии стандарта SQL 2015 года невозможно определить CTE в UPDATE;MySQL это позволяет, но делает CTE доступным только для чтения (сейчас мы обновляем документацию, чтобы упомянуть об этом).Тем не менее, можно использовать представление вместо CTE;тогда представление может быть обновляемым, но из-за присутствия оконных функций оно материализуется во временную таблицу (не объединяется), поэтому не обновляется (мы также упомянем это в документе).

Все вышеперечисленное относится и к DELETE.

Если вы перейдете по вышеуказанной ссылке на ошибку, вы увидите обходной путь, предложенный для использования CTE, но он включал присоединение CTE к исходной целевой таблице.в сопоставлении один к одному.Исходя из вашего примера, который представляет собой полное удаление, не ясно, какой обходной путь вам нужен, чтобы продолжить использование CTE для удаления.

...