Optimieren einer Abfrage zum Erstellen von Durchschnittswerten

Ich habe vor kurzem eine Abfrage in SQL gebaut, die ich verwenden kann, um unser Zahlungsprotokoll zu betrachten und eine durchschnittliche Anzahl von Zahlungen pro Stunde über einen timeraum zu finden. Ich bin sicher, es gibt Drittanbieter-Berichterstattung Anwendungen, die viel mehr geeignet sind, um die Art der Berechnung Ich versuche zu tun, aber nur zum Spaß, ich bin irgendwie neugierig zu sehen, was andere methods, die Sie alle verwenden könnte (in T-SQL), um die data zu bekommen, die ich suche. Ich weiß, es ist eine dumme Frage, also werde ich nicht beleidigt sein, wenn du mich abstimmst. Aber für jeden anderen da draußen ist das langweilig wie ich, fühlen Sie sich frei, Ihre anderen Lösungen zu posten.

Die Tabelle wird mit einer Spalte [CreateDate] eingerichtet, bei der es sich um den DATETIME-Wert handelt. Ich benutze dies, um festzustellen, welche Stunde sie die Zahlung in gemacht haben.

CREATE TABLE #TempTimes ( [Time] DATETIME, ) DECLARE @numDays INT SET @numDays = 10 DECLARE @time DATETIME SET @time = DATEADD(dd, DATEDIFF(dd, 0, GETDATE() - @numDays), 0) WHILE @time < GETDATE() BEGIN INSERT #TempTimes VALUES (@time) SET @time = DATEADD(hour, 1, @time) END GO /* I have to join in a table with all of the hours for the time span I'm querying against, because otherwise, the AVG function won't calculate in the hours where no payments were made. */ SELECT DATEPART(hour, [Time]) [Hour], AVG(CAST([Count] AS DECIMAL)) [Average] FROM ( SELECT [Time], CASE WHEN [Count] IS NULL THEN 0 ELSE [Count] END [Count] FROM #TempTimes tt LEFT JOIN ( SELECT DATEADD(hour, DATEDIFF(hour, 0, [CreateDate]), 0) [hour], COUNT(*) [Count] FROM [dbo].[PaymentLog] GROUP BY DATEADD(hour, DATEDIFF(hour, 0, [CreateDate]), 0) ) t1 ON t1.[hour] = tt.[time] ) t2 GROUP BY DATEPART(hour, tt.[Time]) GO DROP TABLE #TempTimes GO 

CJ

IIUC Sie filtern aus dem Haupttisch mit einem Join mit der Temp-Tabelle.

Warum nicht den Beitritt fallen lassen und einfach eine Wo-Klausel verwenden? Wenn du alle Stunden zwingen willst, aufzutauchen, mache dich nach dem Rest der Arbeit und mache eine Vereinigung irgendwelcher Art.

Ich denke, das ist eine vernünftig nette Methode. Es vermeidet die Verwendung einer Stunden-Tabelle (oder Temp-Tabelle, wie Sie verwenden). Der Nachteil ist, dass es nur Werte für Stunden zeigt, wo eine Zahlung gemacht wurde. Lassen Sie die Vorderseite in alle 0s setzen. 🙂

 CREATE TABLE dbo.Payments ( payment_id INT IDENTITY NOT NULL, create_date DATETIME NOT NULL, CONSTRAINT PK_Payments PRIMARY KEY CLUSTERED (payment_id) ) GO INSERT INTO dbo.Payments (create_date) SELECT '2009-02-25 12:00:00.000' UNION SELECT '2009-02-25 12:45:00.000' UNION SELECT '2009-02-25 12:30:00.000' UNION SELECT '2009-02-25 13:10:00.000' UNION SELECT '2009-02-25 13:22:00.000' UNION SELECT '2009-02-25 14:09:00.000' UNION SELECT '2009-02-25 14:40:00.000' GO SELECT CAST(CONVERT(VARCHAR(13), T1.create_date, 121) + ':00:00.000' AS DATETIME), COUNT(T3.payment_id) + 1 FROM dbo.Payments T1 LEFT OUTER JOIN dbo.Payments T2 ON T2.create_date >= CAST(CONVERT(VARCHAR(13), T1.create_date, 121) + ':00:00.000' AS DATETIME) AND T2.create_date < T1.create_date LEFT OUTER JOIN dbo.Payments T3 ON T3.create_date >= T1.create_date AND T3.create_date < DATEADD(hh, 1, CAST(CONVERT(VARCHAR(13), T1.create_date, 121) + ':00:00.000' AS DATETIME)) AND T3.payment_id <> T1.payment_id WHERE T2.payment_id IS NULL GROUP BY CAST(CONVERT(VARCHAR(13), T1.create_date, 121) + ':00:00.000' AS DATETIME) GO