2012-04-05 31 views
12

¿Cómo puedo usar la cláusula WHERE para filtrar en la cláusula OVER?SQL: use la cláusula WHERE en OVER()?

es decir, de los datos siguientes

LoanID | Principal | Tenor | AmortizingPrincipal 
---------------------------------------- 
1   20000  1  5000 
1   20000  2  5000 
1   20000  3  5000 
1   20000  4  5000  

necesito cuarta columna virtual con el director Equilibrio en cada Tenor como la siguiente:

LoanID | Principal | Tenor | AmortizingPrincipal | BalancePrinicpal 
----------------------------------------------------------- 
1  20000  1  5000     20000 
1  20000  2  5000     15000 
1  20000  3  5000     10000 
1  20000  4  5000     5000 

algo como esto:

SELECT 
    BalancePrincipal = Principal - SUM(AmortizingPrincipal) OVER(PARTITION BY LoanID WHERE Tenor < this row's tenor) 

ACTUALIZACIÓN:

La siguiente consulta me da el resultado deseado:

 
SELECT 
    L1.*  
    ,BalancePrincipal = AL1.Principal - ISNULL(Cumulative.AmortizingSum,0) 
FROM 
    Loan L1 
CROSS APPLY 
    (
     SELECT 
      AmortizingSum = SUM(AmortizingPrincipal) 
     FROM 
      Loan L2 
     WHERE 
      L1.LoanID = L2.LoanID 
      AND 
      L1.Tenor > L2.Tenor 
    ) Cumulative 

¿Puede ser mejor?

+2

¿Qué DB está utilizando? ¿Estás tratando de obtener una suma acumulativa? –

+0

Estoy usando SQL Server 2008. – Sreerag

+0

Eche un vistazo a [Calcular un total en ejecución en SqlServer] (http://stackoverflow.com/questions/860966/calculate-a-running-total-in-sqlserver). La respuesta aceptada tiene algunos puntos de referencia sobre algunas formas de calcular la suma acumulada. –

Respuesta

6

Si está utilizando SQL Server 2012, se estaría buscando para especificar ROWS/RANGE en su OVER:

más los límites de las filas dentro de la partición especificando los puntos de inicio y fin dentro de la partición. Esto se hace especificando un rango de filas con respecto a la fila actual, ya sea por asociación lógica o por asociación física. La asociación física se logra mediante el uso de la cláusula ROWS.

Otros sistemas de bases de datos pueden tener características similares. Esta característica es nueva en la versión 2012 de SQL Server.

+0

Un enlace que podría ser útil http://sqlandme.com/2011/08/17/sql-server-denali-over-rows-range/ –

+1

Probablemente sea el que creo que necesitaré aquí. ¿Cómo podemos lograr lo mismo en SQL 2008? – Sreerag

0

Para la muestra publicado, que no parece que se necesita un filtro:

SELECT LoanID, Principal, Tenor, AmortizingPrincipal 
     ,SUM(AmortizingPrincipal) OVER(PARTITION BY LoanID ORDER BY Tenor Desc) AS BalancePrincipal 
    FROM loan 
    ORDER BY LoanID, Principal, Tenor 

ACTUALIZACIÓN:

Parece SQL Server 2008 no tiene la cláusula de ventanas? Ni siquiera pensé que podrías crear una función analítica sin una cláusula de ventana. El sql anterior se ejecutó en Oracle y Postgres sin problema. Por defecto, la cláusula window está DESORDEN ANTERIOR Y LA FILA ACTUAL (desde - hasta). Pero puede cambiar el orden y pasar de CURRENT ROW a UNWUNDED FOLLOWING.

Update2:

Por lo tanto desconcertado: ¿qué significado tendría un SUM (acumulativo) tiene una función analítica en si no son capaces de ordenar las filas dentro de la partición? ¿Hay un pedido implícito? Puedo cambiar la ventana (a continuación) y obtener el mismo resultado, pero debo proporcionar el ORDER BY (en Oracle y Postgres). No puedo ver cómo la SUM analítica tendría ningún significado sin ORDER BY.

SELECT LoanID, Principal, Tenor, AmortizingPrincipal 
     ,SUM(AmortizingPrincipal) OVER(PARTITION BY LoanID ORDER BY tenor 
            RANGE BETWEEN CURRENT ROW 
             AND UNBOUNDED FOLLOWING) AS BalancePrincipal 
    FROM loan 
    ORDER BY LoanID, Principal, Tenor 
+0

¿Qué significaría la combinación de 'SUM' y' ORDER BY', dado que la adición es conmutativa? –

+0

@Damien_The_Unbeliever Por defecto, la SUMA está entre SIN ANULAR PRECEDENTES y FILA ACTUAL. Así que ordenar las filas en orden descendente deja un total acumulado desde el tenor más alto al más bajo, que parece ser lo que realmente se busca. – Glenn

+0

Solo puedo conseguir que acepte el 'ORDER BY' en 2012. En 2008 se produce un error (" sintaxis incorrecta cerca de '' '') –

Cuestiones relacionadas