Mysql - Cómo averiguar el último registro insertado en una tabla

Hay veces que realizamos operaciones de inserción que involucran valores autonuméricos y necesitamos averiguar el idetificador del último registro que hemos añadido para utilizarlo en verificaciones, o incluso en otras operaciones con la base de datos, como insertar registros hijos.

La función a utilizar en este caso sería last_insert_id(), a continuación muestro un ejemplo de su funcionamiento

He establecido un entorno de pruebas muy sencillo con un pequeño esquema que representa un sistema de autobuses y sus viajeros.

La tabla autobuses registraría las diferentes líneas entre dos ciudades. Para identificar los autobuses se utiliza una columna de tipo AUTO_INCREMENT que aumentará de valor automáticamente sin que tengamos que especificarla. Al crear una columna de este tipo, es obligatorio que se use en una clave, así que la usaremos como clave primaria.
CREATE TABLE autobuses(
id_bus int not null AUTO_INCREMENT,
ciudad_origen text not null,
ciudad_destino text not null,
PRIMARY KEY(id_bus)
);

La tabla de viajeros registraría los viajeros que pueden utilizar el servicio, se utiliza un identificador de viajero del mismo tipo que el identificador del autobus
CREATE TABLE viajeros(
id_viajero int not null AUTO_INCREMENT,
nombre text not null,
apellidos text not null,
PRIMARY KEY(id_viajero)
);

Por último necesitamos una tabla que referencie los autobuses con los viajeros en una fecha, es decir que controle las fechas y las líneas que utiliza cada viajero.
CREATE TABLE autobuses_viajeros(
id_bus int not null,
id_viajero int not null,
fecha date not null
);

Damos de alta un autobús realizando una operación de inserción (omitimos el campo de identificación del autobús porque se rellena de forma automática con la columna de tipo AUTO_INCREMENT)
mysql> insert into autobuses (ciudad_origen, ciudad_destino)
VALUES ('Barcelona', 'Zaragoza');
Query OK, 1 row affected (0.02 sec)

Podemos recuperar el valor del último registro generado con last_insert_id()
mysql> select last_insert_id();
+------------------+
| last_insert_id() |
+------------------+
| 1 |
+------------------+
1 row in set (0.00 sec)

Podemos dar de alta viajeros insertándolos, cada vez que insertemos un registro que involucra a una columna de tipo AUTO_INCREMENT o autonumérica, el valor de last_insert_id() varía, es decir que se genera cada vez que se llama a un autonumérico a nivel de sesión.
mysql> insert into viajeros (nombre,apellidos)
VALUES ('Juan', 'Pérez');
Query OK, 1 row affected (0.01 sec)
mysql> select last_insert_id();
+------------------+
| last_insert_id() |
+------------------+
| 1 |
+------------------+
1 row in set (0.00 sec)
mysql> insert into viajeros (nombre,apellidos)
VALUES ('Manuel', 'Fernández');
Query OK, 1 row affected (0.02 sec)
mysql> select last_insert_id();
+------------------+
| last_insert_id() |
+------------------+
| 2 |
+------------------+
1 row in set (0.00 sec)
mysql> insert into viajeros (nombre,apellidos)
VALUES ('María', 'López');
Query OK, 1 row affected (0.02 sec)
mysql> select last_insert_id();
+------------------+
| last_insert_id() |
+------------------+
| 3 |
+------------------+
1 row in set (0.00 sec)

Debo aclarar también que el valor de last_insert_id() es privado para la sesión que ejecuta las llamadas a columnas de tipo AUTO_INCREMENT, nadie más excepto nuestra sesión tendrá acceso al identificador de registro generado.

El valor recuperado por last_insert_id() se puede utilizar normalmente donde prodría ir una expresión, por ejemplo una sentencia de inserción del último viajero en una línea de bus determinada.
mysql> insert into viajeros (nombre,apellidos)
VALUES ('Rosa', 'Álvarez');
Query OK, 1 row affected (0.02 sec)
mysql> select last_insert_id();
+------------------+
| last_insert_id() |
+------------------+
| 4 |
+------------------+
1 row in set (0.00 sec)
mysql> insert into autobuses_viajeros
(id_bus, id_viajero, fecha)
VALUES (1, last_insert_id(), now());
Query OK, 1 row affected (0.02 sec)
mysql> select * from autobuses_viajeros;
+--------+------------+------------+
| id_bus | id_viajero | fecha |
+--------+------------+------------+
| 1 | 4 | 2008-04-30 |
+--------+------------+------------+
1 row in set (0.00 sec)
mysql> select last_insert_id();
+------------------+
| last_insert_id() |
+------------------+
| 4 |
+------------------+
1 row in set (0.00 sec)

En este caso podemos comprobar que se utiliza correctamente el valor de last_insert_id() para la inserción en otra tabla y que esa inserción en una tabla que no contiene valores AUTO_INCREMENT no hace que el valor de last_insert_id() varíe.

Nota: La función now() devuelve la fecha y hora actuales, como el campo es de tipo date, solamente almacena la fecha.

Pero vamos a rizar un poco más el asunto, ¿qué ocurre cuándo se utiliza last_insert_id() en un insert múltiple?, es decir, cuando se insertan varios registros en una sola sentencia:
mysql> insert into viajeros (nombre,apellidos)
VALUES ('Ramón', 'Sánchez'),('Sara','Hernández'),
('Julián','Martínez');
Query OK, 3 rows affected (0.03 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> select last_insert_id();
+------------------+
| last_insert_id() |
+------------------+
| 5 |
+------------------+
1 row in set (0.00 sec)

Mysql retornará el valor generado por el primer registro insertado, pero no por el resto. Si hubieramos insertado los 3 viajeros en 3 inserts diferentes, hubieramos obtenido 5, 6 y 7 como valores para last_insert_id().

Espero haber aclarado un poco más sobre el funcionamiento de last_insert_id() con este caso práctico.