Necesito calcular la diferencia de una columna entre dos líneas de una tabla. ¿Hay alguna forma de que pueda hacer esto directamente en SQL? Estoy usando Microsoft SQL Server 2008.
Estoy buscando algo como esto:
SELECT value - (previous.value) FROM table
Imaginando que la variable "anterior" hace referencia a la última fila seleccionada. Por supuesto, con una selección como esa, terminaré con n-1 filas seleccionadas en una tabla con n filas, eso no es probable, en realidad es exactamente lo que necesito.
¿Es eso posible de alguna manera?
sql
sql-server
sql-server-2008
Edwin Jarvis
fuente
fuente
Respuestas:
SQL no tiene una noción incorporada de orden, por lo que debe ordenar por alguna columna para que esto sea significativo. Algo como esto:
Si sabe cómo ordenar las cosas pero no cómo obtener el valor anterior dado el actual (por ejemplo, desea ordenar alfabéticamente), entonces no conozco una forma de hacerlo en SQL estándar, pero la mayoría de las implementaciones de SQL tendrán extensiones para hacerlo.
Aquí hay una forma para el servidor SQL que funciona si puede ordenar filas de manera que cada una sea distinta:
Si necesita romper los lazos, puede agregar tantas columnas como sea necesario al ORDER BY.
fuente
Utilice la función de retraso :
Las secuencias utilizadas para los ID pueden omitir valores, por lo que Id-1 no siempre funciona.
fuente
LAG(ExpressionToSelect, NumberOfRowsToLag, DefaultValue)
. El número predeterminado de filas para retrasar es 1, pero puede especificar eso y el valor predeterminado para seleccionar cuando no es posible retrasar ya que está al comienzo del conjunto.Oracle, PostgreSQL, SQL Server y muchos más motores RDBMS tienen funciones analíticas llamadas
LAG
yLEAD
que hacen esto mismo.En SQL Server antes de 2012, deberá hacer lo siguiente:
, dónde
COL1
está la columna por la que está ordenando.Tener un índice
(COL1, PK)
activado mejorará enormemente esta consulta.fuente
fuente
LEFT JOIN la tabla consigo misma, con la condición de unión resuelta de modo que la fila coincidente en la versión unida de la tabla sea una fila anterior, para su definición particular de "anterior".
Actualización: Al principio estaba pensando que querría mantener todas las filas, con NULL para la condición donde no había una fila anterior. Al volver a leerlo, solo desea que se eliminen las filas, por lo que debe usar una combinación interna en lugar de una combinación izquierda.
Actualizar:
Las versiones más nuevas de Sql Server también tienen las funciones LAG y LEAD Windowing que también se pueden usar para esto.
fuente
fuente
La respuesta seleccionada solo funcionará si no hay espacios en la secuencia. Sin embargo, si está utilizando una identificación generada automáticamente, es probable que haya espacios en la secuencia debido a inserciones que se revertieron.
Este método debería funcionar si tiene lagunas
fuente