MySQL, увеличивающий значение - PullRequest
28 голосов
/ 09 марта 2012

Есть ли способ сделать приращение значения с каждой вставкой, если есть несколько вставок? (Я не говорю о первичном ключе, который автоинкрементен)

Допустим, у меня есть такая структура:

|ID_PRODUCT|ID_CATEGORY|NAME|POSITION|

Таким образом, у меня есть индивидуальные идентификаторы продуктов, каждый продукт относится к категории и имеет другую позицию в этой категории. Я хочу сделать что-то вроде этого:

INSERT INTO products
( SELECT id_product, id_category, name, MY_POSITION++
  FROM db2.products WHERE id_category = xxx )

Таким образом, должна быть переменная MY_POSITION, которая начинается с 1 и увеличивает каждую вставку.

Было бы действительно легко сделать все это только с помощью языка сценариев, такого как php или python, но я хочу стать лучше с SQL:)

Ответы [ 5 ]

63 голосов
/ 09 марта 2012

Да: используйте пользовательскую переменную :

SET @position := 0; -- Define a variable
INSERT INTO products
SELECT id_product, id_category, name, (@position := @position + 1)
FROM db2.products
WHERE id_category = xxx;

Результатом увеличения до @position является значение, используемое для вставки.


Edit:

Вы можете пропустить объявление переменной, обработав начальное значение в строке:

...
SELECT ..., (@position := ifnull(@position, 0) + 1)
...

Это может быть особенно удобно при выполнении запроса с использованием драйвера, который неразрешить несколько команд (разделенных точкой с запятой).

5 голосов
/ 09 марта 2012

Вам потребуется ORDER BY id_category и использовать две пользовательские переменные, чтобы вы могли отслеживать предыдущий идентификатор категории -

SET @position := 0;
SET @prev_cat := 0;

INSERT INTO products
SELECT id_product, id_category, name, position
FROM (
    SELECT
        id_product,
        id_category,
        name,
        IF(@prev_cat = id_category, @position := @position + 1, @position := 1) AS position,
        @prev_cat := id_category
    FROM db2.products
    ORDER BY id_category ASC, id_product ASC
) AS tmp;

Это позволит вам выполнять все категории в одном запросе вместо категории по категории.

3 голосов
/ 10 марта 2017

Чисто добавить к ответу @Bohemians - я хотел, чтобы счетчик сбрасывался время от времени, и это можно сделать так:

SELECT *,(@position := IF (@position >= 15,1,@position + 1))

Где 15, очевидно, максимальное числодо сброса.

2 голосов
/ 09 марта 2012

Попробуйте установить значение, используя такой подзапрос, как этот

 (SELECT MAX(position) FROM products AS T2)+1

Или

(SELECT MAX(position) FROM products AS T2 WHERE id_category = 'product category')+1
0 голосов
/ 10 декабря 2014

Надеюсь, это сработает.

update <tbl_name> set <column_name>=<column_name>+1 where <unique_column/s>='1'";
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...