web-dev-qa-db-ja.com

MySQLの増分値

複数の挿入がある場合、挿入ごとに値を増加させる方法はありますか? (自動インクリメントする主キーについては語りません)

私はこのような構造を持っているとしましょう:

|ID_PRODUCT|ID_CATEGORY|NAME|POSITION|

そのため、個々の製品IDがあり、各製品はカテゴリに属し、このカテゴリで異なる位置にあります。私はこのようなことをしたい:

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

そのため、変数MY_POSITIONが1で始まり、挿入ごとに増分する必要があります。

これをすべてphpやpythonのようなスクリプト言語で行うのは本当に簡単ですが、SQLでもっと良くなりたいです:)

29
user945967

はい: ユーザー定義変数 を使用します:

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へのインクリメントの結果は、挿入に使用される値です。


編集:

初期値をインラインで処理することにより、変数の宣言をスキップできます。

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

これは、複数のコマンド(セミコロンで区切られた)を許可しないドライバーを使用してクエリを実行するときに特に便利です。

64
Bohemian

Id_categoryでORDER BYし、2つのユーザー変数を使用して、以前のカテゴリIDを追跡できるようにする必要があります-

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;

これにより、カテゴリごとにではなく、1つのクエリですべてのカテゴリを実行できます。

5
nnichols

純粋に@Bohemiansの答えに追加する-私はカウンターを頻繁にリセットしたかったのですが、これは次のように行うことができます:

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

ここで、15は明らかにリセット前の最大数です。

3
Antony

このようなサブクエリを使用して値を設定してみてください

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

または

(SELECT MAX(position) FROM products AS T2 WHERE id_category = 'product category')+1
2
Oriesok Vlassky