0
DELETE *
FROM coins_info
WHERE (((coins_info.Код) Not In (SELECT Max(coins_info.Код) AS 'Max-Код' FROM coins_info GROUP BY coins_info.url_loaded, coins_info.name HAVING (((Count(*))>1))) And (coins_info.Код) Not In (SELECT Max(coins_info.Код) AS 'Max-Код' FROM coins_info GROUP BY coins_info.url_loaded, coins_info.name HAVING (((Count(*))=1)))));

Перевожу запросы с Access на MуSQL, на сколько понимаю, SELECT от DELETE отличается только самим словом SELECT/DELETE, так вот, в данном случае SELECT работает, а когда меняю на DELETE, получаю ошибку

1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '*
  FROM coins_info
  WHERE (((coins_info.Код) Not In (SELECT Max(coins_info.К' at line 1

брал "Код" в ``, ничего не изменилось, что еще нужно поменять чтобы запрос заработал?

UPD: видимо простой правкой запроса не отделаться, придется переделывать его, опишу задачу:

Есть таблица coins_info

Код name symbol price1 price2 date_load url_loaded
157370  garli   grlc        0,00026397  3,08043         2018-01-28 18:49:00 https://11111
157371  solaris xlr     0,00181792  21,2144         2018-01-28 18:52:00 https://11111
157372  garli   grlc        0,00053393  6,23074         2018-01-28 19:05:00 https://11111
157377  pirl    pirl        0,00019997  2,33359         2018-01-28 19:08:00 https://22222
157378  garli   grlc        0,00053391  6,23071         2018-01-28 19:11:00 https://22222

Из нее нужно удалить все повторяющиеся старые записи по name, symbol и url_loaded, т.е. в данном случае должна удалиться только первая строка. Код выше отлично работал в Access, сейчас необходимо перевести на MySQL, во многих запросах достаточно удалить [ и ] из тела запроса и все работает прекрасно, здесь же затык какой-то.

  • DELETE FROM table .... – splash58 Jan 29 '18 at 14:11
  • * уберите из запроса – Anton Shchyrov Jan 29 '18 at 14:35
  • Пробовал, все равно ошибка: > 1093 - You can't specify target table 'coins_info' for update in FROM clause – Василий Егоров Jan 29 '18 at 14:41
  • Используйте синтаксис delete с join, либо оберните подзапрос в еще один уровень https://ru.stackoverflow.com/a/558500/194569 – Mike Jan 29 '18 at 16:07
  • Правда я не понимаю как ваш код вообще работал. там два условия not in, первое берет все группы с количеством >1, второй с =1 и того эта два подзапроса дают эффект "удалить все записи, код которых не равен кодам для групп где количество записей >=1", но в любой группе заведомо есть >=1 записи... – Mike Jan 29 '18 at 16:17
  • Делал для Access по этому примеру: https://ru.stackoverflow.com/a/593638/280344 Все работало отлично :) – Василий Егоров Jan 29 '18 at 16:36
  • И почему в приведенном примере должна удалится только первая строка. Я вижу 3 строки garli/grlc чем таким отличается первая строка, что ее мы удаляем, а 2 оставляем ? – Mike Jan 29 '18 at 16:38
  • Потому что источник url_loaded у них разный (у 2-й и 3-й записи garli), а у 1 и 2 garli источник 1 и тот же, соответственно нужно оставить только 1 самую свежую из них. – Василий Егоров Jan 29 '18 at 17:27
  • А почему тогда в вопросе написано "Из нее нужно удалить все повторяющиеся старые записи по name и symbol", как по этой строке догадаться, что url то же надо сравнивать ? Кстати ответ вам дали исходя из этой строки ... – Mike Jan 29 '18 at 18:07
  • Да, приношу извинения, при редактировании не все поля выписал из запроса. Добавил в вопрос. Просто не думал что так все затянется, пока не возникало вообще никаких трудностей с конвертацией INSERT и UPDATE запросов, дошло дело до DELETE и что-то все затянулось надолго. – Василий Егоров Jan 29 '18 at 18:17

1 Answers1

0

Если вы хотите для сочетаний name, symbol оставить только самую свежую запись, то примерно так:

  • Находим name, symbol, max(date_load) для сочетания name, symbol

  • Теперь находим name, symbol, date_load, не совпадающие с найденными на первом шаге

  • И все их удаляем

Вот такая конструкция

 delete t1 from coins_info t1
         join  
           (select name, symbol, date_load 
              from coins_info t2 
              where (name, symbol, date_load) not in 
                (select name, symbol, max(date_load) 
                   from coins_info 
                group by name, symbol)
           ) as t3 
         using (name, symbol, date_load)  

sqlfiddle

splash58
  • 16,457
  • 1093 - You can't specify target table 't1' for update in FROM clause По ссылке выполняется, в базе - ошибка, магия :) Что есть t1? – Василий Егоров Jan 29 '18 at 17:38
  • по ссылке посмотрите, что у нас различается – splash58 Jan 29 '18 at 17:39
  • вот же - delete t1 from coins_info t1 t1 - алиас к coins_info – splash58 Jan 29 '18 at 17:40
  • Добавил еще поле url_loaded в Ваш запрос, так как у Вас удаляется нужная запись. Больше ничего не отличается. – Василий Егоров Jan 29 '18 at 17:41
  • добавлять его надо на все уровни или наоброт в конце - where a <> b – splash58 Jan 29 '18 at 17:43
  • http://sqlfiddle.com/#!9/e56dcd/1 вот, все работает как надо в браузере, но при запросе к БД - ошибка, код выше. Вообще не догоняю что-то. – Василий Егоров Jan 29 '18 at 17:45
  • Нужны специалисты, небось, по версиям mysql. Казалось бы должно работать – splash58 Jan 29 '18 at 17:47
  • А у вас точно mysql? – splash58 Jan 29 '18 at 17:47
  • Версия 5.7.21. Только пару дней как поставил. – Василий Егоров Jan 29 '18 at 17:50
  • Попробовал на своей локальной 5.5, прекрасно отработало – splash58 Jan 29 '18 at 17:58
  • @ВасилийЕгоров попробуйте delete t1.* ... далее по тексту. только условия склейки на свои не забудьте поменять, как они на самом деле, а не как указаны в вопросе – Mike Jan 29 '18 at 18:11
  • @Mike http://joxi.ru/ZrJG9LRs17KYRm та же ошибка. – Василий Егоров Jan 29 '18 at 18:20
  • @ВасилийЕгоров На одном японском (или хз каком, там иероглифы) сайте пишут что то про баг в версии MySQL 5.7, рекомендуют перед удалением выполнить SET optimizer_switch = 'derived_merge=off'; правда не удалось понять помогло им это или нет :) В общем попробуйте – Mike Jan 29 '18 at 18:41
  • @ВасилийЕгоров Еще предлагают добавить distinct сразу после слова select. Правда не во всех версиях помогает. Если в вашей версии не помогает, то берите другую, менее глючную версию. В 5.6 ошибки еще не было, появилась только в 5.7.6, причем про 5.7.13 пишут что ошибку уже исправили, видимо не до конца. – Mike Jan 29 '18 at 18:59
  • SET optimizer_switch = 'derived_merge=off'

    OK Time: 0s

    delete t1.* from coins_info t1 join
    (select name, symbol, date_last_load, url_loaded from coins_info t2 where (name, symbol, date_last_load, url_loaded) not in (select name, symbol, max(date_last_load), url_loaded from coins_info group by name, symbol, url_loaded)) as t3 using (name, symbol, date_last_load, url_loaded)

    Affected rows: 1552 Time: 56,642s Помогло derived_merge=off, его каждый раз перед удалением нужно выполнять?

    – Василий Егоров Jan 30 '18 at 07:19
  • @ВасилийЕгоров предположу, что на сеанс. И, кстати, если код у вас уникальный, можно немного иначе написать - http://sqlfiddle.com/#!9/3e0ddc/1 – splash58 Jan 30 '18 at 07:21
  • Да, так и сделал, по полю "Код", так как в аксессе именно по этому полю и был отбор записей. Вопрос с delete решил добавлением DISTINCT, всем спасибо за помощь! – Василий Егоров Jan 30 '18 at 08:25
  • Ура! Удачи вам! – splash58 Jan 30 '18 at 08:37