Wie kann ich erstellen Sie eine Reihe von Monaten beitreten spärliche Daten zu?
Ich denke, das ist eine ziemlich häufige Frage, aber ich weiß nicht, was der Prozess genannt, also werde ich beschreiben es mit einem Beispiel. Das Konzept ist, dass ich beitreten soll eine sparse-dataset, um eine komplette Serie, wie die Tage der Woche, Monate des Jahres, oder jeden bestellten set (Z. B. für das ranking). Leere Positionen in den spärlichen Daten, die zeigen, wie NULL-neben der kompletten Serie.
Sagen wir, ich führen Sie die folgende Abfrage in SQL-Servers, um herauszufinden, die monatlichen Verkäufe.
SELECT
YEAR([timestamp]),
MONTH([timestamp]),
COUNT(*)
FROM table1
WHERE YEAR([timestamp]) = YEAR(GETDATE())
GROUP BY
YEAR([timestamp]),
MONTH([timestamp])
ORDER BY
YEAR([timestamp]) DESC,
MONTH([timestamp]) DESC;
Wenn jedoch Umsatz nur traten im Mai und August dieses Jahres, zum Beispiel, dann die return-Ergebnis würde dann so Aussehen:
2010 August 1234
2010 May 5678
Möchte ich mein Ergebnis zurückgeben set wie folgt Aussehen:
2010 January
2010 February
2010 March
2010 April
2010 May 1234
2010 June
2010 July
2010 August 5678
2010 September
2010 October
2010 November
2010 December
Ich weiß nur einen Weg, dies zu tun, ist dies:
SELECT
YEAR(GETDATE()),
month_index.month_name,
sales_data.sales
FROM (
SELECT 'January' as month_name, 1 as month_number
UNION
SELECT 'February', 2
UNION
SELECT 'March', 3
UNION
SELECT 'April', 4
UNION
SELECT 'May', 5
UNION
SELECT 'June', 6
UNION
SELECT 'July', 7
UNION
SELECT 'August', 8
UNION
SELECT 'September', 9
UNION
SELECT 'October', 10
UNION
SELECT 'November', 11
UNION
SELECT 'December', 12
) as month_index
LEFT JOIN (
SELECT
YEAR([timestamp]) AS year_name,
MONTH([timestamp]) AS month_name,
COUNT(*) AS sales
FROM table1
WHERE YEAR([timestamp]) = GETDATE()
GROUP BY
YEAR([timestamp]),
MONTH([timestamp])
) AS sales_data
ON month_index.month_name = sales_data.month_name
ORDER BY
month_index.month_number DESC;
Gibt es einen besseren Weg, um erstellen Sie das vollständige Datum und die alphanumerische Serie beizutreten Daten auf? Und was ist das genannt?
Dank!
- Verwandte: stackoverflow.com/questions/1478951/...
Du musst angemeldet sein, um einen Kommentar abzugeben.
probieren Sie etwas wie dieses:
Ausgabe:
OPTION (MAXRECURSION 0)
oderOPTION (MAXRECURSION 1000)
werden kann, die für große Datenbereiche.Anfragen wie diese sind einer der Hauptgründe, dass viele erfahrene Datenbankadministratoren (DBAs) oder Datenbank-Programmierer halten Kalender Tisch in Ihren Datenbanken.
Ich mag diesen Ansatz zu bauen, der Monate Tabelle:
Basierend auf meinen tests, es ist schneller als eine CTE. Ich bin mit SQL Server 2008 Express.
Hier sind die Testergebnisse, die mithilfe von SET STATISTICS IO ON und SET STATISTICS TIME ON
CTE:
Unterabfrage:
Obwohl Ihre ursprüngliche Frage ist zu Fragen, was dies heißt. Ich weiß nicht, einen Namen für ihn; vielleicht so etwas wie "left outer join gegen eine Serie?"
Einen weiteren Teil hinzufügen: wenn Sie sich gegen die Monate Tabelle, oder sogar, wenn Ihre original query, es ist in der Regel empfohlen, um zu vermeiden, mit einer Funktion wie JAHR([timestamp]) auf der linken Seite der WHERE-Klausel.
Also dieser code:
...bewirken, dass ein index scan (vorausgesetzt, timestamp indiziert ist), weil das JAHR([timestamp]) muss die Auswertung für jede Zeile. Auf einem 1m+ Zeile der Tabelle wird dies bedeuten, eine schlechte Leistung.
So werden Sie in der Regel eine Empfehlung wie dieses, statt:
Diese verwenden eine index-Suche (wieder, vorausgesetzt, timestamp ist eine indizierte Spalte) und das Ergebnis in weniger logische Lesevorgänge und damit eine schnellere Reaktion. Dies bestätigt sich durch die überprüfung der execution plan.
Bin ich mit den KM, die für SQL Server 2005+ Sie könnte eine rekursive CTE:
Nachdem alle, die Letzte Zeit KM & plauderten über dies - wir fanden eine rekursive CTE etwas effizienter als die Verwendung einer zahlen-Tabelle.
wie wäre es mit einer neuen Tabelle namens Monate: dann füllen Sie die Daten, die Sie beitreten können, um?