Noe Nieto

Mi sitio personal | Personal site

Cómo sacar la diferencia entre dos filas con PostgreSQL

Aprende a calcular la diferencia entre valores de filas consecutivas en PostgreSQL usando self-joins, ideal para tablas con datos de medición.

Elefantote

Tengo una tabla muy simple donde se guardan mediciones. Cada fila corresponde a una medición y cada fila tiene una columna con el ID.

CREATE TABLE history (
  id SERIAL,
  conteo INT
);

Ahora insertaré algunos datos.

INSERT INTO history(conteo)
VALUES (43), (63), (22), (41), (85);

Necesito calcular qué tanto ha cambiado el valor de conteo de una columna con respecto a la columna anterior. ¿Cómo se hace eso? La respuesta es más sencilla de lo que me imaginé. Este es uno de esos casos donde se puede hacer un JOIN de la tabla consigo misma. Esto en inglés se le llama self-join.

SELECT Y.id, Y.conteo - X.conteo AS "Diferencia"
FROM history X
JOIN history Y ON X.id = (Y.id - 1)
ORDER BY Y.id DESC;

La solución, en este caso específico, consiste en aprovechar que la columna ID es un número entero que crece conforme se van insertando columnas. Simplemente se busca que el ID de la columna anterior sea equivalente al de la columna actual menos uno.

El resultado es este:

IDDiferencia
544
419
3-41
220

Obviamente en condiciones reales no todas las tablas tendrán un ID seriado de 1 en 1. Pero si la tabla incluye la fecha y hora de la creación de la columna se puede usar esta columna.

Acá dejo un SQLFiddle para que puedas jugar con los datos.

Nota: En PostgreSQL moderno (8.4+) la forma idiomática de hacer esto es con window functions, específicamente LAG():

SELECT id, conteo - LAG(conteo) OVER (ORDER BY id) AS "Diferencia"
FROM history
ORDER BY id DESC;

FIN