sql >> Base de Datos >  >> RDS >> Sqlserver

LAST_VALUE en SQL Server 2012 está devolviendo resultados extraños

SQL Server no sabe ni se preocupa por el orden en que se insertaron las filas en la tabla. Si necesita un pedido específico, use siempre ORDER BY . En tu ejemplo ORDER BY es ambiguo, a menos que incluya PK en el ORDER BY . Además, LAST_VALUE La función puede devolver resultados extraños si no tiene cuidado; consulte a continuación.

Puede obtener el resultado esperado usando MAX o LAST_VALUE (SQLFiddle ). Son equivalentes en este caso:

SELECT
    PK, Id1, Id2
    ,MAX(PK) OVER (PARTITION BY Id1, Id2) AS MaxValue
    ,LAST_VALUE(PK) OVER (PARTITION BY Id1, Id2 ORDER BY PK rows between unbounded preceding and unbounded following) AS LastValue
FROM
    Data
ORDER BY id1, id2, PK

El resultado de esta consulta será el mismo independientemente del orden en que se insertaron originalmente las filas en la tabla. Puedes intentar poner INSERT declaraciones en orden diferente en el violín. No afecta el resultado.

Además, LAST_VALUE no se comporta como esperarías intuitivamente con la ventana predeterminada (cuando solo tienes ORDER BY en el OVER cláusula). La ventana predeterminada es ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW , mientras esperaba que fuera ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING . Aquí hay una respuesta SO con un buena explicación . El enlace a esta respuesta SO está en la página de MSDN para LAST_VALUE . Entonces, una vez que la ventana de la fila se especifica explícitamente en la consulta, devuelve lo que se necesita.

Si desea saber el orden en que se insertaron las filas en la tabla, creo que la forma más sencilla es usar IDENTITY . Entonces, la definición de su tabla cambiaría a esto:

CREATE TABLE Data 
(PK INT IDENTITY(1,1) PRIMARY KEY,
Id1 INT,
Id2 INT)

Cuando INSERT en esta tabla no necesita especificar el valor para PK , el servidor lo generaría automáticamente. Garantiza que los valores generados sean únicos y crecientes (con parámetro de incremento positivo), incluso si tiene muchos clientes insertando en la tabla al mismo tiempo simultáneamente. Puede haber espacios entre los valores generados, pero el orden relativo de los valores generados le indicará qué fila se insertó después de qué fila.