Имя: Пароль:
IT
Админ
как сократить Запрос (My)SQL для удаления дублей с выбором лучшей записи? ☑
0 Патчкорд
 
13.11.15
✎
07:31
Есть таблица фотографий, у которой в колонке filename появились дубли которые нужно удалить.

Но удалять нужно не любую запись, а ту у которой меньше высота фотографии (значение в колонке height).

Если у всех дублей высота одинаковая, то нужно удалить ту у которой "имя" = 'Папа', а у которой 'Мама' оставить.

Но если и имя тоже одинаковое, то удалить ту у которой заголовок равен 'Описание', а ту у которой заголовок другой оставить.

Но если и заголовок тоже одинаковый, то удалить по следующему условию, которое я не написал, потому что так можно продолжать очень долго.

В итоге получилось очень длинное условие, в котором при каждой следующей проверке нужно проверять и отрицание всех предыдущих, после каждого очередного OR условие все длиннее и длиннее:

DELETE t1 FROM photos t1, photos t2
WHERE t1.filename=t2.filename
AND(
t1.height < t2.height
OR
t1.height = t2.height and t1.name = 'Папа' and t2.name = 'Мама'
OR
t1.height = t2.height and t1.name = t2.name and t1.description = 'Описание' and not t2.description = 'Описание'
OR
...................................................
)

Вопрос: Как сократить проверку, чтобы не проверять отрицание всех накопившихся предыдущих проверок?
1 Мэс33
 
13.11.15
✎
07:45
IF...ELSE
2 Патчкорд
 
13.11.15
✎
10:47
(1) Я ничего не понимаю. Я запросы начал учить только неделю назад. Куда эти слова пихать?
3 Мэс33
 
13.11.15
✎
12:19
Хм, а задачка-то непростая )))
Пробовал решить на pl/sql. Решение чуть позже выложу.
4 Горогуля
 
13.11.15
✎
12:20
а case when здесь не в тему?
5 Гёдза
 
13.11.15
✎
12:20
сначала селект напиши, так проще будет )))
6 Мэс33
 
13.11.15
✎
12:21
(0) и кстати твой код нерабочий. Даже если так напишешь.
7 Гёдза
 
13.11.15
✎
12:22
1. Группируем  и находим максимум по длине
2. группируем и находим максимум по name = 'Мама'
3. группируем и находим максимум по description = 'Описание'

Таким образом мы находим ключевые поля
8 Патчкорд
 
16.11.15
✎
05:55
(3) У меня все задачки не простые.
9 Патчкорд
 
16.11.15
✎
05:57
(6) На многоточия ругается, синтаксическая ошибка, да?
10 Горогуля
 
16.11.15
✎
05:59
нормальный синтаксис, это твоя версия sql не имеет интеллектуального модуля
11 Патчкорд
 
16.11.15
✎
06:24
(10) Не, у меня работает запрос нормально.
Я подумал еще немного, и решил что никак его нельзя сократить.
Темку можно закрыть.
12 Мэс33
 
16.11.15
✎
06:26
(11) Да, пробовал писать процедурку на pl/sql, все равно получается портянка.
13 Патчкорд
 
16.11.15
✎
09:23
(12) Ага. +1
14 los_hooliganos
 
16.11.15
✎
09:28
Пиши батчами, в один батч - одно условие.
В каждом батче коммент, что этот батч делает.
Первым должны идти батчи активно юзающие индекс.
Самый первый должен юзать кластерный индекс.

Если так, то батчи очень быстро отработают.
15 Патчкорд
 
16.11.15
✎
09:31
(14) что такое батчи? Я не в теме
16 Мэс33
 
16.11.15
✎
09:52
Поэтому лучше вытащить все дубли одним запросом, потом перебрать их и получить айдишники, и другим запросом удалить по этим айди ).
17 1Сергей
 
16.11.15
✎
09:57
MySQL понимает конструкцию WITH <...> DO ?
18 ДенисЧ
 
16.11.15
✎
09:58
(17) mysql <> pascal
19 los_hooliganos
 
16.11.15
✎
10:01
Batches

Batch - это набор операторов TSQL, передаваемых на выпонение и выполняющихся вместе, как одно целое. Batch компилируется целиком и оканчивается специальным символом-сигналом конца (go). Все последовательности операторов TSQL, набираемые в ISQL/w или в Enterprise Manager интерпретируются именно как batch'и (интересно то, что при выделении некоторой части текста в окне выполняться будет именно она)
Пример



Несколько SELECT в одном batch'е

  SELECT COUNT(*) FROM titles
  SELECT COUNT(*) FROM authors
20 los_hooliganos
 
16.11.15
✎
10:02
На языке 1С - батч это пакет запросов
21 1Сергей
 
16.11.15
✎
10:03
(18) я вот это имел в виду https://msdn.microsoft.com/ru-ru/library/ms175972(v=sql.120).aspx
22 Патчкорд
 
16.11.15
✎
12:20
(19) не думаю что mysql это умеет. Но попробую.
23 Мэс33
 
16.11.15
✎
12:39
24 Гёдза
 
16.11.15
✎
12:44
Собственно задача - аналог среза последних. А он делается как (7)
25 Патчкорд
 
17.11.15
✎
08:12
(23) Хрень какая-то. Те же самые запросы, только вводятся не с клавиатуры, а из файла. Сами запросы от этого не меняются. У меня и без того запрос в файле. Мне этот вариант ничего не изменит.