Difference between revisions of "6238 Databaser Agenda/Mere sql"
(→Opgave) |
(→LEFT JOIN) |
||
(21 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
− | == | + | ==ON DELETE CASCADE== |
− | + | On delete fortæller hvad databasen skal gøre hvis man forsøger at slette data der anvendes som foreign key af andre tabeller. | |
− | |||
− | |||
− | |||
<source lang=sql> | <source lang=sql> | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
CREATE TABLE Saelger( | CREATE TABLE Saelger( | ||
Navn NVARCHAR(20)NOT NULL, | Navn NVARCHAR(20)NOT NULL, | ||
Line 40: | Line 10: | ||
PRIMARY KEY(MedarbNr) | PRIMARY KEY(MedarbNr) | ||
); | ); | ||
+ | |||
CREATE TABLE TelefonNr( | CREATE TABLE TelefonNr( | ||
Nr NVARCHAR(8) NOT NULL, | Nr NVARCHAR(8) NOT NULL, | ||
Line 51: | Line 22: | ||
DELETE FROM Saelger WHERE MedarbNr = 1; | DELETE FROM Saelger WHERE MedarbNr = 1; | ||
+ | </source> | ||
− | + | I eksemplet her laves først tabellen sælger og derefter TelefonNr der har Saelger som FK. Bemærk ON DELETE CASCADE efter FOREIGN KEY på TelefonNr. | |
− | I eksemplet her laves først tabellen sælger og derefter TelefonNr der har Saelger som FK. | ||
Efterfølgende indsættes en sælger og en telefon med reference til sælgeren hvorefter vi forsøger at slette sælgeren. | Efterfølgende indsættes en sælger og en telefon med reference til sælgeren hvorefter vi forsøger at slette sælgeren. | ||
− | Normalt vil dette ikke være muligt, men fordi vi har indsat ON DELETE Cascade vil den blot slette de numre som referere til Sælgeren når Sælgeren slettes. | + | Normalt vil dette ikke være muligt, men fordi vi har indsat ON DELETE Cascade vil den blot slette de numre som referere til Sælgeren når Sælgeren slettes. |
− | ==Opgave== | + | |
+ | ===Opgave=== | ||
Forsøg på sælger databasen at slette en Vare | Forsøg på sælger databasen at slette en Vare | ||
+ | |||
Ret i databasen ved at tilføje de nødvendige ON DELETE sådan at en Vare kan slettes uden problemer | Ret i databasen ved at tilføje de nødvendige ON DELETE sådan at en Vare kan slettes uden problemer | ||
+ | |||
Ret derefter også sådan at en Sælger kan slettes uden problemer. Dette er nok ikke praktisk i virkeligheden men prøv alligevel | Ret derefter også sådan at en Sælger kan slettes uden problemer. Dette er nok ikke praktisk i virkeligheden men prøv alligevel | ||
− | + | ||
==SELECT DISTINCT== | ==SELECT DISTINCT== | ||
− | Afprøv selv forskellen på | + | Med DISTINCT kommer hvert resultat kun en gang i output. Afprøv selv forskellen på |
+ | |||
+ | <source lang=sql> | ||
SELECT Navn FROM KoebesAf | SELECT Navn FROM KoebesAf | ||
JOIN Kunde ON Kunde.KundeNr = KoebesAf.Kunde | JOIN Kunde ON Kunde.KundeNr = KoebesAf.Kunde | ||
− | + | </source> | |
+ | |||
+ | og | ||
+ | |||
+ | <source lang=sql> | ||
SELECT DISTINCT Navn FROM KoebesAf | SELECT DISTINCT Navn FROM KoebesAf | ||
JOIN Kunde ON Kunde.KundeNr = KoebesAf.Kunde | JOIN Kunde ON Kunde.KundeNr = KoebesAf.Kunde | ||
+ | </source> | ||
+ | |||
+ | ==IDENTITY/AUTO_INCREMENT== | ||
+ | Ofte vi vi ønske at have et index der automatisk tæller op. | ||
− | + | Det er muligt i både Ms-Sql og MySql men på to forskellige måder. | |
− | = | + | |
+ | <source lang=sql> | ||
/* Opret tabellen Saelger */ | /* Opret tabellen Saelger */ | ||
+ | /*MS-Sql*/ | ||
+ | CREATE TABLE Saelger | ||
+ | ( | ||
+ | Navn NVARCHAR(20) NOT NULL, | ||
+ | StartDato DATETIME NOT NULL, | ||
+ | Email NVARCHAR(20) NOT NULL, | ||
+ | MedarbNr INT IDENTITY , | ||
+ | PRIMARY KEY(MedarbNr) | ||
+ | ); | ||
+ | |||
+ | /*MySql*/ | ||
CREATE TABLE Saelger | CREATE TABLE Saelger | ||
( | ( | ||
Line 79: | Line 75: | ||
StartDato DATETIME NOT NULL, | StartDato DATETIME NOT NULL, | ||
Email NVARCHAR(20) NOT NULL, | Email NVARCHAR(20) NOT NULL, | ||
− | MedarbNr INT | + | MedarbNr INT AUTO_INCREMENT, |
PRIMARY KEY(MedarbNr) | PRIMARY KEY(MedarbNr) | ||
); | ); | ||
+ | </source> | ||
+ | Hvis du benytter en autoincrementeret værdi må denne ikke længere være med under INSERT | ||
+ | <source lang=sql> | ||
INSERT INTO Saelger (Navn,StartDato,Email) VALUES ('Ole','1-1-1','ole@mail.dk'); | INSERT INTO Saelger (Navn,StartDato,Email) VALUES ('Ole','1-1-1','ole@mail.dk'); | ||
+ | </source> | ||
− | |||
− | |||
− | |||
==Unique== | ==Unique== | ||
+ | Med UNIQI kan vi bestemme at en attribut skal være unik selv om den ikke er nøgle attribut. | ||
+ | |||
+ | Derved kan vi anvende den som reference til foreign key. | ||
+ | |||
+ | I eksemplet her anvendes MedarbNr som nøgle, men vi vælger at angive Navn som UNIQ og kan derfor anvende det som Foreign key på TelefonNr. | ||
+ | <source lang=sql> | ||
/* Opret tabellen Saelger */ | /* Opret tabellen Saelger */ | ||
CREATE TABLE Saelger | CREATE TABLE Saelger | ||
( | ( | ||
Navn NVARCHAR(20) NOT NULL, | Navn NVARCHAR(20) NOT NULL, | ||
− | StartDato | + | StartDato DATETIME NOT NULL, |
Email NVARCHAR(20) NOT NULL, | Email NVARCHAR(20) NOT NULL, | ||
MedarbNr INT NOT NULL, | MedarbNr INT NOT NULL, | ||
Line 108: | Line 111: | ||
FOREIGN KEY(SaelgerNavn) REFERENCES Saelger(Navn) | FOREIGN KEY(SaelgerNavn) REFERENCES Saelger(Navn) | ||
); | ); | ||
+ | </source> | ||
− | + | ==LEFT JOIN== | |
− | + | I Sales databasen havde vi blandt andet tabellerne Saelger, TelefonNR og KundeNr. | |
− | == | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | De kunne samles med dette JOIN | |
− | + | <source lang=sql> | |
+ | Select * from Saelger | ||
+ | JOIN Kunde on Kunde.Saelger = Saelger.MedarbNr | ||
+ | JOIN TelefonNr ON TelefonNr.Saelger = Saelger.MedarbNr | ||
+ | </source> | ||
+ | |||
+ | Problemet opstår på TelefonNr da en af sælgerne ikke har nogen telefon og derfor ikke kommer med i listen. | ||
+ | |||
+ | Det kan løses med en LEFT JOIN. Med LEFT JOIN medtages alle entry fra venstre side selv om de ikke har nogen match i højre side. | ||
+ | <source lang=sql> | ||
+ | Select * from Saelger | ||
+ | JOIN Kunde on Kunde.Saelger = Saelger.MedarbNr | ||
+ | LEFT JOIN TelefonNr ON TelefonNr.Saelger = Saelger.MedarbNr | ||
+ | </source> | ||
− | + | Du kan læse mere om JOINs i Læs SQL Tutorial Kapitel 26 | |
− | |||
− |
Latest revision as of 11:18, 3 November 2015
Contents
ON DELETE CASCADE
On delete fortæller hvad databasen skal gøre hvis man forsøger at slette data der anvendes som foreign key af andre tabeller.
CREATE TABLE Saelger(
Navn NVARCHAR(20)NOT NULL,
StartDatoDATETIMENOT NULL,
EmailNVARCHAR(20)NOT NULL,
MedarbNrINTNOT NULL,
PRIMARY KEY(MedarbNr)
);
CREATE TABLE TelefonNr(
Nr NVARCHAR(8) NOT NULL,
SaelgerINT NOT NULL,
PRIMARY KEY(Nr),
FOREIGN KEY(Saelger) REFERENCES Saelger(MedarbNr) ON DELETE Cascade
);
INSERT INTO Saelger (Navn, StartDato,Email,MedarbNr) VALUES ('Hans','2001-1-1','Hans@mail.dk',1);
INSERT INTO TelefonNr (Nr, Saelger) VALUES ('12345678',1);
DELETE FROM Saelger WHERE MedarbNr = 1;
I eksemplet her laves først tabellen sælger og derefter TelefonNr der har Saelger som FK. Bemærk ON DELETE CASCADE efter FOREIGN KEY på TelefonNr.
Efterfølgende indsættes en sælger og en telefon med reference til sælgeren hvorefter vi forsøger at slette sælgeren.
Normalt vil dette ikke være muligt, men fordi vi har indsat ON DELETE Cascade vil den blot slette de numre som referere til Sælgeren når Sælgeren slettes.
Opgave
Forsøg på sælger databasen at slette en Vare
Ret i databasen ved at tilføje de nødvendige ON DELETE sådan at en Vare kan slettes uden problemer
Ret derefter også sådan at en Sælger kan slettes uden problemer. Dette er nok ikke praktisk i virkeligheden men prøv alligevel
SELECT DISTINCT
Med DISTINCT kommer hvert resultat kun en gang i output. Afprøv selv forskellen på
SELECT Navn FROM KoebesAf
JOIN Kunde ON Kunde.KundeNr = KoebesAf.Kunde
og
SELECT DISTINCT Navn FROM KoebesAf
JOIN Kunde ON Kunde.KundeNr = KoebesAf.Kunde
IDENTITY/AUTO_INCREMENT
Ofte vi vi ønske at have et index der automatisk tæller op.
Det er muligt i både Ms-Sql og MySql men på to forskellige måder.
/* Opret tabellen Saelger */
/*MS-Sql*/
CREATE TABLE Saelger
(
Navn NVARCHAR(20) NOT NULL,
StartDato DATETIME NOT NULL,
Email NVARCHAR(20) NOT NULL,
MedarbNr INT IDENTITY ,
PRIMARY KEY(MedarbNr)
);
/*MySql*/
CREATE TABLE Saelger
(
Navn NVARCHAR(20) NOT NULL,
StartDato DATETIME NOT NULL,
Email NVARCHAR(20) NOT NULL,
MedarbNr INT AUTO_INCREMENT,
PRIMARY KEY(MedarbNr)
);
Hvis du benytter en autoincrementeret værdi må denne ikke længere være med under INSERT
INSERT INTO Saelger (Navn,StartDato,Email) VALUES ('Ole','1-1-1','ole@mail.dk');
Unique
Med UNIQI kan vi bestemme at en attribut skal være unik selv om den ikke er nøgle attribut.
Derved kan vi anvende den som reference til foreign key.
I eksemplet her anvendes MedarbNr som nøgle, men vi vælger at angive Navn som UNIQ og kan derfor anvende det som Foreign key på TelefonNr.
/* Opret tabellen Saelger */
CREATE TABLE Saelger
(
Navn NVARCHAR(20) NOT NULL,
StartDato DATETIME NOT NULL,
Email NVARCHAR(20) NOT NULL,
MedarbNr INT NOT NULL,
UNIQUE (Navn),
PRIMARY KEY(MedarbNr)
);
/* Opret tabellen TelefonNr */
CREATE TABLE TelefonNr
(
Nr NVARCHAR(8) NOT NULL,
SaelgerNavn NVARCHAR(20) NOT NULL,
PRIMARY KEY(Nr),
FOREIGN KEY(SaelgerNavn) REFERENCES Saelger(Navn)
);
LEFT JOIN
I Sales databasen havde vi blandt andet tabellerne Saelger, TelefonNR og KundeNr.
De kunne samles med dette JOIN
Select * from Saelger
JOIN Kunde on Kunde.Saelger = Saelger.MedarbNr
JOIN TelefonNr ON TelefonNr.Saelger = Saelger.MedarbNr
Problemet opstår på TelefonNr da en af sælgerne ikke har nogen telefon og derfor ikke kommer med i listen.
Det kan løses med en LEFT JOIN. Med LEFT JOIN medtages alle entry fra venstre side selv om de ikke har nogen match i højre side.
Select * from Saelger
JOIN Kunde on Kunde.Saelger = Saelger.MedarbNr
LEFT JOIN TelefonNr ON TelefonNr.Saelger = Saelger.MedarbNr
Du kan læse mere om JOINs i Læs SQL Tutorial Kapitel 26