2012-04-05 13 views
12

Jak używać klauzuli WHERE do filtrowania w klauzuli ?SQL: użyj klauzuli WHERE w OVER()?

czyli z następującymi danymi

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

muszę czwarty wirtualny kolumny z głównymi równowaga w każdej Tenor tak:

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 

coś takiego:

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

AKTUALIZACJA:

Poniższe zapytanie daje mi pożądany rezultat:

 
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 

Może to być lepszego?

+2

Z jakiego DB korzystasz? Czy próbujesz uzyskać łączną sumę? –

+0

Im przy użyciu programu SQL Server 2008. – Sreerag

+0

Zobacz [Oblicz bieżącą sumę w SqlServer] (http://stackoverflow.com/questions/860966/calculate-a-running-total-in-sqlserver). Zaakceptowana odpowiedź ma kilka testów porównawczych na kilka sposobów obliczania sumy bieżących. –

Odpowiedz

6

Jeśli używasz SQL Server 2012, można być patrząc określić ROWS/RANGE w OVER:

podobne limity wierszy w partycji poprzez określenie punktu początkowego i końcowego w partycji. Odbywa się to poprzez określenie zakresu wierszy w odniesieniu do bieżącego wiersza albo przez powiązanie logiczne lub fizyczne powiązanie. Fizyczne powiązanie uzyskuje się za pomocą klauzuli ROWS.

Inne systemy baz danych mogą mieć podobne funkcje. Ta funkcja jest nowa w wersji 2012 programu SQL Server.

+0

Link, który może być pomocny http://sqlandme.com/2011/08/17/sql-server-denali-over-rows-range/ –

+1

To chyba ten, który moim zdaniem będzie tutaj potrzebny. Jak możemy to osiągnąć w SQL 2008? – Sreerag

0

Dla próbki pisał, że nie wygląda jak potrzebny jest filtr:

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

UPDATE:

Wydaje SQL Server 2008 nie posiada klauzuli okienkowy? Nie sądziłem nawet, że można utworzyć funkcję analityczną bez klauzuli okienkowania. Powyższy sql został uruchomiony na Oracle i Postgres bez problemu. Domyślnie klauzulą ​​okna jest UNBOUNDED PRECEDING I BIEŻĄCE WIERSZE (od - do). Ale możesz zmienić kolejność i przejść z BIEŻĄCEGO RZĘDU do NIEDOPUSZCZALNEJ PONIŻSZEJ.

Update2:

Więc zdziwiony: jakie znaczenie a (narastająco) suma miałaby w funkcji analitycznej, jeśli nie jesteś w stanie zamówić wiersze wewnątrz partycji? Czy istnieje domniemany porządek? Mogę zmienić okno (poniżej) i uzyskać ten sam wynik, ale muszę dostarczyć ORDER BY (w Oracle i Postgres). Nie widzę, jak analityczne SUMA miałoby jakiekolwiek znaczenie bez 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

Co by oznaczało połączenie słowa "SUM" i "ORDER BY", biorąc pod uwagę, że dodatek jest przemienny? –

+0

@Damien_The_Unbeliever Domyślnie SUM jest pomiędzy UNBOUNDED PRECEDING i BIEŻĄCY RZĄD. Zatem porządkowanie rzędów w porządku malejącym pozostawia całkowitą liczbę od najwyższego do najtańszego, co wydaje się być tym, czego naprawdę szuka. – Glenn

+0

Mogę go pobrać tylko po to, aby zaakceptować "ZAMÓWIENIE PRZEZ" w 2012 r. W 2008 r. Wystąpiły błędy ("niepoprawna składnia w pobliżu" zamówienia ") –

Powiązane problemy