Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Einführung in allgemeine Tabellenausdrücke in SQL Server

Common Table Expressions, oder kurz CTE, ist einfach eine Technik, um einen temporären Satz von Datensätzen zu erstellen, auf die in einer INSERT-, SELECT-, UPDATE- oder DELETE-Anweisung verwiesen werden kann.

Allgemeine Tabellenausdrücke wurden von Microsoft in SQL Server 2005 eingeführt. Sie werden nicht als Objekte im Datenbankspeicher gespeichert, da ihre Lebensdauer der Ausführungszeit der Abfrage entspricht. Sobald eine Abfrage abgeschlossen ist, werden sie aus dem Datenbankspeicher entfernt. CTE kann in einer Abfrage beliebig oft referenziert werden und sie können auch selbstreferenzierend sein.

Lassen Sie uns eine Datenbank mit einer Schülertabelle erstellen und einige Dummy-Schülerdatensätze darin einfügen. Wir werden diese Datenbank verwenden, um CTE-Abfragen zu schreiben. Stellen Sie wie immer sicher, dass Sie gut gesichert sind, bevor Sie mit einem neuen Code experimentieren. Lesen Sie diesen Artikel zur SQL-Sicherung, wenn Sie sich nicht sicher sind.

Führen Sie die folgenden Abfragen auf Ihrem Server aus.

CREATE DATABASE schooldb

CREATE TABLE student
(
    id INT PRIMARY KEY,
    name VARCHAR(50) NOT NULL,
    gender VARCHAR(50) NOT NULL,
    DOB datetime NOT NULL,
    total_score INT NOT NULL,
    
 )

INSERT INTO student

VALUES (1, 'Jolly', 'Female', '12-JUN-1989', 500), 
(2, 'Jon', 'Male', '02-FEB-1974', 545), 
(3, 'Sara', 'Female', '07-MAR-1988', 600), 
(4, 'Laura', 'Female', '22-DEC-1981', 400), 
(5, 'Alan', 'Male', '29-JUL-1993', 500), 
(6, 'Kate', 'Female', '03-JAN-1985', 500), 
(7, 'Joseph', 'Male', '09-APR-1982', 643), 
(8, 'Mice', 'Male', '16-AUG-1974', 543), 
(9, 'Wise', 'Male', '11-NOV-1987', 499), 
(10, 'Elis', 'Female', '28-OCT-1990', 400);

Lassen Sie uns nun einen sehr einfachen allgemeinen Tabellenausdruck erstellen. Dieser CTE enthält Aufzeichnungen aller Studenten, die vor dem 1. Januar 1985 geboren wurden. Sehen Sie sich das folgende Skript an.

USE schooldb;

WITH OldStudents AS
(
SELECT * FROM student
WHERE DOB < '1985-01-01'
)

Um einen CTE zu erstellen, müssen Sie mit dem Schlüsselwort „WITH“ beginnen, gefolgt vom Namen des CTE und dem Schlüsselwort „AS“.

Als nächstes müssen Sie innerhalb der Klammern die Abfrage schreiben, die die Datensätze zurückgibt, die der CTE vorübergehend speichert. Im obigen Skript haben wir einen CTE mit dem Namen „OldStudents“ erstellt.

Beachten Sie jedoch, dass Sie eine Fehlermeldung erhalten, wenn Sie versuchen, die obige Abfrage auszuführen. Denn sobald Sie einen CTE erstellt haben, müssen Sie ihn sofort verwenden.

Lassen Sie uns alle Datensätze aus unserem neu erstellten CTE „OldStudents“ auswählen. Probieren Sie das folgende Skript auf Ihrem Server aus.

USE schooldb;

WITH OldStudents AS
(
	SELECT * FROM student
	WHERE DOB < '1985-01-01'

)

SELECT * FROM OldStudents

Das obige Skript ruft die folgenden Datensätze ab:

Berechnung des Aggregats über CTE

Wie Tabellen können Sie Aggregatfunktionen auf CTE ausführen. Sehen wir uns ein weiteres Beispiel für CTE an.

USE schooldb;

WITH SumofScores AS
(
	SELECT 
		gender, SUM(total_score) as SumScore
	FROM student
	GROUP BY gender
)

SELECT AVG (SumScore)
FROM SumofScores

Im obigen Beispiel haben wir einen CTE namens SumofScores erstellt. Dieser CTE enthält die Summe der Werte, die in der Spalte total_score der student-Tabelle gespeichert sind. Das Ergebnis wird nach der Geschlechterspalte gruppiert. Die vom CTE abgelegten Daten sehen im Speicher folgendermaßen aus:

Als Nächstes führten wir die AVG-Funktion in der Spalte „SumScore“ des CTE durch. Das Endergebnis des Skripts ist der Durchschnitt von 2400 und 2730, also 2565.

Dies ist etwas komplizierter als das vorherige Beispiel, demonstriert aber das Konzept von CTE deutlicher.

Spalten in CTE beschriften

Im vorherigen Beispiel haben wir der zweiten Spalte des CTE einen Alias ​​hinzugefügt. Wir haben es in „SumScore“ umbenannt. Dies ist eine Möglichkeit, Spalten in CTE zu kennzeichnen, und ähnelt Aliasen für Tabellenspalten.

Es gibt jedoch eine andere Möglichkeit, Spaltennamen in CTE zu definieren. Sehen Sie sich die folgende Abfrage an.

USE schooldb;

WITH SumofScores(Gender, SumScore) AS
(
	SELECT 
		gender, SUM(total_score)
	FROM student
	GROUP BY gender
)

SELECT AVG (SumScore)
From SumofScores

In diesem Skript haben wir die Spaltennamen des CTE „SumofScores“ in Klammern nach dem CTE-Namen hinzugefügt. Jeder Spaltenname wird durch ein Komma getrennt.

Wenn Sie sich die SELECT-Anweisung nach dem CTE ansehen, können Sie sehen, dass wir uns dann auf die Spalte „SumScore“ beziehen, die wir in der Klammer hinter dem CTE-Namen erstellt haben.

Mehrere CTEs erstellen

Alle bisherigen Beispiele haben der Übersichtlichkeit halber nur einen einzigen gemeinsamen Tabellenausdruck verwendet. Sie können gleichzeitig eine Liste von CTEs erstellen und diese dann alle zusammen in der endgültigen Ergebnismenge verwenden.

Dies lässt sich am besten anhand eines Beispiels erklären. Sehen Sie sich das folgende Skript unten an.

Hier erstellen wir zwei CTEs. Das erste CTE wird alle Unterlagen der vor dem 1. Januar 1985 geborenen Studenten speichern. Das zweite CTE wird alle Unterlagen der am oder nach dem 1. Januar 1985 geborenen Studenten enthalten.

Danach verwenden wir select-Anweisungen, um alle Datensätze von beiden CTEs abzurufen. Die abgerufenen Datensätze werden mithilfe der UNION-Anweisung zusammengeführt. Schließlich wird der zusammengeführte Datensatz in aufsteigender Reihenfolge nach dem Geburtsdatum sortiert.

USE schooldb;

WITH OldStudents AS
(
	SELECT * FROM student
	WHERE DOB < '1985-01-01'

),

YoungStudents AS
(
	SELECT * FROM student
	WHERE DOB >= '1985-01-01'

)

(SELECT * FROM OldStudents
UNION
SELECT * FROM YoungStudents)

ORDER BY DOB

In der obigen SQL-Abfrage haben wir zwei CTEs erstellt:„OldStudents“ und „YoungStudents“. Erwähnenswert ist, dass Sie das Schlüsselwort „WITH“ nicht bei jedem CTE verwenden müssen. Sie müssen es nur vor dem ersten CTE im Skript verwenden, danach können Sie beliebig viele CTEs erstellen, indem Sie sie durch ein Komma trennen.

Das obige Skript ruft die folgenden Ergebnisse ab: