#mysql
Вопрос:
У меня есть таблица данных ресторана, и я хотел бы удалить строки, restaurant_name
если они дублируются, когда я SELECT
. Единственный столбец, который мне нужно проверить на наличие дубликатов restaurant_name
, — это включить все остальные столбцы, как показано в таблице.
Я пробовал SELECT restaurant_id, max(restaurant_name), city FROM restaurant_data GROUP BY name
, как бы это мне ни давалось MYSQL error 1055: this is incompatible with sql_mode=only_full_group_by
. После попытки изменить этот параметр запрос сработал, однако он работает медленно
Есть ли лучший способ сделать это или мне следует просто отключить эту настройку?
Стол:
restaurant_id | restaurant_name | city | 5 other columns |
--------------------------------------------------------------------
1 Rest1 A strings
2 Rest1 B strings
3 Rest2 C strings
4 Rest3 C strings
5 Rest1 D strings
6 Rest2 D strings
7 Rest3 C strings
Желаемые Результаты:
restaurant_id | restaurant_name | city | 5 other columns |
--------------------------------------------------------------------
1 Rest1 A strings
3 Rest2 C strings
4 Rest3 C strings
Ответ №1:
Использование ROW_NUMBER
в MySQL 8 :
WITH cte AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY restaurant_name
ORDER BY restaurant_id) rn
FROM restaurant_data
)
SELECT restaurant_id, restaurant_name, city
FROM cte
WHERE rn = 1;
В противном случае в более ранних версиях MySQL мы можем объединить вашу таблицу с подзапросом, который находит наименьшее restaurant_id
значение для каждого имени:
SELECT r1.restaurant_id, r1.restaurant_name, r1.city
FROM restaurant_data r1
INNER JOIN
(
SELECT restaurant_name, MIN(restaurant_id) AS min_restaurant_id
FROM restaurant_date
GROUP BY restaurant_name
) r2
ON r2.restaurant_name = r1.restaurant_name AND
r2.min_restaurant_id = r1.restaurant_id;
Комментарии:
1. У меня есть MySQL 7, и нижний блок кода работал отлично. Большие взлеты
Ответ №2:
Если вы используете последнюю версию mysql, то для этого вы можете использовать функцию ранга.
SELECT restaurant_id, restaurant_name, city FROM
(
select restaurant_id, restaurant_name, city , RANK() OVER (PARTITION BY restaurant_name order by restaurant_id)ranks
from restaurant_data
) T WHERE ranks=1;
Комментарии:
1. Это решение работает, однако я сделал другой ответ таким же правильным, поскольку для завершения операции потребовалось вдвое меньше времени (0,1 секунды по сравнению с 0,3 секунды для таблицы из 70 000 записей).