Lær SQL – En vejledning med kodeeksempler
SQL’s syntaks er baseret på relationsalgebra, hvilket adskiller dette programmeringssprog fra andre sprog. Ved at gøre dig fortrolig med syntaksen gennem praktiske eksempler kan du lære SQL på en effektiv måde.
Hvad er SQL-syntaks?
I programmering henviser syntaks til den måde, et programmeringssprog skrives på. Syntaksen fastlægger de grundlæggende kodekonstruktioner og hvordan de skal sammenkædes. At forstå syntaksen er en grundlæggende forudsætning for at kunne læse og skrive kode i programmeringssprog.
De vigtigste syntakselementer i SQL er SQL-sætninger, som også kan indeholde klausuler. Begge betegnes ofte som »SQL-kommandoer«, selvom dette rent teknisk set ikke er helt korrekt. Det er dog ikke de eneste syntakselementer i SQL. Nedenfor finder du en tabel, der giver dig et overblik over syntakselementerne i SQL.
| SQL-udtryk | Forklaring | Eksempel |
|---|---|---|
| Sætning | Instruerer DBMS om at udføre en handling; slutter med et semikolon | CREATE TABLE People;
|
| Klausul | Modificerer en sætning; kan kun forekomme inden for sætninger | WHERE, HAVING
|
| Udtryk | Returnerer en værdi ved evaluering | 6 * 7
|
| Identifikator | Navn på et databaseobjekt, en variabel eller en procedure; kan være kvalificeret eller ukvalificeret | dbname.tablename / tablename
|
| Prædikat | Udtryk, der evalueres til TRUE, FALSE eller UNKNOWN
|
Age < 42
|
| Forespørgsel | Speciel sætning; returnerer fundne sæt af poster | SELECT Name FROM People WHERE Age < 42;
|
| Funktion | Behandler en eller flere værdier; skaber normalt en ny værdi | UPPER('text') -- returns 'TEXT'
|
| Kommentar | Bruges til at kommentere SQL-kode; ignoreres af RDBMS | -- Comment up to end of line / /*multiline comment if necessary*/
|
SQL-kommandoer som SELECT og CREATE TABLE skrives normalt med store bogstaver. SQL skelner dog ikke mellem store og små bogstaver. Brugen af store bogstaver i kommandoerne er blot en udbredt konvention.
Hvordan udføres SQL-kode?
SQL-kode findes som kildekode i tekstfiler. Koden kommer først til live i et passende kørselsmiljø. Kildekoden læses af en SQL-fortolker og omdannes til handlinger i et RDBMS. Der er to grundlæggende tilgange her:
1. Udfør SQL-kodeinteraktivt I denne fremgangsmåde indtastes eller kopieres SQL-koden direkte ind i et tekstvindue. SQL-koden udføres, og resultatet vises. Du kan justere koden og udføre den igen. Den hurtige afveksling mellem kodemanipulation og visning af resultater gør denne fremgangsmåde særdeles velegnet til at lære og oprette komplekse forespørgsler. 2. Udfør SQL-kode somscript I denne fremgangsmåde udføres en hel kildekodefil, der indeholder SQL-kode, linje for linje. Hvis det er nødvendigt, sendes feedback kun til brugeren ved afslutningen af udførelsen. Denne fremgangsmåde er bedst egnet til automatisering af processer og til import af MySQL-database-backups med MySQL dump.
| Grænseflade | Beskrivelse | Eksempler |
|---|---|---|
| Kommandolinjegrænseflade (CLI) | Tekstbaseret grænseflade; SQL-kode indtastes og udføres, resultatet vises som tekst | mysql, psql, mysqlsh |
| Grafisk brugergrænseflade (GUI) | SQL-kode indtastes i et tekstvindue og/eller genereres som reaktion på brugerinteraktion; SQL-kode udføres, resultatet vises som tabeller | phpMyAdmin, MySQL Workbench, HeidiSQL |
| Applikationsprogrammeringsgrænseflade (API) | Muliggør direkte kommunikation med et RDBMS; SQL-kode indgår og udføres som en streng i programmeringssprogets kode; resultaterne er tilgængelige som datastrukturer til videre brug | PHP Data Objects (PDO), Connector/J (Java), Connector/Python, C API |
Sådan opretter du et produktstyringssystem ved hjælp af SQL
Den nemmeste måde at lære et programmeringssprog på er at skrive og køre koden selv. I denne vejledning skal vi oprette en minidatabase og køre forespørgsler på den. Til det formål bruger vi online-SQL-fortolkeren fra hjemmesiden sql.js. For at følge vejledningen skal du gå ind på hjemmesiden og erstatte den SQL-kode, der allerede er indtastet, med koden fra vores eksempler. Kør koden stykke for stykke for at få resultaterne vist.
Opret en SQL-database
I dette eksempel skal vi udvikle et produktstyringssystem til en butik. Her er kravene:
- Vi har flere forskellige produkter, og vi har et bestemt antal af hvert produkt på lager.
- Vores kundebase omfatter mange kunder.
- Ordrer afgivet af kunder kan indeholde flere produkter.
- For hver ordre gemmer vi ordredatoen og oplysninger om den person, der har afgivet ordren, samt de bestilte produkter og den bestilte mængde.
Disse krav omsættes først til en abstrakt beskrivelse og derefter til SQL-kode:
- Opret model
- Definer skema
- Indtast dataposter
- Definer forespørgsler
Opret en model over enheder og relationer
Det første trin foregår på papir eller ved hjælp af specielle modelleringsværktøjer. Vi indsamler oplysninger om det system, der skal modelleres, for at udlede enheder og relationer. Dette trin udmøntes ofte i et entitet-relationsdiagram (ER-diagram).
Hvilke enheder findes der, og hvordan hænger de sammen? Enheder er kategorier af objekter. I vores eksempel på et produktstyringssystem er enhederne produkter, kunder og ordrer. Der skal oprettes en tabel for hver enhed. På grund af den relationelle models særlige karakteristika tilføjes der yderligere tabeller for at modellere sammenhængene. Det kræver erfaring at forstå dette og implementere det korrekt.
Et centralt spørgsmål, der skal besvares, er, hvordan enhederne forholder sig til hinanden. Her skal vi tage højde for begge retninger i en relation og skelne mellem ental og flertal. Her er et eksempel med biler og bilejere:
- En ejer kan potentielt eje flere biler.
- En bil kan kun tilhøre én ejer.
Der tegner sigtre mulige mønstre for forholdet mellem de to enheder:
| Forhold | Enheder | Fra venstre | Fra højre |
|---|---|---|---|
| 1:1-relation | Auto:indikator | En bil kan kun have én indikator. | En indikator kan kun tilhøre én bil. |
| 1:n-relation | Ejer:bil | En ejer kan potentielt have flere biler. | En bil kan kun tilhøre én ejer. |
| m:n-relation | Bil:gade | En bil kan køre på flere veje. | Flere biler kan køre på én vej. |
Implementere produkter
Først skal vi oprette produkttabellen. For at gøre dette skal vi definere et skema, indtaste dataposter og, med henblik på test, køre et par enkle forespørgsler.
Definer skema
Den centrale SQL-kommando til oprettelse af databasetabeller er CREATE TABLE. Med denne kommando kan du oprette en tabel med et navn og angive kolonneegenskaber. Samtidig defineres datatyper og, hvis nødvendigt, begrænsninger for de værdier, der skal gemmes:
DROP TABLE IF EXISTS Products;
CREATE TABLE Products ( product_id int, product_name text, stocked int, price int );sqlVi bruger en DROP TABLE IF EXISTS-sætning, før vi definerer tabellen. Dette sletter eventuelle eksisterende tabeller og gør det muligt at køre den samme SQL-kode flere gange uden at der vises fejlmeddelelser.
Tilføj datasæt
Nu skal vi oprette et par testposter. Vi bruger SQL-kommandoen INSERT INTO samt funktionen VALUES til at udfylde felterne:
INSERT INTO Products VALUES (10, 'ABC Product', 74, 1050);
INSERT INTO Products VALUES (20, 'KLM Product', 23, 750);
INSERT INTO Products VALUES (30, 'XYZ Product', 104, 350);sqlDefiner forespørgsler
For at se, hvordan det står til med tabellen »Produkter«, skriver vi en simpel forespørgsel. Vi bruger kommandoen SELECT FROM og viser hele tabellen:
SELECT * FROM Products;sqlNu skal vi skrive en lidt mere kompleks forespørgsel, der beregner den samlede værdi af de varer, vi har på lager:
SELECT product_name AS 'Name', (stocked * price) AS 'Value' FROM Products;sqlOpret yderligere tabeller
Nu skal vi oprette de resterende tabeller, vi har brug for. Vi følger de samme trin, som vi brugte til tabellen »Produkter«. Først opretter vi tabellen »Kunder«:
DROP TABLE IF EXISTS Customers;
CREATE TABLE Customers ( customer_id int, customer_name text, contact text );sqlDerefter indtaster vi data for to eksempler på kunder:
INSERT INTO Customers VALUES (100, 'EDC Customer', 'ED@example.com');
INSERT INTO Customers VALUES (200, 'WVU Customer', 'WV@example.com');sqlFor at se, om det virkede, viser vi kundetabellen:
SELECT * FROM Customers;sqlDet næste trin er at oprette tabellen »Orders«:
DROP TABLE IF EXISTS Orders;
CREATE TABLE Orders ( order_id int, customer_id int, order_date text );sqlNu skal vi indtaste tre eksempler på indkøbsordrer. For den første værdi i posterne tildeler vi et ID som primærnøgle. Den anden værdi er eksisterende kunde-ID’er, som fungerer som fremmednøgler. Derefter gemmer vi ordredatoen:
INSERT INTO Orders VALUES (1000, 100, '2022-05-03');
INSERT INTO Orders VALUES (1001, 100, '2022-05-04');
INSERT INTO Orders VALUES (1002, 200, '2022-05-08');sqlFor at teste det vil vi udføre følgende kommandoer:
SELECT * FROM Orders;sqlEndelig har vi brug for en tabel, der indeholder produkterne i en ordre sammen med deres antal. Dette er et m:n-forhold, da en ordre kan indeholde flere produkter, og et produkt kan forekomme i flere ordrer. Vi opretter en tabel, der indeholder ID’erne for ordrer og produkter som fremmednøgler:
DROP TABLE IF EXISTS OrderItems;
CREATE TABLE OrderItems ( orderitem_id int, order_id int, product_id int, count int );sqlNu indtaster vi et par produkter, der er blevet bestilt. Vi vælger ID’erne for ordrerne og produkterne, så der er en ordre med to produkter og en anden ordre med kun ét produkt:
INSERT INTO OrderItems VALUES (10001, 1000, 10, 3);
INSERT INTO OrderItems VALUES (10002, 1000, 20, 2);
INSERT INTO OrderItems VALUES (10003, 1002, 30, 12);sqlFor at kontrollere dette vil vi udlevere de bestilte varer:
SELECT * FROM OrderItems;sqlSkriv komplekse forespørgsler
Hvis du har kørt alle de kodestykker, der er vist indtil nu, bør du kunne forstå strukturen i vores testdatabase. Lad os nu gå videre til mere komplekse forespørgsler, der viser, hvor kraftfuldt SQL er. Lad os først skrive en forespørgsel, der samler data fra flere forskellige tabeller. Vi bruger en SQL JOIN-kommando til at sammenføje de tabeller, der indeholder kundedata og ordrer. I den forbindelse navngiver vi kolonnerne og angiver et matchende kunde-ID som JOIN-betingelse. Husk, at vi bruger kvalificerede identifikatorer til at skelne mellem kolonnerne i de to tabeller:
SELECT customers.customer_name as 'Customer', customers.customer_id, orders.order_id, orders.order_date AS 'Date' FROM Customers JOIN Orders ON Orders.customer_id = Customers.customer_id ORDER BY Customers.customer_id;sqlNu bruger vi endnu en JOIN-kommando til at beregne de samlede omkostninger for de bestilte produkter:
SELECT OrderItems.order_id, OrderItems.orderitem_id AS 'Order Item', Products.product_name AS 'Product', Products.price AS 'Unit Price', OrderItems.count AS 'Count', (OrderItems.count * Products.price) AS 'Total' FROM OrderItems JOIN Products ON OrderItems.product_id = Products.product_id;sql