Удалить несколько строк в таблице с помощью WITH и Partition в MySQL

Я пытаюсь удалить несколько повторяющихся строк/данных, но проблема в том, MySQL сказал:

#1064 - У вас ошибка в синтаксисе SQL; проверьте руководство, соответствующее версии вашего сервера MariaDB, на предмет правильного синтаксиса для использования рядом с «УДАЛИТЬ ИЗ СТУДЕНЧЕСКОЙ ТАБЛИЦЫ, ГДЕ RowNumber > 1» в строке 6.

Вот мой код:

WITH studentTable AS
(
   SELECT *, ROW_NUMBER() OVER(PARTITION BY studentID ORDER BY studentID) AS RowNumber
   FROM student_quiz
)
DELETE FROM studentTable WHERE RowNumber > 1;

Вот результат выбора версии: введите здесь описание изображения

Я нашел этот код на YouTube, и это видео было загружено 11 лет назад, поэтому я не уверен, что этот код все еще работает в текущей версии MySQL. Я надеюсь, что вы можете помочь мне с этой проблемой. Спасибо!

mariadb не является mysql, поэтому я добавил правильный тег. Также опубликуйте результат select version().

P.Salmon 29.04.2023 09:39

Пожалуйста, покажите нам некоторые образцы данных. Есть ли в таблице другие столбцы?

GMB 29.04.2023 15:16

MariaDB не во всех случаях совместима с MySQL. В этом случае MySQL поддерживает SELECT, UPDATE или DELETE после CTE, но в реализации MariaDB он поддерживает только SELECT после CTE. Это пример того, почему важно, чтобы мы все считали MySQL и MariaDB разными базами данных, а не заменой друг друга. У них есть общий предок около 2010 года, но с тех пор они оба изменились.

Bill Karwin 29.04.2023 15:26
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
0
3
72
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Поскольку CTE не обновляется, вам нужно обратиться к исходной таблице, чтобы удалить строки, используя JOIN :

WITH studentTable AS
(
   SELECT *, ROW_NUMBER() OVER(PARTITION BY studentID ORDER BY studentID) AS RowNumber
   FROM student_quiz
)
DELETE FROM student_quiz
USING student_quiz join studentTable on student_quiz.id = studentTable.id
WHERE studentTable.RowNumber > 1;

Демо здесь

Я пробую ваш код, но столкнулся с некоторой ошибкой: WITH studentTable AS (SELECT id, studentID, quizID, ROW_NUMBER() OVER(PARTITION BY id ORDER BY id) AS RowNumber FROM student_quiz) DELETE FROM student_quiz, ИСПОЛЬЗУЯ student_quiz, ПРИСОЕДИНЯЙТЕ studentTable к student_quiz.id = studentTable.id ГДЕ studentTable.RowNumber > 1; Ошибка: при анализе обнаружено 2 ошибки. Неожиданное ключевое слово. (рядом с "join" в позиции 183) Неизвестный тип оператора. (рядом с "присоединиться" на позиции 183)

tester tested 29.04.2023 23:42

Какую версию mysql вы используете?

SelVazi 30.04.2023 14:06

@SelVazi они используют MariaDB (из сообщения об ошибке, которое они показывают, хотя оно не показывает версию).

ysth 01.05.2023 03:36

@testertested этот синтаксис поддерживается только в mysql, а не в mariadb (по крайней мере, до 11.0.1), хотя утверждение в вопросе (изменение самого CTE) не поддерживается ни

ysth 01.05.2023 03:38
Ответ принят как подходящий

Ни MySQL, ни MariaDB не поддерживают обновляемые CTE.

Если в вашей таблице есть первичный ключ, скажем pk, то я бы рекомендовал простое самосоединение:

delete q
from student_quiz q
inner join (select id, min(pk) pk from student_quiz group by id) q1
    on q1.id = q.id and q1.pk < q.pk

По сути, для каждого id сохраняется строка с наименьшим pk и удаляются остальные, если они есть.

Другие вопросы по теме