Valor incremental de MySQL
¿Hay alguna manera de incrementar el valor con cada inserción si se tienen varias inserciones? (No hablo de la clave principal que se autoincrementa)
Digamos que tengo una estructura como esta:
|ID_PRODUCT|ID_CATEGORY|NAME|POSITION|
Entonces tengo identificaciones de productos individuales, cada producto pertenece a una categoría y tiene una posición diferente en esta categoría. Quiero hacer algo como esto:
INSERT INTO products
( SELECT id_product, id_category, name, MY_POSITION++
FROM db2.products WHERE id_category = xxx )
Entonces debería haber una variable MY_POSITION que comience con 1 e incremente con cada inserción.
Sería muy fácil hacer todo esto sólo con un lenguaje de scripting como php o python, pero quiero mejorar con SQL :)
Sí: utilice una variable definida por el usuario :
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;
El resultado del incremento @position
es el valor utilizado para la inserción.
Editar:
Puede omitir la declaración de la variable manejando el valor inicial en línea:
...
SELECT ..., (@position := ifnull(@position, 0) + 1)
...
Esto puede resultar especialmente útil al ejecutar la consulta utilizando un controlador que no permite múltiples comandos (separados por punto y coma).
Deberá ORDENAR POR id_category y utilizar dos variables de usuario para poder realizar un seguimiento de la identificación de la categoría anterior:
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;
Esto le permitirá realizar todas las categorías en una sola consulta en lugar de categoría por categoría.
Simplemente para agregar a la respuesta de @Bohemians: quería que el contador se reiniciara de vez en cuando y esto se puede hacer así:
SELECT *,(@position := IF (@position >= 15,1,@position + 1))
Donde 15 es obviamente el número máximo antes del reinicio.