Форум на Kuban.ru (http://forums.kuban.ru/)
-   Веб-дизайн и программирование (http://forums.kuban.ru/f1030/)
-   -   Help SQL (http://forums.kuban.ru/f1030/help_sql-6439237.html)

oleg747 20.01.2015 11:48

Help SQL
 
Доброго всем дня!
Проблема вот какая. Есть некая таблица
CREATE TABLE IF NOT EXISTS `ololo` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`kod` varchar(100) DEFAULT NULL,
`kolvo` float DEFAULT NULL,
`err` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=4 ;

Там есть и будут(оч на это надеюсь)
INSERT INTO `ololo` (`id`, `kod`, `kolvo`, `err`) VALUES
(1, '123', 5, NULL),
(2, '123', 5, NULL),
(3, '321', 1, NULL);

Необходимо написать запрос который будет проверять дубли. Т.е если kod и kolvo есть в таблице совершать update err = 'ОШИБКА'

Вот этот запрос выдаёт мне эти айдишки
select `o1`.`id` from `ololo` as `o1` where exists (select * from `ololo` as `o2` where o2.id <> o1.id and o2.kod = o1.kod)

А вот этот запрос не хочет выполняться

UPDATE ololo SET err = 'ОШИБКА' WHERE id IN (select `o1`.`id` from `ololo` as `o1` where exists (select * from `ololo` as `o2` where o2.id <> o1.id and o2.kod = o1.kod));

Выдает вот чего
#1093 - You can't specify target table 'ololo' for update in FROM clause

Как можно решить данную проблему?

40KHYTbIU 20.01.2015 12:12

Я не уверен, но возможно что селект лочит строки в мускул и поэтому не дает изменять таблицу, вобщее так делать нехорошо.
Этот код вызывается откуда? php?
Можете сделать процедуру, которая будет вытаскивать идентификаторы и потом либо в цикле либо через динамический SQL обновлять поле ERR

40KHYTbIU 20.01.2015 12:16

[url]http://www.sql.ru/forum/876053/vechnaya-voznya-s-you-can-t-specify-target[/url]

oleg747 20.01.2015 12:28

1-40KHYTbIU > СПАСИБО ОГРОМНОЕ
вот тоже такое подозрение)))) видимо придётся разбить на 2 части... выборка этого самого запроса которая будет этим самым in($peremen) а потом уже выполнять его.
Просто хотелось бы выделиться))) что можно это делать одним запросом.
Кстати если сделать копии таблицы и select для IN выполнять из неё все работает)))

1is 21.01.2015 13:26

0-oleg747 > условная процедура:
if ("SQL select") then "error" else "SQL insert"
Где,
"SQL select" - запрос сведений из таблицы. Не такой как у Вас, а
select * from `ololo` where `id`=id, `kod`=kod, `kolvo`=kolvo, `err`=err
Смысл в том, что если запрос возвращает данные (есть такая строка) условие в блоке if получает ненулевое (true) значение (зависит от языка программирования).
"error" - код ошибки на вывод
"SQL insert" - добавление сведений.

40KHYTbIU 21.01.2015 14:21

3-oleg747 > Решение в один запрос на основе ссылки из 2:

UPDATE ololo SET err = 'ERROR' WHERE id IN (select `mo`.`id` from (select `o1`.`id` from `ololo` as `o1` where exists (select * from `ololo` as `o2` where o2.id <> o1.id and o2.kod = o1.kod)) as `mo`);

droidman 21.01.2015 19:38

5-40KHYTbIU >
[code]select `mo`.`id` from[/code]
зачем этот селект?)

40KHYTbIU 21.01.2015 19:46

6-droidman > 2 читал?

droidman 21.01.2015 22:31

7-40KHYTbIU > прочёл, но там JOIN рекомендуют =)
Это я даже не заикалсо ещё про group/having вместо exists(select *

oleg747 22.01.2015 08:11

5-40KHYTbIU > вот это ВАУ!!! Спасибо огромнейшее.
Получается к тому, что я написал нужно было добавить еще один селект?)))) здорово))))
Это действительно отрабатывает. И очень быстро. Нужно проверить как оно будет работать когда в таблице будет несколько тысяч строчек.
Еще раз спасибо огромное!!!

40KHYTbIU 22.01.2015 14:45

8-droidman > Я говорил выше, что не знаю тонкостей MySQL, но ИМХО джоин будет дольше, мне так кажется.
И если вы такой грамотный, привели бы решение.

droidman 22.01.2015 18:01

10-40KHYTbIU > не, я чисто поумничать) сами мы тупые)
Просто никак не могу забыть случаев, когда люди связывали таблицы по строкам (а не ключам) и делали индексы от хэшей, превышающие размерами саму таблицу на диске. А денормализация была панацеей от всего, в том числе планирования ;)

oleg747 23.01.2015 08:57

10-40KHYTbIU > join действительно отрабатывает значительно дольше!!! еще раз спасибо!!!


Текущее время: 04:41. Часовой пояс GMT +3.