Простейший цикл на MySQL

Сегодня, работая над сайтом, мне надо было отделить основной каталог от дополнительного. А в дополнительном каталоге надо было пронумеровать нужные записи в виде «Проект 1», «Проект 2». И тут какой то неведомый зверь не позволил мне сделать это по-быстрому на каком нибудь распространенном языке программирования. Мне захотелось попробовать, а можно ли сделать это используя лишь только средства MySQL?
Насколько я помню, в MySQL есть переменные, например @a. Но поиск в сети, как сделать цикл в MySQL, ничего мне не дал.
Тогда я поразмыслил, ведь мы можем написать
SELECT @i:=@i+1;

А UPDATE в свою очередь проходит каждую запись и заменяет значение по одному.
SELECT @i := 0;
UPDATE `table` SET `name`=CONCAT('Проект ', @i := @i+1) WHERE `type` = 1 ORDER BY `id`;

В итоге мы переименовали записи с типом 1 по порядку следования их ID.
PS: CONCAT объединяет строки.
Ads
AdBlock has stolen the banner, but banners are not teeth — they will be back

More

Comments 11

    +10
    Как бы там и while есть и еще много чего, что узнает человек зайдя на сайт с документацией по mysql
      +1
      Собственно сам этого не знал. Но все таки под названия темы подходит. Вполне простейший цикл, причем работающий при условии заданном в запросе. Думаю найдутся люди, для которых эта статья будут полезна. Вот еще и о While узнают в комментариях. Насколько я понимаю, в данном случае он не подошел бы.
      +1
      Зачем еще и подзапрос? Можно и так:
      UPDATE `table` SET `name`=CONCAT('Проект ', @i := @i+1) WHERE `type` = 1 ORDER BY `id`;


      А насчет цикла, я где то в интернете натыкался на организацию цикла с помощью Benchmark, правда он не подойдет для запросов типа UPDATE. А то, что вы называете циклом в вашей статье, как то слабо на него похоже, это всего лишь обычный способ использовать переменные.
        –1
        Спасибо исправил. Но все таки при поиске проблемы люди будут искать именно цикл при изменении записей. А хабр хорошо индексируется в поисковиках. Если еще побольше информации в циклах в mysql наберется в комментариях…
        0
        Америку конечно лично мне не открыли, с помощью переменных действительно многое удобно делать.
        Хочу привести ещё один пример, посложнее, применения переменных в запросе:
        Выборка вложенного в одно поле параметра
        Иногда для хранения различных характеристик товара, чтобы не плодить громадных таблиц, удобно записать набор параметров прямо в поле `params` таблицы, в виде '|key:value|key:value|key:value|...|'.
        Поиск по определённому параметру примитивен, используя LIKE:
        SELECT `id` FROM `table` WHERE `params` LIKE '%|partam1:100500|%'
        

        Но когда встал вопрос выборки по какому-то одному параметру, тут уже начинаются сложности. Например вывести список значений параметра param1. Можно конечно обойтись без переменных, но тогда запрос будет сложнее. На помощь приходят переменные:
        SELECT DISTINCT
        	SUBSTRING(`params`, @start, LOCATE('|', `params`, @start)-@start) as 'val'
        FROM
        	`table`, (select @start:=0) s
        WHERE
        		`params` LIKE '%|param1:%'
        		&& (@start := LOCATE('|param1:', `params`)+LENGTH('|param1:')) is not null

          +2
          трэш какой
            0
            На сколько я помню, в таком поиске не будет работать индекс и, как следствие, резко упадет производительность.
              0
              Да проблемы с производительностью тут естественно есть, поэтому использовать такие конструкции нужно в «правильных местах» и с умом, т. к. индексы не используются.
                0
                Я например этот запрос применял для вывода таблицы параметров одного товара (товар был специфичный, маслостанции, у каждого товара «подтоваров» с разными параметрами — вольтаж, объём бака, производительность).
                Для вывода таблицы параметров всей группы товаров используется этот запрос (плюс для сбережения производительности используется кэш).
                Кстати мерил производительность, в данном случае она мало различается, т. к. сделать манипуляции над небольшим количеством строк получалось быстрее, чем осуществлять поиск в большой таблице (пусть и с индексами).
            +6
            Только это не цикл, а эмуляция ROW_NUMBER().
              0
              Но поиск в сети, как сделать цикл в MySQL, ничего мне не дал.

              Странно как-то вы искали. В следующий раз идите сразу в доку. Flow Control Statements

              Only users with full accounts can post comments. Log in, please.