dml sql-instructies. Basis SQL-operatoren. Interactieve SQL. Weergaveoperator verwijderen

De basis van de SQL-taal bestaat uit operators, voorwaardelijk verdeeld in verschillende groepen op basis van de functies die ze uitvoeren.

De volgende groepen instructies kunnen worden onderscheiden (niet alle SQL-instructies worden vermeld):

DDL-instructies (Data Definition Language) - instructies voor het definiëren van databaseobjecten

· CREATE SCHEMA - maak een databaseschema

· DROP SHEMA - verwijder een databaseschema

· MAAK TAFEL - maak een tabel

ALTER TABLE - verander de tabel

· DROP TABLE - verwijder een tabel

· DOMEIN MAKEN - maak een domein aan

WIJZIG DOMEIN - wijzig domein

· DROP DOMAIN - verwijder een domein

· CREËER COLLATIE - maak een reeks

· DROP COLLATION - verwijder een reeks

· CREËER WEERGAVE - maak een weergave

· DROP VIEW - verwijder een weergave

DML-operatoren (Data Manipulation Language) - operators voor gegevensmanipulatie

· SELECTEER - selecteer rijen uit tabellen

· INSERT - rijen aan de tabel toevoegen

· UPDATE - wijzig rijen in de tabel

· DELETE - verwijder rijen in de tabel

COMMIT - commit wijzigingen aangebracht

· ROLLBACK - gemaakte wijzigingen ongedaan maken

Operators voor gegevensbescherming en -beheer

· CREËER BEWEGING - creëer een beperking

· DROP ASSERTION - verwijder een beperking

· GRANT - geef rechten aan een gebruiker of applicatie om objecten te manipuleren

REVOKE - trek gebruikers- of applicatierechten in

Daarnaast zijn er groepen operators voor het instellen van sessieparameters, het verkrijgen van informatie over de database, statische SQL-operators en dynamische SQL-operators.

Het belangrijkste voor de gebruiker zijn gegevensmanipulatieverklaringen (DML).

Voorbeelden van het gebruik van operatoren voor gegevensmanipulatie

INSERT - rijen in een tabel invoegen

Voorbeeld 1. Eén rij in een tabel invoegen:

WAARDEN(4, "Ivanov");

UPDATE - rijen in een tabel bijwerken

Voorbeeld 3. Meerdere rijen in een tabel bijwerken:

SET PNAME = "Poesjnikov"

WAAR P.PNUM = 1;

DELETE - rijen in een tabel verwijderen

Voorbeeld 4. Meerdere rijen in een tabel verwijderen:

WAAR P.PNUM = 1;

Voorbeelden van het gebruik van de SELECT-instructie

De SELECT-instructie is eigenlijk het belangrijkste voor de gebruiker en het meest complexe exploitant SQL. Het is bedoeld voor het ophalen van gegevens uit tabellen, d.w.z. het implementeert in feite een van de hoofddoelen van de database: het verstrekken van informatie aan de gebruiker.

De SELECT-instructie wordt altijd uitgevoerd op sommige tabellen die deel uitmaken van de database.

Opmerking. In feite kunnen databases niet alleen permanent opgeslagen tabellen bevatten, maar ook tijdelijke tabellen en zogenaamde views. Weergaven zijn eenvoudigweg SELECT-expressies die in de database zijn opgeslagen. Vanuit het oogpunt van de gebruiker is een weergave een tabel die niet permanent in de database is opgeslagen, maar "verschijnt" wanneer deze wordt geopend. Vanuit het oogpunt van de SELECT-instructie zien zowel persistente tabellen als tijdelijke tabellen en views er precies hetzelfde uit. Wanneer het systeem daadwerkelijk een SELECT-instructie uitvoert, wordt er uiteraard rekening gehouden met de verschillen tussen opgeslagen tabellen en views, maar deze verschillen verborgen van de gebruiker.


Het resultaat van een SELECT-instructie is altijd een tabel. De resultaten van de SELECT-instructie zijn dus vergelijkbaar met de operatoren van relationele algebra. Elke relationele algebra-operator kan worden uitgedrukt op een passende manier geformuleerd door de SELECT-instructie. De complexiteit van de SELECT-instructie wordt bepaald door het feit dat deze alle mogelijkheden van relationele algebra bevat, evenals extra functies, welke erin relationele algebra Nee.

SELECT Uitvoeringsopdracht verklaring

Om te begrijpen hoe het resultaat van het uitvoeren van een SELECT-instructie wordt verkregen, kunt u het conceptuele diagram van de uitvoering ervan bekijken. Dit schema is puur conceptueel, omdat het is gegarandeerd dat het resultaat hetzelfde zal zijn alsof het stap voor stap volgens dit schema zou worden uitgevoerd. In feite wordt het daadwerkelijke resultaat verkregen door meer geavanceerde algoritmen die een bepaald DBMS ‘bezit’.

Fase 1: Een enkele SELECT-instructie uitvoeren

Als de operator bevat trefwoorden UNION, EXCEPT en INTERSECT, dan wordt de zoekopdracht verdeeld in verschillende onafhankelijke zoekopdrachten, die elk afzonderlijk worden uitgevoerd:

Stap 1 (VANAF). Het directe cartesiaanse product van alle tabellen die zijn opgegeven in de vereiste FROM-clausule wordt berekend. Als resultaat van stap 1 verkrijgen we tabel A.

Stap 2 (WAAR). Als er een WHERE-clausule in de SELECT-instructie voorkomt, wordt tabel A, verkregen in stap 1, gescand. De voorwaardelijke expressie die in de WHERE-clausule wordt gegeven, wordt voor elke rij uit tabel A geëvalueerd. Alleen de rijen waarvoor de voorwaardelijke expressie retourneert waarde WAAR, worden meegenomen in het resultaat. Als de WHERE-clausule wordt weggelaten, ga dan direct naar stap 3. Als de voorwaardelijke expressie geneste subquery's omvat, worden deze geëvalueerd in overeenstemming met dit conceptuele schema. Als resultaat van stap 2 verkrijgen we tabel B.

Stap 3 (GROEPEREN OP). Als er een GROUP BY-clausule aanwezig is in de SELECT-instructie, worden de rijen van tabel B die in de tweede stap zijn verkregen, gegroepeerd volgens de groeperingslijst in de GROUP BY-clausule. Als de GROUP BY-clausule wordt weggelaten, ga dan direct naar stap 4. Als resultaat van stap 3 krijgen we tabel C.

Stap 4 (HEBBEN). Als een SELECT-instructie een HAVING-clausule bevat, worden groepen uitgesloten die niet voldoen aan de voorwaardelijke expressie die in de HAVING-clausule is opgegeven. Als de HAVING-sectie wordt weggelaten, ga dan direct naar stap 5. Als resultaat van stap 4 krijgen we tabel D.

Stap 5 (SELECTIE). Elke groep verkregen in stap 4 genereert als volgt één resultaatrij. Alle scalaire expressies die zijn opgegeven in de SELECT-clausule worden geëvalueerd. Volgens de regels voor het gebruik van de GROUP BY-clausule moeten dergelijke scalaire expressies hetzelfde zijn voor alle rijen binnen elke groep. Voor elke groep worden de waarden van de aggregatiefuncties in de sectie SELECT berekend. Als er geen GROUP BY-clausule was, maar er wel een SELECT-clausule is geaggregeerde functies, dan wordt ervan uitgegaan dat er slechts één groep is. Als er noch een GROUP BY-clausule noch aggregatiefuncties aanwezig zijn, wordt ervan uitgegaan dat er evenveel groepen zijn als er rijen geselecteerd zijn op dit moment. Als resultaat van stap 5 verkrijgen we tabel E, die evenveel kolommen bevat als er elementen zijn vermeld in de sectie SELECT en evenveel rijen als er groepen zijn geselecteerd.

Fase 2. Uitvoeren van UNION, EXCEPT, INTERSECT-bewerkingen

Als de SELECT-instructie de trefwoorden UNION, EXCEPT en INTERSECT bevat, worden de tabellen die voortvloeien uit de eerste fase samengevoegd, afgetrokken of doorsneden.

Fase 3. Het resultaat bestellen

Als de SELECT-instructie een ORDER BY-clausule bevat, worden de rijen van de tabel die in de voorgaande stappen zijn verkregen, geordend volgens de volgordelijst die is opgegeven in de ORDER BY-clausule.

In het eerste deel hebben we de DML-taal al een beetje besproken, waarbij we bijna de volledige set commando's gebruikten, met uitzondering van het MERGE-commando.

Ik zal over DML praten volgens mijn eigen volgorde, ontwikkeld op basis van persoonlijke ervaring. Onderweg zal ik ook proberen te praten over de ‘gladde’ plekken waar we ons op moeten concentreren; deze ‘gladde’ plekken zijn vergelijkbaar in veel dialecten van de SQL-taal.

Omdat het leerboek is bedoeld voor een breed scala aan lezers (niet alleen programmeurs), dan zal de uitleg soms passend zijn, d.w.z. lang en vervelend. Dit is mijn visie op de stof, die vooral in de praktijk is verkregen als gevolg van beroepsactiviteiten.

Hoofddoel dit leerboek Ontwikkel stap voor stap een volledig begrip van de essentie van de SQL-taal en leer hoe u de constructies ervan correct kunt toepassen. Professionals op dit gebied zijn wellicht ook geïnteresseerd in het doorbladeren van dit materiaal, misschien kunnen ze iets nieuws voor zichzelf leren, of misschien is het gewoon nuttig om het te lezen om hun geheugen op te frissen. Ik hoop dat iedereen het interessant zal vinden.

Omdat DML in het MS SQL-databasedialect is zeer nauw verwant aan de syntaxis van de SELECT-constructie, dus ik zal ermee over DML beginnen te praten. Naar mijn mening is de SELECT-constructie de belangrijkste constructie in de DML-taal, omdat dankzij hem of zijn onderdelen worden de benodigde gegevens uit de database gehaald.

De DML-taal bevat de volgende constructies:

  • SELECT – gegevensselectie
  • INSERT – nieuwe gegevens invoegen
  • UPDATE – gegevensupdate
  • DELETE – gegevens verwijderen
  • MERGE – gegevens samenvoegen

In dit deel bekijken we alleen de basissyntaxis van de opdracht SELECT, die er als volgt uitziet:

SELECT column_list of * FROM source WHERE filter ORDER BY sort_expression
Het onderwerp van de SELECT-instructie is erg breed, dus in dit deel zal ik me alleen concentreren op de basisconstructies ervan. Ik geloof dat je, zonder de basis goed te kennen, niet kunt beginnen met het bestuderen van complexere structuren dan draait alles om dit basisontwerp (subquery's, joins, etc.).

Als onderdeel van dit deel zal ik het ook hebben over het TOP-aanbod. Ik heb deze zin opzettelijk niet aangegeven in de basissyntaxis, omdat... het wordt anders geïmplementeerd in verschillende SQL-dialecten.

Als de DDL-taal statischer is, d.w.z. met zijn hulp worden rigide structuren gecreëerd (tabellen, relaties, enz.), vervolgens is de DML-taal dynamisch van aard, hier kun je op verschillende manieren de juiste resultaten krijgen.

De training gaat ook door in de stapsgewijze modus, d.w.z. Tijdens het lezen moet u onmiddellijk proberen het voorbeeld met uw eigen handen te voltooien. Vervolgens analyseer je het verkregen resultaat en probeer je het intuïtief te begrijpen. Blijft er iets onduidelijk, bijvoorbeeld de betekenis van een functie, zoek dan hulp op internet.

De voorbeelden worden getoond in de Testdatabase, die in het eerste deel met DDL+DML is aangemaakt.

Voor degenen die in het eerste deel geen database hebben gemaakt (aangezien niet iedereen geïnteresseerd kan zijn in de DDL-taal), kunnen ze het volgende script gebruiken:

Script voor het maken van een database testen

Een database maken CREATE DATABASE Test GO - maak de testdatabase actueel USE Test GO - maak referentietabellen CREATE TABLE Positions(ID int IDENTITY(1,1) NOT NULL CONSTRAINT PK_Positions PRIMAIRE SLEUTEL, Naam nvarchar(30) NOT NULL) CREATE TABLE Departments(ID int IDENTITY(1,1) NOT NULL CONSTRAINT PK_Departments PRIMARY KEY, Name nvarchar(30) NOT NULL) GO -- vul de referentietabellen met gegevens SET IDENTITY_INSERT Posities ON INSERT Posities( ID,Naam)VALUES (1,N"Accountant"), (2,N"Directeur"), (3,N"Programmeur"), (4,N"Senior Programmeur") SET IDENTITY_INSERT Posities UIT GO SET IDENTITY_INSERT Afdelingen AAN INSERT Afdelingen(ID,Naam)VALUES (1,N"Administratie"), (2,N"Accounting"), (3,N"IT") SET IDENTITY_INSERT Afdelingen UIT GO - maak een tabel met medewerkers CREATE TABLE Werknemers(ID int NOT NULL, Naam nvarchar(30), Verjaardagsdatum, E-mailadres nvarchar(30), PositionID int, DepartmentID int, HireDate date NOT NULL CONSTRAINT DF_Employees_HireDate DEFAULT SYSDATETIME(), ManagerID int, CONSTRAINT PK_Employees PRIMARY KEY (ID), CONSTRAINT FK_Employees_DepartmentID FOREIGN KEY(AfdelingsID) REFERENTIES Afdelingen(ID), CONSTRAINT FK_Employees_PositionID FOREIGN KEY(PositieID) REFERENTIES Posities(ID), CONSTRAINT FK_Employees_ManagerID FOREIGN KEY (ManagerID) REFERENTIES Werknemers(ID), CONSTRAINT UQ_Employees_Email UNIQUE( E-mail), CONSTRAINT CK_Employees_ID CHECK (ID TUSSEN 1000 EN 1999), INDEX IDX_Employees_Name(Name)) GO -- vul het met gegevens INSERT Medewerkers (ID,Naam,Verjaardag,E-mail,PositieID,AfdelingsID,ManagerID)VALUES (1000,N"Ivanov I.I.","19550219 ", " [e-mailadres beveiligd]",2,1,NULL), (1001,N"Petrov P.P.","19831203"," [e-mailadres beveiligd]",3,3,1003), (1002,N"Sidorov S.S.","19760607"," [e-mailadres beveiligd]",1,2,1000), (1003,N"Andrejev A.A.","19820417"," [e-mailadres beveiligd]",4,3,1000)

Dat is alles, nu zijn we klaar om de DML-taal te leren.

SELECT – operator voor gegevensselectie

Laten we eerst voor de actieve query-editor de huidige database testen door deze in de vervolgkeuzelijst te selecteren of door de opdracht "USE Test" te gebruiken.

Laten we beginnen met de meest basale vorm van SELECT:

SELECTEER * VAN Medewerkers
In deze query vragen we om alle kolommen (aangegeven door een "*") uit de tabel Werknemers te retourneren. U kunt dit lezen als "SELECT all_fields FROM the Employees_table." Als er een geclusterde index is, zullen de geretourneerde gegevens hoogstwaarschijnlijk daarop worden gesorteerd, in dit geval op de ID-kolom (maar dit is niet belangrijk, aangezien we in de meeste gevallen de sortering zullen specificeren in uitdrukkelijk zelf via ORDER BY...):

Identiteitskaart Naam Verjaardag E-mail PositieID AfdelingID Huurdatum ManagerID
1000 Ivanov I.I. 1955-02-19 [e-mailadres beveiligd] 2 1 2015-04-08 NUL
1001 Petrov P.P. 1983-12-03 [e-mailadres beveiligd] 3 3 2015-04-08 1003
1002 Sidorov S.S. 1976-06-07 [e-mailadres beveiligd] 1 2 2015-04-08 1000
1003 Andreev A.A. 1982-04-17 [e-mailadres beveiligd] 4 3 2015-04-08 1000

Over het algemeen is het de moeite waard om te zeggen dat dit het meest in het MS SQL-dialect is eenvoudige vorm SELECT-vraag bevat mogelijk geen FROM-blok, in welk geval u het kunt gebruiken om enkele waarden op te halen:

SELECT 5550/100*15, SYSDATETIME(), -- ophalen van de databasesysteemdatum SIN(0)+COS(0)

(Geen kolomnaam) (Geen kolomnaam) (Geen kolomnaam)
825 2015-04-11 12:12:36.0406743 1

Houd er rekening mee dat de uitdrukking (5550/100*15) het resultaat 825 opleverde, hoewel als we met een rekenmachine berekenen de waarde (832,5) zal zijn. Het resultaat 825 werd verkregen omdat in onze uitdrukking alle getallen gehele getallen zijn, en daarom is het resultaat een geheel getal, d.w.z. (5550/100) geeft ons 55, niet (55,5).

Houd er rekening mee dat de volgende logica werkt in MS SQL:

  • Heel / Heel = Heel (d.w.z. in dit geval is dat zo gehele deling)
  • Echt / geheel getal = echt
  • Geheel getal / Echt = Echt
Die. het resultaat wordt omgezet naar grotere soort, dus in de laatste 2 gevallen krijgen we een reëel getal (denk aan wiskunde: bereik echte cijfers is groter dan het bereik van gehele getallen, dus het resultaat wordt ernaar geconverteerd):

KIES 123/10, -- 12 123./10, -- 12,3 123/10. -- 12.3
Hier (123.) = (123.0), kan in dit geval alleen 0 worden weggegooid en blijft alleen het punt over.

Met anderen rekenkundige bewerkingen Dezelfde logica is van toepassing, alleen is in het geval van verdeeldheid deze nuance relevanter.

Let dus op het datatype numerieke kolommen. Als het een geheel getal is en u een reëel resultaat wilt krijgen, gebruik dan een transformatie of plaats eenvoudigweg een punt achter het getal dat wordt aangegeven als een constante (123.).

U kunt de functie CAST of CONVERT gebruiken om velden te converteren. Laten we bijvoorbeeld het ID-veld gebruiken, dit is van het type int:

SELECT ID, ID/100, -- deling van gehele getallen vindt hier plaats CAST(ID AS float)/100, -- gebruik de CAST-functie om te converteren naar soort vlotter CONVERT(float,ID)/100, -- gebruik de CONVERT-functie om te converteren naar float-ID/100. -- gebruik transformatie door op te geven dat de noemer een reëel getal FROM Werknemers is

Identiteitskaart (Geen kolomnaam) (Geen kolomnaam) (Geen kolomnaam) (Geen kolomnaam)
1000 10 10 10 10.000000
1001 10 10.01 10.01 10.010000
1002 10 10.02 10.02 10.020000
1003 10 10.03 10.03 10.030000

Even een opmerking. In de ORACLE-database is syntaxis zonder een FROM-blok onaanvaardbaar; voor dit doel wordt de DUAL-systeemtabel gebruikt, die één regel bevat:

SELECTEER 5550/100*15, -- en in ORACLE zal het resultaat gelijk zijn aan 832.5 sysdate, sin(0)+cos(0) FROM DUAL


Opmerking. De tabelnaam in veel RDB's kan worden voorafgegaan door de schemanaam:

SELECT * FROM dbo.Employees -- dbo – schemanaam

Een schema is een logische eenheid van een database, die een eigen naam heeft en waarmee u databaseobjecten zoals tabellen, views, enz. binnen zichzelf kunt groeperen.

De definitie van een schema in verschillende databases kan in sommige gevallen verschillen; het schema is rechtstreeks gerelateerd aan de databasegebruiker, d.w.z. in dit geval kunnen we zeggen dat het schema en de gebruiker synoniemen zijn en dat alle objecten die in het schema zijn gemaakt in wezen objecten zijn gegeven gebruiker. In MS SQL is een schema een onafhankelijke logische eenheid die op zichzelf kan worden gemaakt (zie SCHEMA MAKEN).

Standaard wordt in de MS SQL-database één schema aangemaakt met de naam dbo (Database Owner) en in dit schema worden standaard alle aangemaakte objecten aangemaakt. Als we dus eenvoudigweg de naam van een tabel in een query opgeven, wordt deze doorzocht in het dbo-schema van de huidige database. Als we een object in een specifiek schema willen maken, moeten we de objectnaam ook vooraf laten gaan door de schemanaam, bijvoorbeeld "CREATE TABLE schema_name.table_name(...)".

Bij MS SQL mag de schemanaam ook worden voorafgegaan door de naam van de database waarin het schema zich bevindt:

SELECTEER * UIT Test.dbo.Employees -- databasenaam.schemanaam.tabel
Deze verduidelijking kan bijvoorbeeld nuttig zijn als:

  • in één verzoek hebben we toegang tot objecten die zich in verschillende schema's of databanken
  • u moet gegevens van het ene schema of de database naar het andere overbrengen
  • omdat u zich in de ene database bevindt, moet u gegevens uit een andere database opvragen
  • enz.
Een schema is een erg handig hulpmiddel dat handig is om te gebruiken bij het ontwikkelen van databasearchitectuur, vooral grote databases.

Vergeet ook niet dat we in de verzoektekst zowel enkelregelige “-- ...” als meerregelige “/* ... */” opmerkingen kunnen gebruiken. Als het verzoek groot en complex is, kunnen opmerkingen u of iemand anders na een tijdje enorm helpen de structuur ervan te onthouden of te begrijpen.

Als er veel kolommen in de tabel staan, en vooral als er nog steeds veel rijen in de tabel staan, en als we via het netwerk query's uitvoeren op de database, dan verdient het de voorkeur om te selecteren met een directe lijst van de velden die je nodig hebt, gescheiden door komma's:

SELECTEER ID,Naam VAN Medewerkers

Die. hier zeggen we dat we alleen de velden ID en Naam uit de tabel hoeven terug te geven. Het resultaat zal als volgt zijn (de optimalisatie heeft hier trouwens besloten om de index te gebruiken die is gemaakt door het veld Naam):

Identiteitskaart Naam
1003 Andreev A.A.
1000 Ivanov I.I.
1001 Petrov P.P.
1002 Sidorov S.S.

Even een opmerking. Soms is het handig om te kijken hoe gegevens worden opgehaald, om bijvoorbeeld te achterhalen welke indexen worden gebruikt. Dit kan worden gedaan door op de knop “Geschat uitvoeringsplan weergeven” te klikken of door “Inclusief feitelijk uitvoeringsplan” in te stellen (in dit geval kunnen we zien echt plan, respectievelijk alleen na het uitvoeren van het verzoek):

Analyse van het uitvoeringsplan is erg handig bij het optimaliseren van een query; u kunt er achter komen welke indexen ontbreken of welke indexen helemaal niet worden gebruikt en kunnen worden verwijderd.

Als u net bent begonnen met het leren van DML, dan is dit nu niet zo belangrijk voor u. Houd er rekening mee en u kunt het veilig vergeten (misschien zult u het nooit nodig hebben) - ons oorspronkelijke doel is om de basisprincipes van de DML-taal te leren en leer hoe u ze correct kunt gebruiken, en optimalisatie is al een aparte kunst. Soms is het belangrijker dat u eenvoudigweg een correct geschreven vraag heeft die vanuit het oogpunt van het onderwerp het juiste resultaat oplevert, en dat individuele mensen deze al aan het optimaliseren zijn. Eerst moet u leren hoe u eenvoudigweg query's correct kunt schrijven, met behulp van alle middelen om het doel te bereiken. Het belangrijkste doel dat u nu moet bereiken, is dat uw zoekopdracht de juiste resultaten oplevert.

Tabelaliassen instellen

Bij het weergeven van kolommen kunnen deze worden voorafgegaan door de naam van de tabel in het FROM-blok:

SELECT Werknemers.ID, Werknemers.Naam VAN Werknemers

Maar deze syntaxis is meestal lastig te gebruiken, omdat de tabelnaam kan lang zijn. Voor deze doeleinden worden meestal kortere namen gespecificeerd en gebruikt - aliassen:

SELECT werk.ID, werk.Naam VAN Werknemers AS werk
of

SELECT emp.ID,emp.Name FROM Werknemers emp -- het AS trefwoord kan worden weggelaten (ik geef de voorkeur aan deze optie)

Hier is emp een alias voor de tabel Werknemers die kan worden gebruikt in de context van deze SELECT-instructie. Die. we kunnen zeggen dat we in de context van deze SELECT-instructie de tabel een nieuwe naam geven.

In dit geval zijn de resultaten van de zoekopdracht uiteraard precies hetzelfde als bij “SELECT ID,Name FROM Employees”. Waarom dit nodig is zal later duidelijk worden (zelfs niet in dit deel), voorlopig onthouden we alleen dat de kolomnaam kan worden voorafgegaan (verduidelijkt) hetzij rechtstreeks door de tabelnaam, hetzij door een alias te gebruiken. Hier kunt u een van de twee dingen gebruiken, d.w.z. Als u een alias instelt, moet u deze gebruiken, maar kunt u de tabelnaam niet langer gebruiken.

Even een opmerking. In ORACLE is alleen de optie toegestaan ​​om een ​​tabelalias op te geven zonder het trefwoord AS.

DISTINCT – dubbele rijen verwijderen

Het sleutelwoord DISTINCT wordt gebruikt om dubbele rijen uit het queryresultaat te verwijderen. Stel je grofweg voor dat je eerst een query uitvoert zonder de DISTINCT-optie, en vervolgens alle duplicaten uit het resultaat verwijdert. Laten we dit voor meer duidelijkheid demonstreren aan de hand van een voorbeeld:

Laten we een tijdelijke tabel maken voor demonstratie CREATE TABLE #Trash(ID int NOT NULL PRIMARY KEY, Col1 varchar(10), Col2 varchar(10), Col3 varchar(10)) - fill deze tafel allerlei soorten afval INSERT #Trash(ID,Col1,Col2,Col3)VALUES (1,"A", "A", "A"), (2, "A", "B", "C"), ( 3, "C", "A", "B"), (4,"A", "A", "B"), (5,"B", "B", "B"), (6, "A", "A", "B"), (7,"A", "A", "A"), (8,"C", "A", "B"), (9,"C ", "A", "B"), (10,"A", "A", "B"), (11,"A",NULL,"B"), (12,"A",NULL, "B ") -- laten we eens kijken wat de query retourneert zonder de DISTINCT SELECT-optie Col1,Col2,Col3 FROM #Trash -- laten we eens kijken wat de query retourneert met de DISTINCT SELECT-optie DISTINCT Col1,Col2,Col3 FROM #Trash -- verwijderen de tijdelijke tabel DROP TABLE #Trash

Visueel ziet het er als volgt uit (alle duplicaten zijn gemarkeerd met dezelfde kleur):

Laten we nu kijken waar dit kan worden toegepast, aan de hand van een praktischer voorbeeld: we zullen alleen unieke afdelings-ID's uit de tabel Werknemers retourneren (dat wil zeggen, we zullen de ID's achterhalen van de afdelingen waarin werknemers zijn geregistreerd):

SELECTEER EEN ANDERE AfdelingID VAN Medewerkers

Hier hebben we 4 regels, omdat... Er zijn geen herhalende combinaties (AfdelingsID, PositieID) in onze tabel.

Laten we even terugkeren naar DDL.

Omdat we bijna geen gegevens meer hebben voor demovoorbeelden, en we uitgebreider en duidelijker willen praten, laten we onze Employess-tabel een beetje uitbreiden. Laten we bovendien een beetje DDL onthouden, zoals ze zeggen: "Herhaling is de moeder van leren", en laten we bovendien nog een beetje verder gaan en de UPDATE-verklaring toepassen:

We maken nieuwe kolommen ALTER TABLE Medewerkers ADD Achternaam nvarchar(30), -- achternaam Voornaam nvarchar(30), -- voornaam Middelnaam nvarchar(30), -- middelste naam Salarisvlotter, -- en natuurlijk salaris in sommige eenheden BonusPercent float - percentage voor het berekenen van de bonus van het GO-salaris - vul ze met gegevens (sommige gegevens zijn opzettelijk weggelaten) UPDATE Medewerkers SET LastName=N"Ivanov", FirstName=N"Ivan", MiddleName=N"Ivanovich", Salaris=5000,BonusPercent= 50 WAAR ID=1000 -- Ivanov I.I. UPDATE Werknemers SET Achternaam=N"Petrov",Voornaam=N"Petr",Middennaam=N"Petrovich", Salaris=1500,BonusPercent= 15 WHERE ID=1001 -- Petrov P.P. UPDATE Werknemers SET LastName=N"Sidor",FirstName=N"Sidor",MiddleName=NULL, Salaris=2500,BonusPercent=NULL WHERE ID=1002 -- Sidorov S.S. UPDATE Werknemers SET Achternaam=N"Andreev",Voornaam=N"Andrey",Middennaam=NULL, Salaris=2000,BonusPercent= 30 WAAR ID=1003 -- Andreev A.A.

Laten we ervoor zorgen dat de gegevens succesvol zijn bijgewerkt:

SELECTEER * VAN Medewerkers

Identiteitskaart Naam Achternaam Voornaam Middelste naam Salaris Bonuspercentage
1000 Ivanov I.I. Ivanov Iwan Ivanovitsj 5000 50
1001 Petrov P.P. Petrov Petrus Petrovich 1500 15
1002 Sidorov S.S. Sidorov Sidor NUL 2500 NUL
1003 Andreev A.A. Andrejev Andrej NUL 2000 30

Aliassen instellen voor querykolommen

Ik denk dat het gemakkelijker is om het hier te laten zien dan om te schrijven:

SELECTEER -- geef een naam aan de berekende kolom Achternaam+" "+Voornaam+" "+Middelnaam AS Volledige naam, -- gebruik dubbele aanhalingstekens, omdat er wordt een spatie gebruikt HireDate AS "Datum van ontvangst", -- gebruik van vierkante haken, omdat spatie wordt gebruikt Verjaardag AS [ Geboortedatum], -- het woord AS is niet noodzakelijk Salaris ZP VAN Werknemers

Volledige naam Datum van toelating Geboortedatum ZP
Ivanov Ivan Ivanovitsj 2015-04-08 1955-02-19 5000
Petrov Petr Petrovich 2015-04-08 1983-12-03 1500
NUL 2015-04-08 1976-06-07 2500
NUL 2015-04-08 1982-04-17 2000

Zoals we kunnen zien, worden de kolomaliassen die we hebben opgegeven weergegeven in de koptekst van de resulterende tabel. Eigenlijk is dit het hoofddoel van kolomaliassen.

Let op, want bij de laatste 2 werknemers was geen tweede naam opgegeven (NULL-waarde), dan retourneerde het resultaat van de expressie “LastName+" "+FirstName+" "+MiddleName" ook NULL naar ons.

Om strings samen te voegen (toe te voegen, samen te voegen) in MS SQL, wordt het “+” symbool gebruikt.

Houd er rekening mee dat alle expressies waarbij NULL betrokken is (bijvoorbeeld delen door NULL, optellen met NULL) NULL zullen retourneren.

Even een opmerking.
In het geval van ORACLE wordt de operator “||” gebruikt om tekenreeksen samen te voegen en de aaneenschakeling ziet er als volgt uit: "Achternaam||" "||Voornaam||" "||Middennaam". Voor ORACLE is het vermeldenswaard dat dit het geval is soorten strings Er is een uitzondering, voor hen zijn NULL en de lege string "" hetzelfde, dus in ORACLE zal een dergelijke expressie terugkeren voor de laatste 2 werknemers "Sidorov Sidor" en "Andrey Andreev". Even ORACLE-versies 12c, voor zover ik weet is er geen optie die dit gedrag verandert (als ik het mis heb, corrigeer mij dan alstublieft). Hier kan ik moeilijk beoordelen of dit goed of slecht is, omdat... In sommige gevallen is het gedrag van een NULL-reeks handiger, zoals in MS SQL, en in andere gevallen, zoals in ORACLE.

In ORACLE zijn alle hierboven genoemde kolomaliassen ook geldig, behalve [...].


Om de constructie niet af te schermen met behulp van de ISNULL-functie, kunnen we in MS SQL de CONCAT-functie gebruiken. Laten we 3 opties overwegen en vergelijken:

SELECT Achternaam+" "+Voornaam+" "+TweedeNaam VolledigeNaam1, -- 2 opties voor het vervangen van NULL lege regels"" (we krijgen hetzelfde gedrag als in ORACLE) ISNULL(Achternaam,"")+" "+ISNULL(Voornaam,"")+" "+ISNULL(TweedeNaam,"") VolledigeNaam2, CONCAT(Achternaam," ", Voornaam, " ",Tweedenaam) VolledigeNaam3 FROM Werknemers

VolledigeNaam1 VolledigeNaam2 VolledigeNaam3
Ivanov Ivan Ivanovitsj Ivanov Ivan Ivanovitsj Ivanov Ivan Ivanovitsj
Petrov Petr Petrovich Petrov Petr Petrovich Petrov Petr Petrovich
NUL Sidorov Sidor Sidorov Sidor
NUL Andrejev Andrej Andrejev Andrej

In MS SQL kunnen aliassen ook worden opgegeven met het gelijkteken:

SELECTEER "Ontvangstdatum"=Aanwervingsdatum, -- naast "..." en […] kunt u "..." gebruiken [Geboortedatum]=Verjaardag, ZP=Salaris VAN Werknemers

Het gebruik van het trefwoord AS of het gelijkteken om een ​​alias op te geven is waarschijnlijk meer een kwestie van smaak. Maar bij het analyseren van de verzoeken van anderen kan deze kennis nuttig zijn.

Ten slotte zal ik zeggen dat het beter is om namen voor aliassen in te stellen met alleen Latijnse tekens en cijfers, en het gebruik van “…”, “…” en […] te vermijden, dat wil zeggen, dezelfde regels te gebruiken die we gebruikten bij het benoemen van tabellen . Verder zal ik in de voorbeelden alleen dergelijke namen gebruiken en geen "...", "..." en […].

Basis rekenkundige operatoren voor SQL


Uitvoering prioriteit rekenkundige operatoren hetzelfde als in de wiskunde. Indien nodig kan de volgorde van toepassing van de operatoren worden gewijzigd met behulp van haakjes - (a+b)*(x/(y-z)).

En ik herhaal nogmaals dat elke bewerking met NULL NULL oplevert, bijvoorbeeld: 10+NULL, NULL*15/3, 100/NULL - dit alles zal resulteren in NULL. Die. Simpel gezegd kan er geen onbepaalde betekenis gegeven worden definitief resultaat. Houd hier rekening mee bij het opstellen van uw query en behandel indien nodig NULL-waarden met behulp van de functies ISNULL en COALESCE:

SELECTEER ID,Naam, Salaris/100*BonusPercent AS Resultaat1, -- zonder NULL-waarden te verwerken Salaris/100*ISNULL(BonusPercent,0) AS Resultaat2, -- gebruik de ISNULL-functie Salaris/100*COALESCE(BonusPercent,0) AS Result3 - - gebruik de functie COALESCE VAN Medewerkers

Ik zal je iets vertellen over de COALESCE-functie:

COALESCE (expr1, expr2, ..., exprn) - Retourneert de eerste niet-NULL-waarde uit een lijst met waarden.

SELECT COALESCE(f1, f1*f2, f2*f3) val -- in dit geval wordt de derde waarde geretourneerd FROM (SELECT null f1, 2 f2, 3 f3) q

Ik zal me vooral concentreren op het praten over DML-constructies, en voor het grootste deel zal ik het niet hebben over de functies die in de voorbeelden zullen verschijnen. Als u niet begrijpt wat een bepaalde functie doet, zoek dan naar de beschrijving ervan op internet. U kunt zelfs in één keer naar informatie zoeken per groep functies, bijvoorbeeld door 'MS' te vragen in Google Zoeken SQL-tekenreeksen functies", "MS SQL wiskundige functies" of "MS SQL-functies NULL-verwerking." Er is veel informatie over functies en u kunt deze gemakkelijk vinden. In de MSDN-bibliotheek kunt u bijvoorbeeld meer te weten komen over de COALESCE-functie:

Knippen van MSDN Vergelijking van COALESCE en CASE

De COALESCE-expressie is een syntactische snelkoppeling voor de CASE-expressie. Dit betekent dat COALESCE(expressie1,...n) door de queryoptimalisatie wordt herschreven als de volgende CASE-expressie:

CASE WHEN (expressie1 IS NIET NULL) THEN expressie1 WHEN (expressie2 IS NIET NULL) THEN expressie2 ... ELSE expressieN END

Laten we bijvoorbeeld eens kijken hoe u de rest van de deling (%) kunt gebruiken. Deze exploitant erg handig als u records in groepen moet splitsen. Laten we bijvoorbeeld alle werknemers eruit halen die even hebben personeelsnummers(ID), d.w.z. de ID's die deelbaar zijn door 2:

SELECT ID,Name FROM Werknemers WHERE ID%2=0 -- de rest bij delen door 2 is 0

ORDER BY – het resultaat van de zoekopdracht sorteren

De ORDER BY-clausule wordt gebruikt om het resultaat van een query te sorteren.

SELECTEER Achternaam, Voornaam, Salaris VAN Werknemers BESTEL OP Achternaam, Voornaam - sorteer het resultaat in 2 kolommen - op Achternaam en vervolgens op Voornaam

Voor een opmerking. Er is een ASC-trefwoord voor het sorteren in oplopende volgorde, maar aangezien oplopend sorteren de standaard is, kunt u deze optie vergeten (ik kan me niet herinneren dat ik deze optie ooit heb gebruikt).

Het is vermeldenswaard dat de ORDER BY-clausule ook velden kan gebruiken die niet in de SELECT-clausule voorkomen (behalve in het geval waarin DISTINCT wordt gebruikt, wat ik hieronder zal bespreken). Ik loop bijvoorbeeld een stukje vooruit met de TOP-optie en laat zien hoe u bijvoorbeeld 3 werknemers kunt selecteren die het hoogste salaris hebben, rekening houdend met het feit dat ik om vertrouwelijkheidsredenen het salaris zelf niet mag tonen:

SELECTEER TOP 3 - retourneer alleen de eerste 3 records van de volledige resultaat-ID, Achternaam, Voornaam VAN Werknemers ORDER OP Salaris DESC - sorteer het resultaat in aflopende volgorde van Salaris

Identiteitskaart Achternaam Voornaam
1000 Ivanov Iwan
1002 Sidorov Sidor

Uiteraard doet zich hier het geval voor dat meerdere medewerkers hetzelfde salaris kunnen hebben en het is moeilijk te zeggen bij welke drie medewerkers dit verzoek terugkomt, dit moet met de taakdirecteur worden opgelost; Laten we zeggen dat u, nadat u dit probleem met de ontwerper had besproken, ermee instemde en besloot het te gebruiken volgende optie– doe een extra sortering op geboortedatumveld (d.w.z. wij waarderen jongeren), en mocht de geboortedatum van meerdere medewerkers samenvallen (dit kan immers ook), dan kun je een derde sortering doen in aflopende volgorde van ID-waarden (laatste De steekproef omvat degenen die de maximale ID hebben - bijvoorbeeld degenen die als laatste zijn geaccepteerd, laten we zeggen dat we personeelsnummers opeenvolgend uitgeven):

SELECTEER TOP 3 - retourneer alleen de eerste 3 records van het volledige resultaat ID, Achternaam, Voornaam VAN Werknemers ORDER OP Salaris DESC, -- 1. sorteer het resultaat in aflopende volgorde op Salarisverjaardag, -- 2. en vervolgens op Geboortedatum ID DESC -- 3 en voor volledige duidelijkheid van het resultaat voegen we sortering op ID toe.

Die. je moet proberen het resultaat van het verzoek voorspelbaar te maken, zodat je bij een debriefing kunt uitleggen waarom deze specifieke mensen op de “zwarte lijst” zijn geplaatst. alles werd eerlijk gekozen, volgens de vastgestelde regels.

U kunt ook sorteren met behulp van verschillende expressies in de ORDER BY-clausule:

SELECT Achternaam,Voornaam VAN Werknemers ORDER BY CONCAT(Achternaam," ",Voornaam) -- gebruik de expressie

U kunt ook aliassen gebruiken die zijn opgegeven voor kolommen in ORDER BY:

SELECT CONCAT(Achternaam," ",Voornaam) fi FROM Werknemers ORDER BY fi -- gebruik een alias

Het is vermeldenswaard dat bij gebruik van de DISTINCT-clausule alleen de kolommen uit het SELECT-blok kunnen worden gebruikt in de ORDER BY-clausule. Die. na het toepassen van de DISTINCT-bewerking krijgen we nieuw setje gegevens, met een nieuwe set kolommen. Om deze reden zal het volgende voorbeeld niet werken:

SELECTEER DISTINCT Achternaam, Voornaam, Salaris VAN Werknemers ORDER OP ID - ID staat niet in de resulterende set die we hebben gekregen met DISTINCT

Die. de ORDER BY-clausule wordt toegepast op de resulterende set voordat het resultaat wordt teruggestuurd naar de gebruiker.

Opmerking 1. U kunt ook de nummers van de kolommen gebruiken die worden vermeld in de SELECT in de ORDER BY-clausule:

SELECTEER Achternaam,Voornaam,Salaris VAN Werknemers BESTEL OP -- sorteer op volgorde 3 DESC, -- 1. aflopend Salaris 1, -- 2. op Achternaam 2 -- 3. op Voornaam

Voor beginners lijkt het handig en verleidelijk, maar het is beter om deze sorteeroptie te vergeten en nooit te gebruiken.

Als in dit geval (wanneer de velden expliciet worden vermeld) deze optie nog steeds acceptabel is, dan is het in het geval van het gebruik van “*” beter om deze optie nooit te gebruiken. Waarom - omdat als iemand bijvoorbeeld de volgorde van de kolommen in de tabel wijzigt of kolommen verwijdert (en dit is een normale situatie), uw zoekopdracht mogelijk nog steeds werkt, maar ten onrechte, omdat sorteren kan al op andere kolommen worden gedaan, en dit is verraderlijk omdat deze fout zal wellicht niet zo snel bekend worden.

Als de pijlers expliciet zouden worden vermeld, zou de query in de bovenstaande situatie ofwel blijven werken, maar ook correct (aangezien alles expliciet is gedefinieerd), of zou er eenvoudigweg een foutmelding verschijnen die van deze kolom bestaat niet.

U kunt dus gerust het sorteren op kolomnummers vergeten.

Opmerking 2.
In MS SQL bij oplopende volgorde NULL-waarden wordt als eerste weergegeven.

SELECTEER BonusPercent VAN Medewerkers BESTEL OP BonusPercent

Als u DESC gebruikt, bevinden ze zich dus aan het einde

SELECTEER BonusPercent VAN Medewerkers BESTEL OP BonusPercent DESC

Als u de logica voor het sorteren van NULL-waarden moet wijzigen, gebruikt u bijvoorbeeld expressies:

SELECTEER Bonuspercentage VAN Werknemers BESTEL OP ISNULL(BonusPercent,100)

ORACLE biedt hiervoor twee opties: NULLS FIRST en NULLS LAST (standaard gebruikt). Bijvoorbeeld:

SELECTEER BonusPercent VAN Werknemers BESTEL OP BonusPercent OMSCHRIJVING NULLS LAATSTE

Let hierop bij het overstappen naar een bepaalde database.

TOP – retourneer het opgegeven aantal records

Uittreksel uit MSDN. TOP: Beperkt het aantal geretourneerde rijen in de queryresultaatset tot een opgegeven aantal of percentage. Wanneer een TOP-clausule wordt gebruikt in combinatie met een ORDER BY-clausule, is de resultatenset beperkt tot de eerste N rijen van het gesorteerde resultaat. Anders worden de eerste N rijen in een niet-gespecificeerde volgorde geretourneerd.

Gebruikelijk deze uitdrukking wordt gebruikt met de ORDER BY-clausule en we hebben al naar voorbeelden gekeken waarbij het nodig was om de eerste N rijen uit de resultatenset te retourneren.

Zonder BESTEL DOOR meestal dit voorstel gebruikt wanneer we alleen maar naar een voor ons onbekende tabel moeten kijken, die mogelijk veel records bevat. In dit geval kunnen we bijvoorbeeld vragen om alleen de eerste 10 rijen terug te geven, maar voor de duidelijkheid zullen we slechts 2 zeggen:

SELECTEER TOP 2 * VAN Medewerkers

U kunt ook het woord PERCENT opgeven om het overeenkomstige percentage rijen uit de resultatenset te retourneren:

SELECTEER TOP 25 PROCENT * VAN Werknemers

In mijn praktijk wordt het vaakst gebruik gemaakt van steekproeven op basis van het aantal rijen.

U kunt ook de optie WITH TIES gebruiken met TOP, waarmee u alle rijen kunt retourneren in geval van dubbelzinnige sortering, d.w.z. deze zin retourneert alle rijen die qua samenstelling gelijk zijn aan de rijen die in de TOP N-selectie vallen. Als resultaat kunnen er meer dan N rijen worden geselecteerd. Laten we ter demonstratie nog een "Programmeur" toevoegen met een salaris van 1500:

INSERT Werknemers(ID,Naam,E-mail,PositieID,AfdelingID,ManagerID,Salaris) VALUES(1004,N"Nikolaev N.N."," [e-mailadres beveiligd]",3,3,1003,1500)

En laten we nog een medewerker toevoegen zonder de functie en afdeling aan te geven met een salaris van 2000:

INSERT Werknemers(ID,Naam,E-mail,PositieID,AfdelingsID,ManagerID,Salaris) VALUES(1005,N"Alexandrov A.A."," [e-mailadres beveiligd]",NULL,NULL,1000,2000)

Laten we nu, met behulp van de optie MET BANDEN, alle werknemers selecteren waarvan het salaris samenvalt met de salarissen van 3 werknemers, met het kleinste salaris (ik hoop dat het verder duidelijk wordt waar ik op doel):

SELECTEER TOP 3 MET BANDEN ID, Naam, Salaris VAN Werknemers BESTEL OP Salaris

Hoewel TOP 3 is aangegeven, heeft het verzoek hier 4 records geretourneerd, omdat de salariswaarde die TOP 3 opleverde (1500 en 2000) werd gevonden bij 4 werknemers. Visueel werkt het ongeveer zo:

Even een opmerking.
TOP is geïmplementeerd in verschillende databases op verschillende manieren, in MySQL bestaat hiervoor een LIMIT-clausule, waarin u bovendien de startoffset kunt instellen.

In ORACLE 12c introduceerden ze ook hun eigen analoog, waarbij de functionaliteit van TOP en LIMIT werd gecombineerd - zoek naar de woorden "ORACLE OFFSET FETCH". Vóór versie 12c werd hiervoor doorgaans de pseudokolom ROWNUM gebruikt.


Wat gebeurt er als u de DISTINCT- en TOP-clausules tegelijkertijd toepast? Dergelijke vragen kunnen eenvoudig worden beantwoord door experimenten uit te voeren. Wees in het algemeen niet bang en wees niet lui om te experimenteren, want... Het meeste wordt geleerd door oefening. De woordvolgorde in de SELECT-instructie is als volgt: DISTINCT komt eerst, gevolgd door TOP, d.w.z. Als je logisch nadenkt en van links naar rechts leest, wordt de eerste die duplicaten weggooit toegepast en wordt vervolgens TOP gemaakt op basis van deze set. Laten we eens kijken en ervoor zorgen dat dit het geval is:

SELECTEER DE TOP 2 Salaris VAN Werknemers BESTEL OP Salaris

Salaris
1500
2000

Die. Als gevolg hiervan ontvingen we de twee kleinste salarissen van allemaal. Natuurlijk kan het voorkomen dat het salaris voor sommige werknemers niet wordt gespecificeerd (NULL), omdat Het schema biedt ons de mogelijkheid dit te doen. Daarom besluiten we, afhankelijk van de taak, om NULL-waarden in de ORDER BY-clausule te verwerken, of eenvoudigweg alle records te verwijderen waarvoor Salaris NULL is, en hiervoor gaan we verder met het bestuderen van de WHERE-clausule.

WAAR – voorwaarde voor rijselectie

Deze zin wordt gebruikt om records op een bepaalde voorwaarde te filteren. Laten we bijvoorbeeld alle werknemers selecteren die op de afdeling “IT” werken (de ID=3):

SELECTEER ID,Achternaam,Voornaam,Salaris VAN Werknemers WAAR AfdelingID=3 -- IT ORDER OP Achternaam,Voornaam

Identiteitskaart Achternaam Voornaam Salaris
1004 NUL NUL 1500
1003 Andrejev Andrej 2000
1001 Petrov Petrus 1500

De WHERE-clausule wordt vóór het ORDER BY-commando geschreven.

De volgorde waarin de opdrachten worden toegepast op de initiële set Werknemers is als volgt:

  1. WAAR – indien opgegeven, is de eerste stap uit de gehele set Werknemers het selecteren van alleen records die aan de voorwaarde voldoen
  2. DISTINCT – indien gespecificeerd, worden alle duplicaten verwijderd
  3. ORDER BY – indien opgegeven, wordt het resultaat gesorteerd
  4. TOP – indien opgegeven, wordt alleen het opgegeven aantal records geretourneerd uit het gesorteerde resultaat

Laten we voor de duidelijkheid een voorbeeld bekijken:

SELECTEER DISTINCT TOP 1 Salaris VAN Werknemers WAAR AfdelingID=3 ORDER OP Salaris

Visueel zal het er als volgt uitzien:

Het is vermeldenswaard dat het controleren op NULL niet gebeurt met een gelijkteken, maar met behulp van de operatoren IS NULL en IS NOT NULL. Houd er rekening mee dat u niet kunt vergelijken op NULL met behulp van de operator “=” (gelijkteken), omdat het resultaat van de expressie zal ook gelijk zijn aan NULL.

Laten we bijvoorbeeld alle werknemers selecteren waarvoor geen afdeling is opgegeven (d.w.z. AfdelingID IS NULL):

SELECTEER ID,Naam VAN Werknemers WAAR AfdelingID NULL IS

Laten we nu als voorbeeld de bonus berekenen voor alle werknemers waarvoor de BonusPercent-waarde is opgegeven (d.w.z. BonusPercent IS NIET NULL):

SELECTEER ID,Naam,Salaris/100*BonusPercent ALS Bonus VAN Werknemers WAAR BonusPercent NIET NULL IS

Ja, als je erover nadenkt, kan de waarde van BonusPercent gelijk zijn aan nul (0), en de waarde kan ook worden ingevoerd met een minteken, omdat we geen beperkingen hebben opgelegd aan dit veld.

Nu we over het probleem hadden verteld, kregen we te horen dat we er voorlopig over moesten nadenken of (BonusPercent<=0 или BonusPercent IS NULL), то это означает что у сотрудника так же нет бонуса. Для начала, как нам сказали, так и сделаем, реализуем это при помощи логического оператора OR и NOT:

SELECTEER ID,Naam,Salaris/100*BonusPercent ALS Bonus VAN Werknemers WAAR NIET(BonusPercent<=0 OR BonusPercent IS NULL)

Die. Dit is waar we begonnen te leren over Booleaanse operatoren. De uitdrukking tussen haakjes “(BonusPercent<=0 OR BonusPercent IS NULL)» проверяет на то что у сотрудника нет бонуса, а NOT инвертирует это значение, т.е. говорит «верни всех сотрудников которые не сотрудники у которых нет бонуса».

Deze uitdrukking kan ook herschreven worden door onmiddellijk te zeggen “geef alle werknemers terug die een bonus hebben” door dit uit te drukken met de uitdrukking (BonusPercent>0 en BonusPercent IS NOT NULL):

SELECTEER ID,Naam,Salaris/100*BonusPercent ALS Bonus VAN Werknemers WAAR BonusPercent>0 EN BonusPercent NIET NULL IS

Ook in het WHERE-blok kun je verschillende soorten expressies controleren met behulp van rekenkundige operatoren en functies. Een soortgelijke controle kan bijvoorbeeld worden uitgevoerd met behulp van een expressie met de functie ISNULL:

SELECTEER ID,Naam,Salaris/100*BonusPercent ALS Bonus VAN Werknemers WAAR IS NIET VOLLEDIG(BonusPercent,0)>0

Booleaanse operatoren en eenvoudige vergelijkingsoperatoren

Ja, we kunnen hier niet zonder wiskunde, dus laten we een korte excursie maken naar Booleaanse en eenvoudige vergelijkingsoperatoren.

Er zijn slechts 3 Booleaanse operatoren in SQL - AND, OR en NOT:

Voor elke Booleaanse operator kunt u waarheidstabellen opgeven die bovendien laten zien wat het resultaat zal zijn als de voorwaarden NULL kunnen zijn:

Er zijn de volgende eenvoudige operatoren vergelijkingen die worden gebruikt om voorwaarden te vormen:

Bovendien zijn er 2 operatoren voor het controleren van een waarde/expressie voor NULL:

IS NUL Testen op NULL-gelijkheid
IS NIET NUL Testen op NULL-ongelijkheid

Prioriteit: 1) Alle vergelijkingsoperatoren; 2) NIET; 3) EN; 4) OF.

Bij het bouwen van complexe logische uitdrukkingen haakjes worden gebruikt:

((voorwaarde1 EN voorwaarde2) OF NIET(voorwaarde3 EN voorwaarde4 EN voorwaarde5)) OF (…)

Door haakjes te gebruiken, kunt u ook de standaardvolgorde van berekeningen wijzigen.

Hier probeerde ik een idee te geven van de Booleaanse algebra in een volume dat voldoende was voor werk. Zoals je kunt zien, kun je niet zonder logica om complexere voorwaarden te schrijven, maar er is hier niet veel van (EN, OF en NIET) en het is door mensen uitgevonden, dus alles is redelijk logisch.

Laten we naar het einde van het tweede deel gaan

Zoals je kunt zien, kunnen we zelfs over de basissyntaxis van de SELECT-operator heel lang praten, maar om binnen de reikwijdte van het artikel te blijven, zal ik eindelijk aanvullende logische operatoren laten zien - BETWEEN, IN en LIKE.

BETWEEN – controleren op opname in een bereik

Testwaarde TUSSEN startwaarde EN eindwaarde

Uitdrukkingen kunnen als waarden fungeren.

Laten we eens kijken naar een voorbeeld:

SELECTEER ID,Naam,Salaris VAN Werknemers WAAR Salaris TUSSEN 2000 EN 3000 -- die een salaris heeft tussen 2000 en 3000

Eigenlijk is BETWEEN een vereenvoudigde notatie van de vorm:

SELECTEER ID,Naam,Salaris VAN Werknemers WAAR Salaris>=2000 EN Salaris<=3000 -- все у кого ЗП в диапозоне 2000-3000

Het woord NOT kan vóór het woord BETWEEN worden gebruikt, waarmee wordt gecontroleerd of de waarde niet binnen het opgegeven bereik ligt:

SELECTEER ID,Naam,Salaris VAN Werknemers WAAR Salaris NIET TUSSEN 2000 EN 3000 -- vergelijkbaar met NOT(Salaris>=2000 EN Salaris<=3000)

Als u BETWEEN, IN, LIKE gebruikt, kunt u ze dus ook combineren met andere voorwaarden met AND en OR:

SELECT ID,Name,Salaris FROM Werknemers WHERE Salaris TUSSEN 2000 EN 3000 -- die een salaris heeft tussen 2000 en 3000 EN AfdelingID=3 -- houd alleen rekening met medewerkers van afdeling 3

IN – controleer op opname in de lijst met waarden

Deze operator heeft de volgende vorm:

Test_waarde IN (waarde1, waarde2, ...)

Ik denk dat het makkelijker is om aan te tonen met een voorbeeld:

SELECTEER ID,Naam,Salaris VAN Werknemers WHERE PositionID IN(3,4) -- waarvan de positie 3 of 4 is

Die. dit is in wezen hetzelfde als de volgende uitdrukking:

SELECTEER ID,Naam,Salaris VAN Werknemers WHERE PositionID=3 OF PositionID=4 -- waarvan de positie 3 of 4 is

In het geval van NIET zal het vergelijkbaar zijn (we krijgen iedereen behalve die van afdeling 3 en 4):

SELECTEER ID,Naam,Salaris VAN Werknemers WAAR PositieID NIET IN(3,4) -- vergelijkbaar met NOT(PositieID=3 OF PositieID=4)

Een zoekopdracht met NOT IN kan ook worden uitgedrukt met AND:

SELECTEER ID,Naam,Salaris VAN Werknemers WAAR PositieID<>3AND PositieID<>4 -- gelijk aan PositieID NOT IN(3,4)

Houd er rekening mee dat het zoeken naar NULL-waarden met behulp van de IN-constructie niet zal werken, omdat het controleren van NULL=NULL zal ook NULL retourneren, niet waar:

SELECT ID,Name,DepartmentID FROM Employees WHERE DepartmentID IN(1,2,NULL) -- NULL-records worden niet opgenomen in het resultaat

In dit geval verdeelt u de cheque in verschillende voorwaarden:

SELECTEER ID,Naam,AfdelingID VAN Werknemers WAAR AfdelingID IN(1,2) -- 1 of 2 OF AfdelingID IS NULL -- of NULL

Of je kunt iets schrijven als:

SELECT ID,Name,DepartmentID FROM Employees WHERE ISNULL(AfdelingsID,-1) IN(1,2,-1) -- als u zeker weet dat er geen afdeling is met ID=-1

Ik denk dat de eerste optie in dit geval correcter en betrouwbaarder zal zijn. Oké, dit is slechts een voorbeeld om te demonstreren welke andere structuren kunnen worden gebouwd.

Het is ook de moeite waard om een ​​nog verraderlijkere fout te vermelden die verband houdt met NULL en die kan worden gemaakt bij gebruik van de NOT IN-constructie. Laten we bijvoorbeeld proberen alle medewerkers te selecteren, behalve degenen waarvan de afdeling 1 is of wiens afdeling helemaal niet is opgegeven, d.w.z. is gelijk aan NULL. Als oplossing doet zich de volgende optie voor:

SELECTEER ID,Naam,AfdelingsID VAN Werknemers WAAR AfdelingsID NIET IN(1,NULL)

Maar na het uitvoeren van de query ontvangen we geen enkele rij, hoewel we het volgende verwachtten:

Nogmaals, de grap werd hier gespeeld door NULL gespecificeerd in de lijst met waarden.

Laten we eens kijken waarom er in dit geval een logische fout is opgetreden. Laten we de query uitbreiden met AND:

SELECTEER ID,Naam,AfdelingsID VAN Medewerkers WAAR AfdelingsID<>1 AND AfdelingID<>NULL - het probleem wordt veroorzaakt door deze NULL-controle - deze voorwaarde retourneert altijd NULL

Juiste staat (AfdelingID<>NULL) zal ons hier altijd onzekerheid geven, d.w.z. NUL. Onthoud nu de waarheidstabel voor de AND-operator, waarbij (TRUE AND NULL) NULL oplevert. Die. wanneer aan de linkervoorwaarde is voldaan (DepartmentID<>1) vanwege een ongedefinieerde juiste voorwaarde zullen we eindigen met een ongedefinieerde waarde voor de gehele expressie (DepartmentID<>1 AND AfdelingID<>NULL), zodat de string niet in het resultaat wordt opgenomen.

De voorwaarde kan als volgt correct worden herschreven:

SELECTEER ID,Naam,AfdelingsID VAN Werknemers WAAR AfdelingsID NIET IN(1) - of in dit geval alleen AfdelingsID<>1 AND DepartmentID IS NOT NULL - en controleer afzonderlijk op NOT NULL

IN kan ook worden gebruikt met subquery's, maar we komen op dit formulier terug in de volgende delen van deze tutorial.

LIKE – een string controleren met behulp van een patroon

Ik zal alleen over deze operator praten in zijn eenvoudigste vorm, die een standaard is en wordt ondersteund door de meeste dialecten van de SQL-taal. Zelfs in deze vorm kan het worden gebruikt om veel problemen op te lossen waarbij de inhoud van een string moet worden gecontroleerd.

Deze operator heeft de volgende vorm:

Test_string LIKE string_pattern

Het volgende kan worden gebruikt in “template_string”: speciale karakters:

  1. Het onderstrepingsteken “_” betekent dat elk afzonderlijk teken zijn plaats kan innemen
  2. Het procentteken “%” - geeft aan dat het kan worden vervangen door een willekeurig aantal tekens, inclusief geen
Laten we naar voorbeelden kijken met het symbool "%" (in de praktijk wordt het overigens vaker gebruikt):

SELECT ID,Name FROM Werknemers WHERE Naam LIKE "Pet%" -- waarvan de naam begint met de letters "Pet" SELECT ID,Achternaam FROM Werknemers WHERE Achternaam LIKE "%ov" -- waarvan de achternaam eindigt met "ov" SELECT ID, Achternaam FROM Werknemers WHERE Achternaam LIKE "%re%" -- waarvan de achternaam de combinatie "re" bevat

Laten we voorbeelden bekijken met het symbool “_”:

SELECT ID,Achternaam FROM Werknemers WHERE Achternaam LIKE "_etrov" -- waarvan de achternaam bestaat uit een willekeurig eerste teken en de daaropvolgende letters "etrov" SELECT ID,Achternaam FROM Werknemers WHERE Achternaam LIKE "____ov" -- waarvan de achternaam uit vier willekeurige tekens bestaat en daaropvolgende letters "ov"

Met ESCAPE kunt u een escape-teken opgeven dat het controle-effect van de speciale tekens "_" en "%" annuleert. Deze clausule wordt gebruikt als u rechtstreeks wilt controleren op een procentteken of een onderstrepingsteken in een tekenreeks.

Om ESCAPE te demonstreren, laten we afval in één item plaatsen:

UPDATE Medewerkers SET FirstName="Dit is de prullenbak met %" WHERE ID=1005

En laten we eens kijken wat de volgende zoekopdrachten opleveren:

SELECTEER * VAN Medewerkers WAAR Voornaam ZOALS "%!%%" ESCAPE "!" -- regel bevat "%" teken SELECT * FROM Werknemers WAAR Voornaam LIKE "%!_%" ESCAPE "!" --regel bevat een "_"-teken

Als je een string moet controleren op een volledige match, dan is het beter om in plaats van LIKE simpelweg het “=” teken te gebruiken:

SELECT * FROM Medewerkers WAAR Voornaam="Peter"

Even een opmerking.
In MS SQL kunt u in de LIKE-operatorsjabloon ook een zoekopdracht opgeven met behulp van reguliere expressies; lees hierover op internet als de standaardmogelijkheden van deze operator niet voldoende voor u zijn.

ORACLE gebruikt de functie REGEXP_LIKE om te zoeken met reguliere expressies.

Iets over snaren

Als u een string controleert op de aanwezigheid van Unicode-tekens, moet u het teken N vóór de aanhalingstekens plaatsen, d.w.z. N"…". Maar aangezien alle tekenvelden in onze tabel in Unicode-formaat (nvarchar-type) zijn, kunt u dit formaat altijd voor deze velden gebruiken. Voorbeeld:

SELECT ID,Name FROM Werknemers WHERE Naam LIKE N"Huisdier%" SELECT ID,Achternaam FROM Werknemers WHERE LastName=N"Petrov"

Als u dit correct doet, moet u bij het vergelijken met een veld van het type varchar (ASCII) proberen tests te gebruiken met "...", en wanneer u een veld vergelijkt met het type nvarchar (Unicode), moet u proberen tests te gebruiken met N" ...". Dit wordt gedaan om impliciete typeconversies tijdens het uitvoeren van query's te voorkomen. We gebruiken dezelfde regel bij het invoegen van (INSERT) waarden in een veld of het bijwerken ervan (UPDATE).

Bij het vergelijken van tekenreeksen is het de moeite waard om rekening te houden met het punt dat, afhankelijk van de database-instellingen (collatie), tekenreeksvergelijking hoofdlettergevoelig kan zijn (wanneer "Petrov" = "PETROV") of hoofdlettergevoelig kan zijn (wanneer "Petrov"<>"PETROV").
Als u in het geval van een hoofdlettergevoelige instelling een hoofdletterongevoelige zoekopdracht wilt uitvoeren, kunt u bijvoorbeeld de rechter- en linkerexpressies vooraf converteren naar één hoofdletter: hoger of lager:

SELECT ID,Name FROM Werknemers WHERE UPPER(Naam) LIKE UPPER(N"Huisdier%") -- of LOWER(Name) LIKE LOWER(N"Huisdier%") SELECT ID,LastName FROM Werknemers WHERE UPPER(Achternaam)=UPPER( N"Petrov") -- of LOWER(Achternaam)=LOWER(N"Petrov")

Een beetje over data

Bij het controleren op een datum kunt u, net als bij strings, enkele aanhalingstekens "..." gebruiken.

Ongeacht de regionale instellingen in MS SQL kunt u de volgende datumsyntaxis "JJJJMMDD" gebruiken (jaar, maand, dag samen zonder spaties). MS SQL zal dit datumformaat altijd begrijpen:

SELECTEER ID,Naam,Verjaardag VAN Werknemers WAAR Verjaardag TUSSEN "19800101" EN "19891231" -- werknemers uit de jaren 80 BESTEL OP Verjaardag

In sommige gevallen is het handiger om de datum in te stellen met behulp van de DATEFROMPARTS-functie:

SELECTEER ID,Naam,Verjaardag VAN Medewerkers WAAR Verjaardag TUSSEN DATEFROMPARTS(1980,1,1) EN DATEFROMPARTS(1989,12,31) ORDER OP Verjaardag

Er is ook een soortgelijke functie DATETIMEFROMPARTS, die wordt gebruikt om de datum en tijd in te stellen (voor het datetime-type).

U kunt ook de functie CONVERT gebruiken als u een tekenreeks naar een datum- of datetime-waarde moet converteren:

SELECTEER CONVERTEREN(datum,"12.03.2015",104), CONVERTEREN(datumtijd,"2014-11-30 17:20:15",120)

De waarden 104 en 120 geven aan welk datumformaat in de string wordt gebruikt. Een beschrijving van alle geldige formaten vindt u in de MSDN-bibliotheek door te zoeken naar “MS SQL CONVERT”.

Er zijn veel functies voor het werken met datums in MS SQL, zoek naar “ms sql-functies voor het werken met datums.”

Opmerking. Alle dialecten van de SQL-taal hebben hun eigen reeks functies voor het werken met datums en passen hun eigen benadering toe om ermee te werken.

Iets over getallen en hun transformaties

De informatie in dit gedeelte zal waarschijnlijk nuttiger zijn voor IT-specialisten. Als u niet zo bent en uw doel eenvoudigweg is om te leren hoe u zoekopdrachten schrijft om de informatie te verkrijgen die u nodig heeft uit de database, dan heeft u dergelijke subtiliteiten misschien niet nodig, maar u kunt in ieder geval snel door de tekst gaan en aantekeningen maken. , omdat . Als je SQL bent gaan studeren, dan studeer je al in de IT.

In tegenstelling tot de CAST-conversiefunctie kan de CONVERT-functie een derde parameter specificeren, die verantwoordelijk is voor de conversiestijl (formaat). Verschillende gegevenstypen kunnen hun eigen set stijlen hebben, wat van invloed kan zijn op het geretourneerde resultaat. We hebben het gebruik van stijlen al besproken bij het overwegen van de conversie van een string met behulp van de CONVERT-functie naar de datum- en datetime-typen.

U kunt meer lezen over de CAST-, CONVERT-functies en -stijlen in MSDN - "CAST and CONVERT Functions (Transact-SQL)": msdn.microsoft.com/ru-ru/library/ms187928.aspx

Om de voorbeelden te vereenvoudigen, zullen hier de Transact-SQL-taalinstructies DECLARE en SET worden gebruikt.

In het geval van het converteren van een geheel getal naar een reëel getal (wat ik aan het begin van deze les gaf om het verschil tussen een geheel getal en een reële deling aan te tonen), is kennis van de nuances van de conversie natuurlijk niet zo cruciaal. omdat daar hebben we een conversie van geheel getal naar reëel uitgevoerd (waarvan het bereik veel groter is dan het bereik van gehele getallen):

DECLARE @min_int int SET @min_int=-2147483648 DECLARE @max_int int SET @max_int=2147483647 SELECTEER -- (-2147483648) @min_int,CAST(@min_int AS float),CONVERT(float,@min_int), -- 2147483647 @max_int ,CAST(@max_int AS float),CONVERT(float,@max_int), -- numeriek(16,6) @min_int/1., -- (-2147483648.000000) @max_int/1. -- 2147483647.000000

Misschien was het niet de moeite waard om de methode van de impliciete conversie te specificeren die werd verkregen door te delen door (1.), omdat Het is raadzaam om expliciete conversies uit te voeren voor meer controle over het type resultaat dat wordt verkregen. Hoewel, als we een resultaat van het type numeriek willen krijgen, met een bepaald aantal cijfers achter de komma, we een truc in MS SQL kunnen gebruiken om een ​​geheel getal te vermenigvuldigen met (1., 1.0, 1.00, etc.) :

DECLARE @int int SET @int=123 SELECT @int*1., -- numeriek(12, 0) - 0 decimalen @int*1.0, -- numeriek(13, 1) - 1 decimalen @int*1.00, -- numeriek(14, 2) - 2 tekens -- hoewel het soms beter is om een ​​expliciete conversie uit te voeren CAST(@int AS numeriek(20, 0)), -- 123 CAST(@int AS numeriek(20, 1) ), -- 123,0 CAST(@int AS numeriek(20, 2)) -- 123,00

In sommige gevallen kunnen de details van de conversie erg belangrijk zijn, omdat... ze beïnvloeden de juistheid van het verkregen resultaat, bijvoorbeeld in het geval dat er een conversie wordt gemaakt van een numerieke waarde naar een string (varchar). Laten we eens kijken naar voorbeelden van het omzetten van geld en float-waarden naar varchar:

Gedrag bij het omzetten van geld naar varchar DECLARE @money money SET @money = 1025.123456789 -- er zal een impliciete conversie naar 1025.1235 plaatsvinden, omdat het geldtype slaat slechts 4 cijfers achter de komma op. SELECT @money, -- 1025,1235 -- standaard gedragen CAST en CONVERT zich hetzelfde (d.w.z. grofweg wordt stijl 0 toegepast) CAST(@money als varchar(20)) , -- 1025.12 CONVERT(varchar(20), @money), -- 1025.12 CONVERT(varchar(20), @money, 0), -- 1025.12 (stijl 0 - geen scheidingsteken voor duizendsten en 2 decimalen (standaardnotatie)) CONVERT( varchar(20), @money, 1), -- 1.025.12 (stijl 1 - gebruikt een scheidingsteken voor duizendsten en 2 decimalen) CONVERT(varchar(20), @money, 2) -- 1025.1235 (stijl 2 - geen scheidingsteken en 4 cijfers achter de komma)

Gedrag bij het converteren van float naar varchar DECLARE @float1 float SET @float1 = 1025.123456789 DECLARE @float2 float SET @float2 = 1231025.123456789 SELECT @float1, -- 1025.123456789 @float2, -- 1231025 .12345679 -- Standaard CAST en CONVERT gedragen zich hetzelfde (dat wil zeggen dat grofweg stijl 0 wordt gebruikt) -- stijl 0 - Niet meer dan 6 cijfers. Exponentiële notatie wordt uit noodzaak gebruikt -- er gebeuren hier echt enge dingen bij het converteren naar varchar CAST(@float1 als varchar(20)), -- 1025.12 CONVERT(varchar(20), @float1), -- 1025.12 CONVERT(varchar( 20 ), @float1, 0), -- 1025.12 CAST(@float2 als varchar(20)), -- 1.23103e+006 CONVERTEREN(varchar(20), @float2), -- 1.23103e+006 CONVERTEREN(varchar( 20 ), @float2, 0), -- 1.23103e+006 -- stijl 1 - Altijd 8 cijfers. Er wordt altijd gebruik gemaakt van de wetenschappelijke notatie voor getallen.

Zoals uit het voorbeeld blijkt, zweven zwevende typen, real kan in sommige gevallen zelfs een grote fout veroorzaken, vooral wanneer deze wordt geconverteerd naar een string en terug (dit kan gebeuren bij verschillende soorten integraties, wanneer gegevens bijvoorbeeld worden overgedragen in tekstbestanden van het ene systeem naar het andere).

Als u de nauwkeurigheid tot een bepaald teken, meer dan 4, expliciet wilt regelen, is het soms beter om het decimale/numerieke type te gebruiken om gegevens op te slaan. Als 4 tekens voldoende zijn, kunt u het geldtype gebruiken - dit komt ongeveer overeen met numeriek(20,4).

Decimaal en numeriek DECLARE @money money SET @money = 1025.123456789 -- 1025.1235 DECLARE @float1 float SET @float1 = 1025.123456789 DECLARE @float2 float SET @float2 = 1231025.123456789 DECLARE @numer ic numeriek(28,9) SET @numeriek = 1025.123456789 SELECTEER CAST ( @numeriek als varchar(20)), -- 1025.12345679 CONVERT(varchar(20), @numeriek), -- 1025.12345679 CAST(@geld als numeriek(28,9)), -- 1025.123500000 CAST(@float1 als numeriek( 28 ,9)), -- 1025.123456789 CAST(@float2 als numeriek(28,9)) -- 1231025.123456789

Opmerking.
Vanaf versie MS SQL 2008 kunt u in plaats daarvan de volgende constructie gebruiken:
  • ms sql-server
  • Tags toevoegen

    De basis van de SQL-taal bestaat uit operators, voorwaardelijk verdeeld in verschillende groepen op basis van de functies die ze uitvoeren. De volgende groepen instructies kunnen worden onderscheiden (niet alle SQL-instructies worden vermeld):

    ddl-instructies (Data Definition Language).

    DDL-instructies - definitie-instructies voor databaseobjecten

      CREATE SCHEMA - maak een databaseschema

      DROP SHEMA - verwijder een databaseschema

      MAAK TABEL MAKEN - maak een tabel

      ALTER TABLE - verander de tabel

      DROP TABLE - verwijder een tabel

      DOMEIN MAKEN - maak een domein aan

      WIJZIG DOMEIN - wijzig domein

      DROP DOMAIN - verwijder een domein

      CREËER COLLATIE - maak een reeks

      DROP COLLATION - verwijder een reeks

      CREËER WEERGAVE - maak een weergave

      DROP VIEW - verwijder een weergave

    dml-instructies (Data Manipulation Language).

    DML-instructies - verklaringen voor gegevensmanipulatie

      SELECTEER - selecteer rijen uit tabellen

      INSERT - rijen toevoegen aan de tabel

      UPDATE - wijzig rijen in een tabel

      DELETE - verwijder rijen in de tabel

      COMMIT - doorgevoerde wijzigingen

      ROLLBACK - gemaakte wijzigingen ongedaan maken

    Operators voor gegevensbescherming en -beheer

      CREËER BEWEGING - creëer een beperking

      DROP ASSERTION - verwijder een beperking

      GRANT - verleen rechten aan een gebruiker of applicatie om objecten te manipuleren

      REVOKE - trek gebruikers- of applicatierechten in

    Daarnaast zijn er groepen operators voor het instellen van sessieparameters, het verkrijgen van informatie over de database, statische SQL-operators en dynamische SQL-operators. Het belangrijkste voor de gebruiker zijn gegevensmanipulatieverklaringen (DML).

    Voorbeelden van het gebruik van operatoren voor gegevensmanipulatie

    INSERT - rijen in een tabel invoegen

    Voorbeeld 1 . Eén rij in een tabel invoegen:

    WAARDEN(4, "Ivanov");

    Voorbeeld 2 . In een tabel meerdere rijen invoegen die uit een andere tabel zijn geselecteerd (gegevens over leveranciers uit de P-tabel met getallen groter dan 2 worden ingevoegd in de TMP_TABLE-tabel):

    TMP_TABLE (PNUM, PNAME)

    SELECTEER PNUM, PNAME

    WAAR P.PNUM>2;

    UPDATE - rijen in een tabel bijwerken

    Voorbeeld 3 . Meerdere rijen in een tabel bijwerken:

    SET PNAME = "Poesjnikov"

    WAAR P.PNUM = 1;

    DELETE - rijen in een tabel verwijderen

    Voorbeeld 4 . Meerdere rijen in een tabel verwijderen:

    WAAR P.PNUM = 1;

    Voorbeeld 5 . Alle rijen in een tabel verwijderen:

    Voorbeelden van het gebruik van de SELECT-instructie

    De SELECT-instructie is feitelijk de meest gebruikerskritische en meest complexe SQL-instructie. Het is bedoeld voor het ophalen van gegevens uit tabellen, d.w.z. het implementeert in feite een van de hoofddoelen van de database: het verstrekken van informatie aan de gebruiker.

    De SELECT-instructie wordt altijd uitgevoerd op sommige tabellen die deel uitmaken van de database.

    Opmerking. In feite kunnen databases niet alleen permanent opgeslagen tabellen bevatten, maar ook tijdelijke tabellen en zogenaamde views. Weergaven zijn eenvoudigweg SELECT-expressies die in de database zijn opgeslagen. Vanuit het oogpunt van de gebruiker is een weergave een tabel die niet permanent in de database is opgeslagen, maar "verschijnt" wanneer deze wordt geopend. Vanuit het oogpunt van de SELECT-instructie zien zowel persistente tabellen als tijdelijke tabellen en views er precies hetzelfde uit. Wanneer het systeem daadwerkelijk een SELECT-instructie uitvoert, wordt er uiteraard rekening gehouden met de verschillen tussen opgeslagen tabellen en views, maar deze verschillen verborgen van de gebruiker.

    Het resultaat van een SELECT-instructie is altijd een tabel. De resultaten van de SELECT-instructie zijn dus vergelijkbaar met de operatoren van relationele algebra. Elke relationele algebra-operator kan worden uitgedrukt door een passend geformuleerde SELECT-instructie. De complexiteit van de SELECT-instructie wordt bepaald door het feit dat deze alle mogelijkheden van relationele algebra bevat, evenals aanvullende mogelijkheden die niet aanwezig zijn in relationele algebra.

    Basis SQL-instructies. Syntaxis en voorbeelden van het gebruik van de SELECT-instructie.

    De basis van de SQL-taal bestaat uit operators, voorwaardelijk verdeeld in verschillende groepen op basis van de functies die ze uitvoeren.

    De volgende groepen operators kunnen worden onderscheiden (niet alle SQL-operators worden vermeld):

    DDL-instructies (Data Definition Language) - instructies voor het definiëren van databaseobjecten

    · CREATE SCHEMA - maak een databaseschema

    · DROP SHEMA - verwijder een databaseschema

    · MAAK TAFEL - maak een tabel

    ALTER TABLE - verander de tabel

    · DROP TABLE - verwijder een tabel

    · DOMEIN MAKEN - maak een domein aan

    WIJZIG DOMEIN - wijzig domein

    · DROP DOMAIN - verwijder een domein

    · CREËER COLLATIE - maak een reeks

    · DROP COLLATION - verwijder een reeks

    · CREËER WEERGAVE - maak een weergave

    · DROP VIEW - verwijder een weergave

    DML-operatoren (Data Manipulation Language) - operators voor gegevensmanipulatie

    · SELECTEER - selecteer rijen uit tabellen

    · INSERT - rijen aan de tabel toevoegen

    · UPDATE - wijzig rijen in de tabel

    · DELETE - verwijder rijen in de tabel

    · COMMIT - doorgevoerde wijzigingen

    · ROLLBACK - gemaakte wijzigingen ongedaan maken

    Operators voor gegevensbescherming en -beheer

    · CREËER BEWEGING - creëer een beperking

    · DROP ASSERTION - verwijder een beperking

    · GRANT - geef rechten aan een gebruiker of applicatie om objecten te manipuleren

    REVOKE - trek gebruikers- of applicatierechten in

    Tegelijkertijd zijn er groepen operators voor het instellen van sessieparameters, het verkrijgen van informatie over de database, statische SQL-operators en dynamische SQL-operators.

    Het belangrijkste voor de gebruiker zijn gegevensmanipulatieverklaringen (DML).

    Voorbeelden van het gebruik van operatoren voor gegevensmanipulatie

    INSERT - rijen in een tabel invoegen

    Voorbeeld 1. Eén rij in een tabel invoegen:

    WAARDEN(4, "Ivanov");

    UPDATE - rijen in een tabel bijwerken

    Voorbeeld 3. Meerdere rijen in een tabel bijwerken:

    SET PNAME = "Poesjnikov"

    WAAR P.PNUM = 1;

    DELETE - rijen in een tabel verwijderen

    Voorbeeld 4. Meerdere rijen in een tabel verwijderen:

    WAAR P.PNUM = 1;

    Voorbeelden van het gebruik van de SELECT-instructie

    De SELECT-instructie is feitelijk de meest gebruikerskritische en meest complexe SQL-instructie. Het is ontworpen om gegevens uit tabellen op te halen, ᴛ.ᴇ. het implementeert in feite een van de basisdoelen van de database: het verstrekken van informatie aan de gebruiker.

    De SELECT-instructie wordt altijd uitgevoerd op sommige tabellen die deel uitmaken van de database.

    Opmerking. In databases zijn er namelijk niet alleen permanent opgeslagen tabellen, maar ook tijdelijke tabellen en zogenaamde views. Weergaven zijn eenvoudigweg SELECT-expressies die in de database zijn opgeslagen. Vanuit het oogpunt van de gebruiker is een weergave een tabel die niet permanent in de database is opgeslagen, maar "verschijnt" wanneer deze wordt geopend. Vanuit het oogpunt van de SELECT-instructie zien zowel persistente tabellen als tijdelijke tabellen en views er precies hetzelfde uit. Wanneer het systeem daadwerkelijk een SELECT-instructie uitvoert, wordt er uiteraard rekening gehouden met de verschillen tussen opgeslagen tabellen en views, maar deze verschillen verborgen van de gebruiker.

    Het resultaat van een SELECT-instructie is altijd een tabel. Op basis van de resultaten van zijn acties is de SELECT-instructie echter vergelijkbaar met de operators van relationele algebra. Elke relationele algebra-operator moet worden uitgedrukt door een passend geformuleerde SELECT-instructie. De complexiteit van de SELECT-instructie wordt bepaald door het feit dat deze alle mogelijkheden van relationele algebra bevat, evenals aanvullende mogelijkheden die niet aanwezig zijn in relationele algebra.

    SELECT Uitvoeringsopdracht verklaring

    Om te begrijpen hoe het resultaat van het uitvoeren van een SELECT-instructie wordt verkregen, kunt u het conceptuele diagram van de uitvoering ervan bekijken. Dit schema is puur conceptueel, omdat het is gegarandeerd dat het resultaat hetzelfde zal zijn alsof het stap voor stap volgens dit schema zou worden uitgevoerd. In feite wordt het daadwerkelijke resultaat verkregen door meer geavanceerde algoritmen die een bepaald DBMS ‘bezit’.

    Fase 1: Een enkele SELECT-instructie uitvoeren

    Als de operator de trefwoorden UNION, EXCEPT en INTERSECT bevat, wordt de zoekopdracht opgedeeld in verschillende onafhankelijke zoekopdrachten, die elk afzonderlijk worden uitgevoerd:

    Stap 1 (VANAF). Het directe cartesiaanse product van alle tabellen die zijn opgegeven in de verplichte FROM-sectie wordt berekend. Als resultaat van stap 1 verkrijgen we tabel A.

    Stap 2 (WAAR). Als de SELECT-instructie een WHERE-clausule bevat, wordt tabel A, verkregen in stap 1, gescand. In dit geval wordt voor elke rij uit tabel A de voorwaardelijke expressie berekend die in de WHERE-clausule is opgegeven. Alleen de rijen waarvoor de voorwaardelijke expressie TRUE retourneert, worden in het resultaat opgenomen. Als de WHERE-sectie wordt weggelaten, ga dan onmiddellijk verder met stap 3. Als er geneste subquery's bij de voorwaardelijke expressie betrokken zijn, worden deze berekend in overeenstemming met dit conceptuele schema. Als resultaat van stap 2 verkrijgen we tabel B.

    Stap 3 (GROEPEREN OP). Als de SELECT-instructie een GROUP BY-sectie bevat, worden de rijen van tabel B die in de tweede stap zijn verkregen, gegroepeerd in overeenstemming met de groeperingslijst in de GROUP BY-sectie. Als de sectie GROUP BY wordt weggelaten, ga dan onmiddellijk verder met stap 4. Als resultaat van stap 3 verkrijgen we tabel C.

    Stap 4 (HEBBEN). Als de SELECT-instructie een HAVING-sectie bevat, worden groepen uitgesloten die niet voldoen aan de voorwaardelijke expressie die in de HAVING-sectie is gegeven. Als de HAVING-sectie wordt weggelaten, ga dan onmiddellijk verder met stap 5. Als resultaat van stap 4 verkrijgen we tabel D.

    Stap 5 (SELECTIE). Elke groep verkregen in stap 4 genereert als volgt één resultaatrij. Alle scalaire expressies die zijn opgegeven in de sectie SELECT worden geëvalueerd. Volgens de regels voor het gebruik van de GROUP BY-clausule moeten dergelijke scalaire expressies hetzelfde zijn voor alle rijen binnen elke groep. Voor elke groep worden de waarden van de aggregatiefuncties in de sectie SELECT berekend. Als er geen GROUP BY-sectie is, maar er wel aggregatiefuncties zijn in de SELECT-sectie, wordt ervan uitgegaan dat er slechts één groep is. Als er geen GROUP BY-sectie of aggregatiefuncties zijn, wordt ervan uitgegaan dat er op dit moment net zoveel groepen zijn als er rijen zijn geselecteerd. Als resultaat van stap 5 verkrijgen we tabel E, die evenveel kolommen bevat als er elementen zijn vermeld in de sectie SELECT en evenveel rijen als er groepen zijn geselecteerd.

    Fase 2. Uitvoeren van UNION, EXCEPT, INTERSECT-bewerkingen

    Als de SELECT-instructie de trefwoorden UNION, EXCEPT en INTERSECT bevatte, worden de tabellen verkregen als resultaat van de eerste fase samengevoegd, afgetrokken of doorsneden.

    Fase 3. Het resultaat bestellen

    Als de SELECT-instructie een ORDER BY-sectie bevat, worden de rijen van de tabel die in de voorgaande stappen zijn verkregen, geordend in overeenstemming met de bestellijst in de ORDER BY-sectie.

    Basis SQL-instructies. Syntaxis en voorbeelden van het gebruik van de SELECT-instructie. - concept en typen. Classificatie en kenmerken van de categorie "Basis SQL-operatoren. Syntaxis en voorbeelden van het gebruik van de SELECT-operator." 2017, 2018.

    De syntaxis van de SELECT-instructie is als volgt:

    SELECTEER<список атрибутов>/* VAN<список таблиц>

    Vierkante haken geven elementen aan die mogelijk niet aanwezig zijn in het verzoek.

    Maak een lijst van alle studenten.

    SELECTEER * VAN studenten

    SELECT id_st, achternaam VAN leerling

    Merk op dat als we toevoegen aan dit verzoek ORDER BY achternaam-clausule, de lijst wordt geordend op achternaam. Standaard wordt aangenomen dat de sortering in oplopende volgorde plaatsvindt. Als aflopende volgorde gewenst is, wordt het woord DESC toegevoegd na de attribuutnaam.

    Toon een lijst met cijfers die een student heeft ontvangen met code "1".

    Geef een lijst met codes voor studenten die op de examens minimaal één D of C hebben behaald.

    In de WHERE-clausule kunt u een expressie schrijven met behulp van rekenkundige operatoren vergelijkingen (<, >, etc.) en logische operatoren (AND, OR, NOT) zoals in conventionele programmeertalen.

    Samen met vergelijkingsoperatoren en logische operatoren Om voorwaarden te creëren in de SQL-taal (vanwege de specifieke kenmerken van de reikwijdte), zijn er een aantal speciale operators die in de regel geen analogen hebben in andere talen. Dit zijn de exploitanten:

    • IN – toegang tot een bepaalde reeks waarden;
    • BETWEEN – toegang tot een bepaald waardenbereik;
    • LIKE – patroonmatchingstest;
    • IS NULL – controleer op een ongedefinieerde waarde.

    De IN-operator wordt gebruikt om te controleren of een waarde in een set is opgenomen. Ja, verzoek

    geeft hetzelfde resultaat als de bovenstaande zoekopdracht (er worden de identificatiegegevens weergegeven van alle aanvragers die ten minste één D of C hebben behaald in de examens).

    Hetzelfde resultaat kan worden bereikt met de operator BETWEEN:

    Noem alle leerlingen waarvan de achternaam met de letter A begint.

    In dit geval is het handig om de LIKE-operator te gebruiken.

    De LIKE-operator is uitsluitend van toepassing op tekenvelden en stelt u in staat te bepalen of de waarde van een veld overeenkomt met een patroon. Het patroon kan speciale tekens bevatten:

    _ (onderstrepingsteken) – vervangt elk afzonderlijk teken;

    % (procentteken) – vervangt een reeks van een willekeurig aantal tekens.

    Heel vaak is het nodig om de minimum-, maximum- of gemiddelde waarden in kolommen te berekenen. Mogelijk moet u bijvoorbeeld uw GPA berekenen. Om dergelijke berekeningen uit te voeren, biedt SQL speciale geaggregeerde functies:

    • MIN - minimale waarde in kolom;
    • MAXIMUM – maximale waarde in kolom;
    • SOM – som van waarden in de kolom;
    • AVG – gemiddelde waarde in de kolom;
    • COUNT – het aantal niet-NULL-waarden in de kolom.

    Met de volgende query wordt het gemiddelde berekend van alle scores die studenten op examens hebben behaald.

    SELECTEER AVG(mark) VAN mark_st

    Natuurlijk kunt u gebruiken geaggregeerde functies samen met de WHERE-clausule:

    Deze zoekopdracht berekent de gemiddelde score van een student met code 100 op basis van de resultaten van alle examens die hij heeft afgelegd.

    Deze query berekent de gemiddelde score van studenten op basis van de resultaten van het behalen van het examen met code 10. Naast de besproken mechanismen