Объеденить SELECT + UPDATE ??

Статус
В этой теме нельзя размещать новые ответы.

o_nix

Хранитель порядка
Регистрация
7 Ноя 2007
Сообщения
1.070
Реакции
1.063
Есть запрос
Код:
SELECT * FROM `posts` WHERE `cat` = 2 AND `status` = 0 ORDER BY RAND( ) LIMIT 3
он выдаёт 3 рандомных поста
далее эти данные я использую в своих целях.
но мне эти данные которые мне были выданы нужно обновить
пометить их чтобы они не выдавались при следующем запросе

ясное дело что можно сделать отдельный запрос UPDATE
но это делать не хочется

По "гугелучебнику" родил вот такой вот запрос
Код:
UPDATE `posts` SET `status` = `1` WHERE `id` IN (
SELECT * FROM `posts` WHERE `cat` = 2 AND `status` = 0 ORDER BY RAND( ) LIMIT 3
)

Но злое MySQL выдаёт в ответ это
Код:
Ответ MySQL: Документация
#1235 - This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'

Спецы подскажите можно ли всё таки объединить всё в один запрос чтобы результатом был такой же вывод как и при обычном SELECT или только делать отдельный UPDATE ?
 
попробуйте
PHP:
UPDATE `posts` SET `status` = `1`
WHERE `id` IN 
(
 SELECT id
  FROM (
        SELECT *
        FROM `posts`
        WHERE `cat` = 2 AND `status` = 0
        ORDER BY RAND()
        LIMIT 3
		 )x
)
 
Код:
SQL-запрос: Документация

UPDATE `posts` SET `status` = `1` WHERE `id` IN (
SELECT id
FROM (

SELECT *
FROM `posts`
WHERE `cat` =2
AND `status` =0
ORDER BY RAND( )
LIMIT 3
)
)

Ответ MySQL: Документация
#1248 - Every derived table must have its own alias

не знаю что за символ x, но не работает ни с ним ни без него

Код:
SQL-запрос: Документация

UPDATE `posts` SET `status` = `1` WHERE `id` IN (
SELECT id
FROM (

SELECT *
FROM `posts`
WHERE `cat` =2
AND `status` =0
ORDER BY RAND( )
LIMIT 3
)x
)

Ответ MySQL: Документация
#1054 - Unknown column '1' in 'field list'


Таблица для опытов
Код:
CREATE TABLE `posts` (
  `id` int(11) unsigned NOT NULL auto_increment,
  `url` varchar(255) NOT NULL,
  `date` datetime NOT NULL default '0000-00-00 00:00:00',
  `cat` int(11) unsigned NOT NULL default '0',
  `title` varchar(255) NOT NULL default '',
  `story` text NOT NULL,
  `source_id` int(11) unsigned NOT NULL default '0',
  `receiver_id` int(11) unsigned NOT NULL default '0',
  `status` int(1) unsigned NOT NULL default '0',
  `tags` varchar(255) NOT NULL,
  PRIMARY KEY  (`id`),
  KEY `cat` (`cat`),
  KEY `source_id` (`source_id`),
  KEY `receiver_id` (`receiver_id`),
  KEY `status` (`status`)
) ENGINE=MyISAM AUTO_INCREMENT=224 DEFAULT CHARSET=cp1251 AUTO_INCREMENT=224 ;


INSERT INTO `posts` VALUES (204, 'url1', '2011-08-23 22:46:29', 2, 'тайтл 1', 'текст поста 1', 3, 1, 0, '');
INSERT INTO `posts` VALUES (205, 'url2', '2011-08-23 22:46:29', 2, 'тайтл 2', 'текст поста 2', 3, 1, 0, '');
INSERT INTO `posts` VALUES (206, 'url3', '2011-08-23 22:46:29', 2, 'тайтл 3', 'текст поста 3', 3, 1, 0, '');
INSERT INTO `posts` VALUES (207, 'url4', '2011-08-23 22:46:29', 2, 'тайтл 4', 'текст поста 4', 3, 1, 0, '');
INSERT INTO `posts` VALUES (208, 'url5', '2011-08-23 22:46:29', 2, 'тайтл 5', 'текст поста 5', 3, 1, 0, '');
 
PHP:
UPDATE `posts` AS `a` INNER JOIN (SELECT * FROM `posts` WHERE `cat` =2 AND `status` =0 ORDER BY rand() LIMIT 3) AS `b` ON `a`.`id` = `b`.`id` SET `a`.`status` =1
 
мда...мускул поражает. Надеюсь в нем нормально поддерживаются транзакции. Делайте 2 запроса, чтобы не зависеть от ядра и не мучайтесь.

По поводу символа Х из предыдущего поста тс - это алиас для инлайн вью (или derived table, видимо в терминах мускула). Каждая такая вьюха ДОЛЖНА иметь алиас
 
stealthdebuger
данный запрос работает но выдаёт он лиш то что 3 неких поста были обновлены
его вполне мог бы заменить такой запрос
Код:
UPDATE `posts` SET `status`= 1 WHERE (`cat` = 2 and `status` = 0) ORDER BY RAND( ) LIMIT 3;
а мне в качестве результата нужен SELECT * всех этих постов

Сделал отдельный запрос в sql с UPDATE...

Пробовал сделать наоборот - вложить update в select по аналогии с твоим примером - не срослось.

Вопрос мучает - всё таки нельзя получить SELECT * выполнив при этом UPDATE в одном запросе??
 
Как пишут в документации

Currently, you cannot update a table and select from the same table in a subquery.

В настоящее время вы не можете обновлять таблицу и выбирать из той же таблицы в подзапросе.
 
Как пишут в документации
*** скрытое содержание ***
Currently, you cannot update a table and select from the same table in a subquery.
В настоящее время вы не можете обновлять таблицу и выбирать из той же таблицы в подзапросе.
напрямую - нельзя, а через
select * from (select * from table)x
можно :)


o_nix
надо так:
PHP:
UPDATE `posts` SET `status` = 1
WHERE `id` IN 
(
 SELECT id
  FROM (
        SELECT *
        FROM `posts`
        WHERE `cat` = 2 AND `status` = 0
        ORDER BY RAND()
        LIMIT 3
       )x
)
а с первого раза не сработало бо вы меня сами попутали:
По "гугелучебнику" родил вот такой вот запрос
Код:
UPDATE `posts` SET `status` = [color=red]`[/color]1[color=red]`[/color] WHERE `id` IN (
SELECT * FROM `posts` WHERE `cat` = 2 AND `status` = 0 ORDER BY RAND( ) LIMIT 3
)
`1` - это не скаляр (не число, не строка), а значение колонки c именем 1
 
`1` - это не скаляр (не число, не строка), а значение колонки c именем 1
да я что только не пробовал чтобы запрос сработал оттуда и эти хитрые кавычки появились.
Я такой жуткий "специалист" по MySQL что ещё и не то могу написать :D

Да теперь работает но абсолютно также как и банальное
Код:
UPDATE `posts` SET `status`= 1 WHERE (`cat` = 2 and `status` = 0) ORDER BY RAND( ) LIMIT 3;
и не банальное
Код:
UPDATE `posts` AS `a` INNER JOIN (SELECT * FROM `posts` WHERE `cat` =2 AND `status` =0 ORDER BY rand() LIMIT 3) AS `b` ON `a`.`id` = `b`.`id` SET `a`.`status` =1

Те только выделение, без выдачи SELECT *

Изобретён ещё один не банальный способ получения не того что хотелось :)


попробовал вот так но не работает
Код:
SELECT *
FROM `posts`
WHERE `id` IN
(
SELECT id
FROM (
		UPDATE `posts` SET `status` =1
		WHERE (`cat` = 3 AND `status` = 0)
		ORDER BY RAND( ) LIMIT 3;
		)x 
)
 
Как было сказано выше,
Currently, you cannot update a table and select from the same table in a subquery.

Решить такую задачу можно только одним способом... создавать триггер.
 
Статус
В этой теме нельзя размещать новые ответы.
Назад
Сверху