Задать вопрос
lightalex
@lightalex

Как одним запросом mysql убить двух зайцев?

Всем привет!
Есть два запроса mysql:
SELECT * FROM emails WHERE status=0 order by rand() limit 1
UPDATE emails SET status='1' WHERE id=5111

То есть первый запрос извлекает рандомную запись из базы, а второй блокирует ее изменением поля status
id во второй запрос подставляется с помощью php
Можно ли как-то совместить это в один запрос?
При это мы все равно должны получать в ответ рандомную запись
  • Вопрос задан
  • 353 просмотра
Подписаться 1 Оценить Комментировать
Решения вопроса 1
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
Если нужно выбирать данные параллельными скриптами, то надёжно работает такой вариант:
UPDATE `emails` SET `status` = 1 WHERE @id := `id` AND `status` = 0 ORDER BY RAND() LIMIT 1;
SELECT * FROM `emails` WHERE `id` = @id;

Вот только сортировка по RAND() очень медленная, по возможности от неё лучше отказаться.
Ответ написан
Пригласить эксперта
Ответы на вопрос 5
@nirvimel
UPDATE emails SET status='1' WHERE id=(SELECT id FROM emails WHERE status=0 order by rand() limit 1)
Ответ написан
bigton
@bigton
Web-программист
1. Сделайте в таблице поле proccess типа double по умолчанию 0.
2. В PHP скрипте сделайте $process_id = microtime(TRUE) + getmypid(); чтобы получить уникальный для каждого вызова скрипта идентификатор процесса.
3. UPDATE `emails` SET `process` = $process_id WHERE `process` = 0 LIMIT 1
4. SELECT * FROM `emails` WHERE `process` = $process_id
Таким образом вы добьетесь того, чтобы запускаемые параллельно на обработку скрипты не брали одни данные для обработку. А вы, как я понял, решаете именно такую задачу.
Ответ написан
Комментировать
Hostwell
@Hostwell
а зачем вам таким образом блокировать. Мне кажется вы хотите решить свою проблему изначально не правильным способом.
Ответ написан
xytop
@xytop
PHP/RoR web dev & tech lead
UPDATE emails SET status=1, id=LAST_INSERT_ID(id) order by RAND() LIMIT 1

Потом можно выбрать обновленную запись через SELECT LAST_INSERT_ID() или mysql_last_insert_id()
Ответ написан
Комментировать
martin74ua
@martin74ua Куратор тега MySQL
Linux administrator
обернуть вызов запросов в транзакцию не подойдет?
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы