Unser in der Datenbank ansässiger Experte sagt uns, dass Nummerntabellen von unschätzbarem Wert sind . Ich verstehe nicht ganz warum. Hier ist eine Zahlentabelle:
USE Model
GO
CREATE TABLE Numbers
(
Number INT NOT NULL,
CONSTRAINT PK_Numbers
PRIMARY KEY CLUSTERED (Number)
WITH FILLFACTOR = 100
)
INSERT INTO Numbers
SELECT
(a.Number * 256) + b.Number AS Number
FROM
(
SELECT number
FROM master..spt_values
WHERE
type = 'P'
AND number <= 255
) a (Number),
(
SELECT number
FROM master..spt_values
WHERE
type = 'P'
AND number <= 255
) b (Number)
GO
Laut dem Blog-Post lautet die Begründung
Zahlentabellen sind wirklich von unschätzbarem Wert. Ich benutze sie die ganze Zeit, um Zeichenfolgen zu manipulieren, Fensterfunktionen zu simulieren, Testtabellen mit vielen Daten zu füllen, Cursorlogik zu eliminieren und viele andere Aufgaben, die ohne sie unglaublich schwierig wären.
Aber ich verstehe nicht genau, was diese Verwendungen sind - können Sie überzeugende, spezifische Beispiele dafür liefern, wo eine "Zahlentabelle" Ihnen eine Menge Arbeit in SQL Server erspart - und warum wir sie haben sollten?
sql-server
Jeff Atwood
quelle
quelle
Antworten:
Ich habe viele Anwendungen gesehen, wenn Sie "fehlende Daten" projizieren müssen. Z.B. Sie haben eine Zeitreihe (z. B. ein Zugriffsprotokoll) und möchten die Anzahl der Zugriffe pro Tag in den letzten 30 Tagen anzeigen (Think Analytics Dashboard). Wenn Sie eine
select count(...) from ... group by day
ausführen, erhalten Sie die Zählung für jeden Tag, aber das Ergebnis enthält nur eine Zeile für jeden Tag, an dem Sie tatsächlich mindestens einen Zugriff hatten. Auf der anderen Seite, wenn Sie zuerst eine Tabelle mit Tagen aus Ihrer Zahlentabelle (select dateadd(day, -number, today) as day from numbers
) projizieren und dann verlassen, um sich den Zählungen anzuschließen (oder äusserlich anzuwenden, was immer Sie möchten), erhalten Sie ein Ergebnis, das für die Tage, die Sie zählen, 0 hat hatte keinen Zugang. Dies ist nur ein Beispiel. Natürlich kann man argumentieren, dass die Präsentationsebene Ihres Dashboards die fehlenden Tage behandeln und stattdessen nur eine 0 anzeigen könnte, aber einige Tools (z. B. SSRS) werden dies einfach nicht können.Andere Beispiele, die ich gesehen habe, verwendeten ähnliche Zeitreihentricks (Datum / Zeit +/- Zahl), um alle Arten von Fensterberechnungen durchzuführen. Wenn Sie in einer imperativen Sprache eine for-Schleife mit einer bekannten Anzahl von Iterationen verwenden, kann die deklarative und festgelegte Natur von SQL einen Trick verwenden, der auf einer Zahlentabelle basiert.
Übrigens, ich habe das Bedürfnis, darauf hinzuweisen, dass die Verwendung einer Zahlentabelle zwar wie eine zwingende prozedurale Ausführung erscheint, aber nicht in den Irrtum der Annahme fällt, dass sie zwingend ist. Lassen Sie mich ein Beispiel geben:
Dieses Programm gibt 999999 aus, das ist so ziemlich garantiert.
Versuchen wir dasselbe in SQL Server unter Verwendung einer Nummerntabelle. Erstellen Sie zunächst eine Tabelle mit 1.000.000 Zahlen:
Nun machen wir die 'for-Schleife':
Das Ergebnis ist:
Wenn Sie jetzt einen WTF Moment haben (schließlich
number
ist die Cluster - Primärschlüssel!), Wird der Trick genannt scannen Zuteilung Ordnung und ich habe nicht einfügen@j*1000+@i
zufällig ... Sie hatte , konnte auch eine Vermutung wagen und sagen , das Ergebnis ist da Parallelität und das kann manchmal die richtige Antwort sein.Es gibt viele Trolle unter dieser Brücke, und ich habe einige in On SQL Server erwähnte boolesche Operator-Kurzschlüsse erwähnt, und T-SQL-Funktionen implizieren keine bestimmte Ausführungsreihenfolge
quelle
Ich habe eine Zahlentabelle gefunden, die in verschiedenen Situationen sehr nützlich ist.
Bei Warum sollte ich eine Hilfsnummern Tabelle? , geschrieben im Jahr 2004, zeige ich ein paar Beispiele:
Bei Bad Habits to Kick: Verwenden von Schleifen zum Auffüllen großer Tabellen zeige ich, wie mit einer Zahlentabelle das Einfügen vieler Zeilen in kurzer Zeit erledigt werden kann (im Gegensatz zum kniffligen Ansatz einer while-Schleife).
Unter Verarbeiten einer Liste von Ganzzahlen: Meine Vorgehensweise und Weitere Informationen zum Teilen von Listen: Benutzerdefinierte Trennzeichen, Verhindern von Duplikaten und Beibehalten der Reihenfolge wird gezeigt, wie mithilfe einer Zahlentabelle eine Zeichenfolge (z. B. eine Reihe von durch Kommas getrennten Werten) geteilt und die Leistung verbessert wird Vergleiche zwischen dieser und anderen Methoden. Weitere Informationen zum Teilen und zum Umgang mit anderen Zeichenfolgen:
Und in der SQL Server-Nummerntabelle (Teil 1) gebe ich Hintergrundinformationen zum Konzept und habe zukünftige Veröffentlichungen vor, in denen bestimmte Anwendungen detailliert beschrieben werden.
Es gibt viele andere Verwendungszwecke, das sind nur einige, die mir so aufgefallen sind, dass ich darüber schreiben kann.
Und wie bei @gbn habe ich ein paar Antworten zum Stapelüberlauf und auf dieser Site , die auch eine Nummerntabelle verwenden.
Schließlich habe ich eine Reihe von Blogposts zum Thema Generieren von Sets ohne Schleifen, die teilweise den Leistungsvorteil der Verwendung einer Zahlentabelle im Vergleich zu den meisten anderen Methoden zeigen (Remus 'skurriler Ausreißer beiseite):
quelle
Hier ist ein großartiges Beispiel, das ich kürzlich von Adam Machanic verwendet habe:
Ich habe etwas Ähnliches mit a verwendet
CTE
, um eine bestimmte Instanz der Teilzeichenfolge zu finden (z. B. "Finde die dritte Pipe in dieser Zeichenfolge"), um mit korrelierten, abgegrenzten Daten zu arbeiten:Wenn Sie keine Nummerntabelle haben, können Sie auch eine Art Schleife verwenden. Grundsätzlich können Sie mit einer Zahlentabelle eine satzbasierte Iteration ohne Cursor oder Schleifen durchführen.
quelle
Ich würde eine Zahlentabelle verwenden, wenn ich ein SQL-Äquivalent von Enumerable.Range benötige. Ich habe es beispielsweise gerade in einer Antwort auf dieser Website verwendet: Berechnung der Anzahl der Permutationen
quelle