2016-05-23 7 views
-1

Beginnend mit Tabelle;Berechnung der durchschnittlichen Tagesbilanz in SQL

[AccountLedger] 

AccountCode PostingDate   Amount  
128   2014-01-01 08:36:09 200.00 
128   2014-01-01 14:18:10 200.00 
128   2014-01-01 14:26:56  0.00 
128   2014-01-01 18:17:31 400.00 
128   2014-01-01 20:18:53 100.00 
128   2014-01-02 00:10:35  0.00 
128   2014-01-02 01:44:26 300.00 
128   2014-01-02 15:49:31 -300.00 
128   2014-01-03 00:33:23 400.00 
128   2014-01-03 11:55:13 -200.00 
128   2014-01-03 11:56:34 -100.00 
128   2014-01-03 14:58:42 -400.00  
128   2014-01-03 17:31:11  0.00 

**REQUIRED RESULT** 

AccountCode PostingDate   daily_balance 
128   2014-01-01   900.00 
128   2014-01-02   900.00 
128   2014-01-03   600.00 

Abfrage wird

beigefügten
select 
     Acc 
    , Dte 
    , sum(daily_amt) over (PARTITION BY Acc ORDER BY Dte DESC) as daily_balance 
from (select 
      [AccountLedger].[AccountCode] as Acc 
      , convert(date, [AccountLedger].[PostingDate]) as Dte 
      , sum([AccountLedger].[Amount]) as daily_amt 
     from [AccountLedger] 
     WHERE [AccountLedger].[PostingDate] < '2014-04-01' 
     and [AccountLedger].[AccountCode]=128 

     group by [AccountLedger].AccountCode 
     , [AccountLedger].[PostingDate] 

    ) t 
     order by Acc, dte* 

* Aber Fehler erscheint;

Msg 102, Level 15, State 1, Line 4 
Incorrect syntax near 'order'. 
Msg 102, Level 15, State 1, Line 16 
Incorrect syntax near 't'.* 

Wie kann ich das gewünschte Ergebnis erhalten?

+0

Was ist, um von acc, dte *? Was ist Tee *? in diesem Fall glaube ich, die Fehlermeldung spricht Bände ... und es ist ziemlich genau. – JonH

+0

Dieser Beitrag zeigt keinen Forschungsaufwand. – dfundako

+0

Dte ist das Buchungsdatum das * Zeichen bei der Formatierung im Texteditor hier arglos angehängt. Das Problem kommt aus over-Klausel; Es funktioniert gut bis "PARTITION BY Acc" und Fehler entsteht aus "ORDER BY DTE DESC" – 3439027

Antwort

1

Mit einem einfachen Datumstabelle

Declare @DateR1 Date,@DateR2 Date 
Set @DateR1 = '2014-01-01' 
Set @DateR2 = '2014-01-31' 


Select AccountCode 
     ,PostingDate=Date2 
     ,DailyBalance=sum(amount) 
From #Temp A 
Join (Select [email protected],Date2=cast(RetVal as Date) from [dbo].[udf-Create-Range-Date](@DateR1,@DateR2,'DD',1)) B on cast(PostingDate as Date) between Date1 and Date2 
Group By AccountCode,Date2 
Order By 1 

Returns

AccountCode PostingDate DailyBalance 
128   2014-01-01 900 
128   2014-01-02 900 
128   2014-01-03 600 
128   2014-01-04 600 
128   2014-01-05 600 
128   2014-01-06 600 
... 
128   2014-01-31 600 

The

UDF
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 

CREATE FUNCTION [dbo].[udf-Create-Range-Date] (@DateFrom datetime,@DateTo datetime,@DatePart varchar(10),@Incr int) 

Returns 
@ReturnVal Table (RetVal datetime) 

As 
Begin 
    With DateTable As (
     Select DateFrom = @DateFrom 
     Union All 
     Select Case @DatePart 
       When 'YY' then DateAdd(YY, @Incr, df.dateFrom) 
       When 'QQ' then DateAdd(QQ, @Incr, df.dateFrom) 
       When 'MM' then DateAdd(MM, @Incr, df.dateFrom) 
       When 'WK' then DateAdd(WK, @Incr, df.dateFrom) 
       When 'DD' then DateAdd(DD, @Incr, df.dateFrom) 
       When 'HH' then DateAdd(HH, @Incr, df.dateFrom) 
       When 'MI' then DateAdd(MI, @Incr, df.dateFrom) 
       When 'SS' then DateAdd(SS, @Incr, df.dateFrom) 
       End 
     From DateTable DF 
     Where DF.DateFrom < @DateTo 
    ) 

    Insert into @ReturnVal(RetVal) Select DateFrom From DateTable option (maxrecursion 32767) 

    Return 
End 

-- Syntax Select * from [dbo].[udf-Create-Range-Date]('2016-10-01','2020-10-01','YY',1) 
-- Syntax Select * from [dbo].[udf-Create-Range-Date]('2016-10-01','2020-10-01','DD',1) 
-- Syntax Select * from [dbo].[udf-Create-Range-Date]('2016-10-01','2016-10-31','MI',15) 
-- Syntax Select * from [dbo].[udf-Create-Range-Date]('2016-10-01','2016-10-02','SS',1) 
+0

Sie haben genau das erreicht, was ich wollte, Eigentlich bin ich sehr neu in der Programmierung, also können Sie bitte erarbeiten Wie kann ich dies auf meine Tabelle anwenden (anstelle von udf) wie in Frage gegeben, Danke im voraus! – 3439027

+1

Um klar zu sein. Sie möchten oder können die UDF nicht verwenden? Die UDF generiert nur einen Datumsbereich während der Übertragung. Eine andere Option wäre die Verwendung einer einfachen Datumstabelle. So oder so, lass es mich wissen und ich kann helfen –

+1

Ich fühle mich verpflichtet zu sagen, dies sind Spot Balances, nicht tägliche Mittelwerte. Sie können gewichtete durchschnittliche Saldos aus dem Spot-Saldo erstellen, ohne die Lücken "auszufüllen". –

0

Ihre Anfrage Werke (oder ein UDF in meinem Fall einen Datumsbereich erzeugen) fein. aber es tut nicht, was Sie vorhaben, da Sie nach datetime-Feld gruppieren und 2014-01-01 00:00:00 unterscheidet sich von 2014-01-01 00:00:01.

das ist ziemlich einfache Art und Weise Menge zu aggregieren basierend auf Datum

SELECT [AccountCode] ,cast([PostingDate] as date) as date ,sum([Amount]) as 'daily balance' FROM [AccountLedger] WHERE [PostingDate] < '2014-04-01' GROUP BY [AccountCode], cast([PostingDate] as date)

Lassen Sie mich wissen, ob das funktioniert.

+0

Es funktioniert auch in meiner Abfrage, das Problem kommt aus der Klausel over; Es funktioniert gut bis "PARTITION BY Acc" und der Fehler ergibt sich aus "ORDER BY Dte DESC" – 3439027

+0

Welchen Zweck erfüllt "PARTITION BY Acc"? Gibt meine Anfrage nicht die Ergebnisse, die Sie benötigen? –

0
select 
    AccountCode, 
    convert(date, PostingDate) AS PostingDate, 
    avg(Amount) as Average 
from 
    AccountLedger 
where 
    PostingDate < '2014-04-01' 
group by 
    AccountCode, 
    convert(date, PostingDate) 

http://sqlfiddle.com/#!6/965ec/19

Verwandte Themen