Supongamos que tengo la tabla:
id | val_1 | val_2 1 | 1 | 0 2 | 1 | 1 3 | 1 | 2 4 | 2 | 0val_2 debería ser cero al principio si no había filas con val_1 antes. De lo contrario, debería ser anterior val_2 + 1 para este val_1.
No puedo averiguar por mí mismo la mejor manera de hacerlo. Lo único que he inventado es disparar después de insertar, pero creo que aquí tal vez haya alguna otra forma de hacerlo más limpio y rápido. Mi código es algo como:
DELIMITER $$ CREATE TRIGGER after_table_insert AFTER INSERT ON table FOR EACH ROW BEGIN UPDATE table SET val_2 = t.val_2 + 1 FROM ( SELECT val_2 FROM table WHERE val_1 = new.val_1 ORDER BY id DESC LIMIT 1 ) t WHERE id = new.id; END$$ DELIMITER ;¡Apreciaré cualquier ayuda! Que tengas un gran día/noche.
Tiene un par de problemas con dicha configuración:
¿Qué sucede si ACTUALIZA o ELIMINA filas? Puede estropear todo con val2. Ten cuidado con eso.
Val2 siempre se puede calcular y no es necesario almacenarlo.
Habiendo dicho eso, a continuación le mostraré una configuración con la que almacenaré solo id y val1. Luego, val2 se calculará dentro de la declaración SELECT (por lo que siempre será correcto).
CREATE TABLE vals( id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, val INT NOT NULL ); INSERT INTO vals(val) VALUES(1),(1),(1),(2);Ahora lo que voy a hacer es usar la función ROW_NUMBER() (que imprime el número de fila) y ejecutarla sobre una PARTICIÓN POR val:
SELECT id, val, ROW_NUMBER() OVER ( PARTITION BY val ) AS val2 FROM vals;Estamos casi alli. Lamentablemente, los compensará en 1 en comparación con lo que necesita:
+----+-----+------+ | id | val | val2 | +----+-----+------+ | 1 | 1 | 1 | | 2 | 1 | 2 | | 3 | 1 | 3 | | 4 | 2 | 1 | +----+-----+------+La solución es simple. Simplemente agregue "-1" y estará listo.
SELECT id, val, -1+ROW_NUMBER() OVER ( PARTITION BY val ) AS val2 FROM vals;Esto producirá:
+----+-----+------+ | id | val | val2 | +----+-----+------+ | 1 | 1 | 0 | | 2 | 1 | 1 | | 3 | 1 | 2 | | 4 | 2 | 0 | +----+-----+------+Con esta solución, no es necesario almacenar val2 en absoluto (puede crearlo como VISTA si lo desea) y no es vulnerable al problema cuando elimina una fila (continuará funcionando correctamente).
Esta es una posibilidad
Esquema (MySQL v5.7)
CREATE TABLE table1 ( `id` INTEGER, `val_1` INTEGER, `val_2` INTEGER ); DELIMITER // CREATE TRIGGER after_table_insert BEFORE INSERT ON table1 FOR EACH ROW BEGIN SET @maxval2 = 0; SELECT max(val_2) + 1 into @maxval2 FROM table1 WHERE val_1 = new.val_1; IF @maxval2 IS NULL THEN SET @maxval2 = 0; END IF; SET NEW.val_2 = @maxval2; END// DELIMITER ; INSERT INTO table1 (`id`, `val_1`, `val_2`) VALUES ('1', '1', '0'), ('2', '1', '0'), ('3', '1', '0'), ('4', '2', '0'), ('4', '2', '0');Consulta #1
SELECT * FROM table1; | id | val_1 | val_2 | | --- | ----- | ----- | | 1 | 1 | 0 | | 2 | 1 | 1 | | 3 | 1 | 2 | | 4 | 2 | 0 | | 4 | 2 | 1 |