sql >> Database >  >> RDS >> Sqlserver

Introductie van algemene tabelexpressies in SQL Server

Common Table Expressions, of kortweg CTE, is gewoon een techniek om een ​​tijdelijke set records te maken waarnaar kan worden verwezen in een INSERT-, SELECT-, UPDATE- of DELETE-instructie.

Algemene tabelexpressies zijn door Microsoft geïntroduceerd in SQL Server 2005. Ze worden niet als objecten in het databasegeheugen opgeslagen omdat hun levensduur gelijk is aan de uitvoeringstijd van de query. Zodra een query is voltooid, worden ze uit het databasegeheugen verwijderd. Er kan zo vaak naar CTE worden verwezen in een zoekopdracht als u wilt en ze kunnen ook naar zichzelf verwijzen.

Laten we een database maken met een studententabel en er enkele dummy-studentenrecords in invoegen. We zullen deze database gebruiken om CTE-query's te schrijven. Zorg er zoals altijd voor dat je een goede back-up hebt gemaakt voordat je met een nieuwe code gaat experimenteren. Raadpleeg dit artikel over SQL-back-up als u het niet zeker weet.

Voer de volgende zoekopdrachten uit op uw server.

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);

Laten we nu een heel eenvoudige algemene tabeluitdrukking maken. Deze CTE bevat alle leerlingen die zijn geboren vóór 1 januari 1985. Bekijk het volgende script.

USE schooldb;

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

Om een ​​CTE aan te maken, moet u beginnen met het trefwoord 'WITH' gevolgd door de naam van het CTE en het trefwoord 'AS'.

Vervolgens moet u tussen haakjes de query schrijven die de records retourneert die de CTE tijdelijk zal opslaan. In het bovenstaande script hebben we een CTE gemaakt met de naam "OldStudents".

Houd er echter rekening mee dat als u de bovenstaande query probeert uit te voeren, u een foutmelding krijgt. Dit komt omdat zodra u een CTE heeft gemaakt, u deze onmiddellijk moet gebruiken.

Laten we alle records selecteren uit onze nieuw gecreëerde "OldStudents" CTE. Probeer het volgende script op uw server.

USE schooldb;

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

)

SELECT * FROM OldStudents

Het bovenstaande script haalt de volgende reeks records op:

Aggregatie berekenen via CTE

Net als tabellen kunt u aggregatiefuncties uitvoeren op CTE. Laten we een ander voorbeeld van CTE bekijken.

USE schooldb;

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

SELECT AVG (SumScore)
FROM SumofScores

In het bovenstaande voorbeeld hebben we een CTE gemaakt met de naam SumofScores. Deze CTE bevat de som van de waarden die zijn opgeslagen in de kolom total_score van de studententabel. Het resultaat is gegroepeerd op de geslachtskolom. De door de CTE opgeslagen gegevens zien er in het geheugen als volgt uit:

Vervolgens hebben we de AVG-functie uitgevoerd in de kolom "SumScore" van de CTE. Het uiteindelijke resultaat van het script is het gemiddelde van 2400 en 2730, ofwel 2565.

Dit is iets ingewikkelder dan het vorige voorbeeld, maar laat het concept van CTE duidelijker zien.

Kolommen labelen in CTE

In het vorige voorbeeld hebben we een alias toegevoegd aan de tweede kolom van de CTE. We hebben het omgedoopt tot "SumScore". Dit is een manier om kolommen in CTE te labelen en is vergelijkbaar met tabelkolomaliassen.

Er is echter een andere manier om kolomnamen in CTE te definiëren. Bekijk de volgende vraag.

USE schooldb;

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

SELECT AVG (SumScore)
From SumofScores

In dit script hebben we de kolomnamen van de "SumofScores" CTE tussen haakjes achter de CTE-naam toegevoegd. Elke kolomnaam wordt gescheiden door een komma.

Als u naar de SELECT-instructie na de CTE kijkt, kunt u zien dat we dan verwijzen naar de kolom 'SumScore' die we tussen haakjes achter de CTE-naam hebben gemaakt.

Meerdere CTE's maken

Alle voorbeelden tot nu toe hebben voor de duidelijkheid slechts één algemene tabeluitdrukking gebruikt. U kunt tegelijkertijd een lijst met CTE's maken en ze vervolgens allemaal in combinatie gebruiken in de uiteindelijke resultatenset.

Dit is het beste uit te leggen aan de hand van een voorbeeld. Bekijk het volgende script hieronder.

Hier zullen we twee CTE's maken. De eerste CTE bevat alle gegevens van de studenten geboren vóór 1 januari 1985. De tweede CTE bevat alle gegevens van de studenten geboren op of na 1 januari 1985.

Daarna zullen we select statements gebruiken om alle records van beide CTE's op te halen. De opgehaalde records worden samengevoegd met behulp van de UNION-instructie. Ten slotte wordt het samengevoegde record gesorteerd in oplopende volgorde van geboortedatum.

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 de bovenstaande SQL-query hebben we twee CTE's gemaakt:"OldStudents" en "YoungStudents". Het is vermeldenswaard dat u het trefwoord "WITH" niet bij elke CTE hoeft te gebruiken. U hoeft het alleen te gebruiken vóór de eerste CTE in het script, daarna kunt u een willekeurig aantal CTE's maken door ze te scheiden met een komma.

Het bovenstaande script haalt de volgende resultaten op:


  1. Geen enkele operator komt overeen met de opgegeven naam en argumenttype(s). Mogelijk moet u expliciete typecasts toevoegen. -- Netbeans, Postgresql 8.4 en Glassfish

  2. SQLite en database-initialisatie

  3. De standaardtaal van een login wijzigen in SQL Server

  4. Werken met MyISAM in MySQL