Teniendo en cuenta la tabla orders
:
+-----------+----------------+
| AccountID | AccountOrderID |
+-----------+----------------+
| 1 | NULL |
| 5 | NULL |
| 1 | NULL |
| 6 | NULL |
| 5 | NULL |
| 2 | NULL |
| 6 | NULL |
| 4 | NULL |
| 4 | NULL |
| 5 | NULL |
+-----------+----------------+
¿Cómo puedo asignar un ID incremental AccountOrderID
relativamente a Account ID
, de manera que el resultado será igual:
+-----------+----------------+
| AccountID | AccountOrderID |
+-----------+----------------+
| 1 | 1 |
| 5 | 1 |
| 1 | 2 |
| 6 | 1 |
| 5 | 2 |
| 2 | 1 |
| 6 | 2 |
| 4 | 1 |
| 4 | 2 |
| 5 | 3 |
+-----------+----------------+
Hasta el momento yo estaba usando el users
con una columna llamada LastOrderID
y un disparador para incrementarlo junto con el AccountOrderID
(que funciona bien):
DELIMITER $$
CREATE TRIGGER `new_order` BEFORE INSERT ON maindb.orders
FOR EACH ROW BEGIN
UPDATE users
SET LastOrderID = LastOrderID + 1
WHERE AccountID = NEW.AccountID;
SET NEW.AccountOrderID = (SELECT LastOrderID FROM Credentials WHERE AccountID = NEW.AccountID);
END;
$$
DELIMITER ;
Pero yo creo que la users
mesa no se debe utilizar para este propósito: ¿hay una otra manera de achive este resultado?
EDITAR
Incluso si es exactamente lo que dijo GMB, aquí es una respuesta que ofrece un ejemplo similar: https://stackoverflow.com/a/2404587/9373031
Usted puede hacer esto con row_number()
si está ejecutando MySQL 8.0. Pero se necesita otra columna para hacer la clase consistente. Suponiendo que la clave primaria de la tabla es order_id
, que puede hacer:
select
order_id,
account_id,
row_number() over(partition by account_id order by order_id) account_order_id
from orders
A primera vista, no me recomiendan realmente almacenar estos números, ya que este caso es necesario para mantener esa información derivada - puede crear una vista en lugar. Pero desde que solicitó la update
consulta:
update orders o
inner join (
select
order_id,
row_number() over(partition by account_id order by order_id) account_order_id
from orders
) o1 on o1.order_id = o.order_id
set o.account_order_id = o1.account_order_id
Tenga en cuenta que esto actualiza toda la tabla a la vez (mientras que la solución original tiene un bucle dentro de un procedimiento almacenado); generalmente no hay necesidad de bucles en SQL, que es un lenguaje basado en conjuntos.