2016-04-22 17 views
0

Ich muss die folgende T-SQL-Anweisung ändern, um einen rollierenden 7-Tage-Durchschnitt des Umsatzes zu enthalten.7-Tage-Durchschnitt in SQL Server 2014

Was muss ich in den folgenden Code aufnehmen, um das zu erreichen?

SELECT 
    CAST(create_dtg AS DATE) DATE, 
    SUM([agent_rev] + [anchor_rev] + [corp_rev] + [offsite_rev]) AS RevenueTotals, 
    SUM([media_est_cost] + [other_cost]) AS COSTTOTALS 
FROM 
    [dbo].[dw_rpt_traffic] 
WHERE 
    [create_dtg] >= (Getdate() - 90) 
--GROUP BY CREATE_DTG 
--ORDER BY CREATE_DTG ASC 

Ich habe auch versucht, Partion durch, aber dies gibt den gleichen Wert wie die Revenuetotals.

Select a.dte, a.revenuetotals, a.COSTTOTALS, AVG(A.RevenueTotals) OVER  (PARTITION BY a.dte ORDER BY a.dte ROWS 7 PRECEDING) as Day7Avg 
from 
(
    select CAST(CREATE_DTG AS DATE) as dte, 
      SUM([AGENT_REV]+[ANCHOR_REV]+[CORP_REV]+[OFFSITE_REV]) as RevenueTotals, 
      SUM([MEDIA_EST_COST]+[OTHER_COST]) as COSTTOTALS 
    FROM [dbo].[dw_rpt_traffic] 
    where [CREATE_DTG] >= (GetDate() - 90) 
    GROUP BY CREATE_DTG 
    ) as A 
Group by a.dte, a.revenuetotals, a.COSTTOTALS 
order by a.dte 

Danke, Karen

+0

Welche Version von SQL Server suchen Sie? –

+0

Er verwendet SQL-Server (T-SQL). Ich habe die Frage präzisiert und den Code so formuliert, dass er lesbar ist. Sollte jetzt helfen! –

Antwort

1

Für Aggregate rollen typischerweise ich eine OVER Klausel mit ROWS [...] PRECEDING [...] verwenden.

WITH cte 
      AS (SELECT x.Date 
         ,x.Revenue 
         ,AVG(x.Revenue) OVER (ORDER BY x.Date 
               ROWS BETWEEN 6 PRECEDING AND CURRENT ROW 
         ) AS [MA7] 
       FROM  (SELECT CAST(t.Date AS DATE) AS [Date] 
            ,SUM(t.Revenue) AS [Revenue] 
          FROM  #tmp t 
          WHERE  CAST(t.Date AS DATE) > CAST(GETDATE() - 96 AS DATE) 
          GROUP BY CAST(t.Date AS DATE) 
         ) x 
      ) 
    SELECT c.Date 
      ,c.Revenue 
      ,c.MA7 
    FROM cte c 
    WHERE c.Date > CAST(GETDATE() - 90 AS DATE) 
    ORDER BY c.Date; 

Die obige Tabelle wurde mit der folgenden generiert:

IF (OBJECT_ID('tempdb..#tmp') IS NOT NULL) 
    DROP TABLE #tmp; 
CREATE TABLE #tmp 
    (
    [Date] DATETIME 
    ,[Revenue] DECIMAL(18, 2) 
    ); 
-- 
DECLARE @first INT = 0 
    ,@last INT = 200; 
WHILE @first < @last 
    BEGIN 
     INSERT INTO #tmp 
       (Date, Revenue) 
     VALUES (GETDATE() - @first * 0.5, RAND() * 100000); 

     SET @first = @first + 1; 
    END; 
+0

gibt es eine Möglichkeit, dies zu erreichen, ohne temporäre Tabelle zu erstellen. Ich habe derzeit keine Berechtigungen zum Erstellen und Löschen von Tabellen? –

+0

Die Tempentabelle ist für die Lösung nicht erforderlich; Ich benutzte es nur, um den Code auf etwas Konkretes zu demonstrieren. Sie sollten in der Lage sein, Ihre reale Tabelle basierend auf dem, was oben dargestellt ist, anzupassen. Zum Beispiel würde "# tmp.Revenue" durch "[agent_rev] + [anchor_rev] + [corp_rev] + [offsite_rev]" usw. ersetzt. – nrussell

+0

Ich muss die CostTotals einschließen und auch den Bruttogewinn (Revenue- costttotals) Wie sollte dieser Code geändert werden? –

1

Wahrscheinlich nutzt der einfachste Weg outer apply:

with rt as (
     select CAST(CREATE_DTG AS DATE) as dte, 
       SUM([AGENT_REV]+[ANCHOR_REV]+[CORP_REV]+[OFFSITE_REV]) as RevenueTotals, 
       SUM([MEDIA_EST_COST]+[OTHER_COST]) as COSTTOTALS 
     from [dbo].[dw_rpt_traffic] 
     where [CREATE_DTG] >= (GetDate() - 90) 
    ) 
select rt.*, rolling.avgrt 
from rt outer apply 
    (select avg(rt2.RevenueTotals) as avgrt 
     from rt rt2 
     where rt2.dte >= dateadd(day, -6, rt.dte) and 
      rt2.dte <= rt.dte 
    ) rolling 
order by dte; 
+0

Ich habe die Gruppe per per Anfrage der Fehlermeldung hinzugefügt und es scheint zu hängen –

+0

Siehe Änderung in orignial Post versucht mit Partitionen. –