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

Тема в разделе "Базы данных", создана пользователем o_nix, 25 авг 2011.

Статус темы:
Закрыта.
Модераторы: latteo
  1. o_nix

    o_nix

    Регистр.:
    7 ноя 2007
    Сообщения:
    1.073
    Симпатии:
    1.037
    Есть запрос
    Код:
    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 ?
     
  2. DrakonHaSh

    DrakonHaSh

    Регистр.:
    29 июн 2010
    Сообщения:
    358
    Симпатии:
    122
    попробуйте
    PHP:
    UPDATE `postsSET `status` = `1`
    WHERE `idIN 
    (
     
    SELECT id
      FROM 
    (
            
    SELECT *
            
    FROM `posts`
            
    WHERE `cat` = AND `status` = 0
            ORDER BY RAND
    ()
            
    LIMIT 3
             
    )x
    )
     
  3. o_nix

    o_nix

    Регистр.:
    7 ноя 2007
    Сообщения:
    1.073
    Симпатии:
    1.037
    Код:
    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, '');
    
     
  4. stealthdebuger

    stealthdebuger Механик

    Administrator
    Регистр.:
    25 авг 2008
    Сообщения:
    628
    Симпатии:
    1.388
    PHP:
    UPDATE `posts` AS `aINNER JOIN (SELECT FROM `postsWHERE `cat` =AND `status` =0 ORDER BY rand() LIMIT 3) AS `bON `a`.`id` = `b`.`idSET `a`.`status` =1
     
    o_nix нравится это.
  5. Phrack

    Phrack

    Регистр.:
    3 ноя 2010
    Сообщения:
    264
    Симпатии:
    38
    мда...мускул поражает. Надеюсь в нем нормально поддерживаются транзакции. Делайте 2 запроса, чтобы не зависеть от ядра и не мучайтесь.

    По поводу символа Х из предыдущего поста тс - это алиас для инлайн вью (или derived table, видимо в терминах мускула). Каждая такая вьюха ДОЛЖНА иметь алиас
     
    o_nix нравится это.
  6. o_nix

    o_nix

    Регистр.:
    7 ноя 2007
    Сообщения:
    1.073
    Симпатии:
    1.037
    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 в одном запросе??
     
  7. polyetilen

    polyetilen Заблокирован

    Регистр.:
    10 авг 2006
    Сообщения:
    814
    Симпатии:
    474
    Как пишут в документации

    http://dev.mysql.com/doc/refman/5.0/en/update.html

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

    В настоящее время вы не можете обновлять таблицу и выбирать из той же таблицы в подзапросе.
     
  8. DrakonHaSh

    DrakonHaSh

    Регистр.:
    29 июн 2010
    Сообщения:
    358
    Симпатии:
    122
    напрямую - нельзя, а через
    select * from (select * from table)x
    можно :)


    o_nix
    надо так:
    PHP:
    UPDATE `postsSET `status` = 1
    WHERE 
    `idIN 
    (
     
    SELECT id
      FROM 
    (
            
    SELECT *
            
    FROM `posts`
            
    WHERE `cat` = AND `status` = 0
            ORDER BY RAND
    ()
            
    LIMIT 3
           
    )x
    )  
    а с первого раза не сработало бо вы меня сами попутали:
    `1` - это не скаляр (не число, не строка), а значение колонки c именем 1
     
    o_nix нравится это.
  9. o_nix

    o_nix

    Регистр.:
    7 ноя 2007
    Сообщения:
    1.073
    Симпатии:
    1.037
    да я что только не пробовал чтобы запрос сработал оттуда и эти хитрые кавычки появились.
    Я такой жуткий "специалист" по 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 
    ) 
     
  10. stealthdebuger

    stealthdebuger Механик

    Administrator
    Регистр.:
    25 авг 2008
    Сообщения:
    628
    Симпатии:
    1.388
    Как было сказано выше,
    Решить такую задачу можно только одним способом... создавать триггер.
     
Статус темы:
Закрыта.