Initial commit, ov1-4
This commit is contained in:
commit
35175b6c69
7
losning_template.md
Normal file
7
losning_template.md
Normal file
@ -0,0 +1,7 @@
|
||||
---
|
||||
geometry: margin=30mm
|
||||
author: Felix Albrigtsen
|
||||
...
|
||||
|
||||
# Øving
|
||||
|
31
ov1/eksempeldata.sql
Normal file
31
ov1/eksempeldata.sql
Normal file
@ -0,0 +1,31 @@
|
||||
/* Gyldig demo-data, følger alle begrensinger i databasen. */
|
||||
|
||||
INSERT INTO Borettslag (navn) VALUES ('BB Nardo');
|
||||
|
||||
INSERT INTO Bygning (borettslag_id, gatenavn, husnummer) VALUES (1, 'Borgveien', '1');
|
||||
INSERT INTO Bygning (borettslag_id, gatenavn, husnummer) VALUES (1, 'Borgveien', '2');
|
||||
|
||||
INSERT INTO Leilighet (bygning_id, etasje, romnr, areal) VALUES (1, 1, 1, 100);
|
||||
INSERT INTO Leilighet (bygning_id, etasje, romnr, areal) VALUES (1, 1, 2, 100);
|
||||
|
||||
INSERT INTO Leilighet (bygning_id, etasje, romnr, areal) VALUES (2, 1, 1, 45);
|
||||
INSERT INTO Leilighet (bygning_id, etasje, romnr, areal) VALUES (2, 1, 2, 45);
|
||||
|
||||
|
||||
INSERT INTO Medlem (fornavn, etternavn, borettslag_id, leilighet_id) VALUES ('Ole', 'Olsen', '1', '1');
|
||||
INSERT INTO Medlem (fornavn, etternavn, borettslag_id, leilighet_id) VALUES ('Kari', 'Karlsen', '1', '3');
|
||||
|
||||
INSERT INTO Medlem (fornavn, etternavn, borettslag_id, leilighet_id) VALUES ('Jon', 'Jonsen', '1', NULL);
|
||||
/* Denne har lov til å eksistere, siden Medlem.leilighet_id kan være NULL. */
|
||||
|
||||
|
||||
|
||||
/* Ugyldig demo-data, fordi flere felter ikke kan være null og ikke har default-verdier: */
|
||||
|
||||
INSERT INTO Bygning (borettslag_id, gatenavn, husnummer) VALUES (NULL, 'Borgveien', '1');
|
||||
INSERT INTO Medlem (borettslag_id, leilighet_id) VALUES (1, 1);
|
||||
|
||||
|
||||
/* Ugyldig demo-data, fordi fremmednøklene referer til tupler i andre databaser, og disse tuplene ikke eksisterer. */
|
||||
|
||||
INSERT INTO Bygning (borettslag_id, gatenavn, husnummer) VALUES (8, 'Borgveien', '3');
|
62
ov1/modeller.sql
Normal file
62
ov1/modeller.sql
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
For alle tabellene i databasen har jeg vurdert at det ikke finnes noen tilfredsstillende kandidater som primærnøkkel.
|
||||
Derfor har jeg laget surrogatnøkkelen "id" i alle tabellene, slik at disse kan indekseres og brukes som entydige nøkler.
|
||||
|
||||
De aller fleste fremmednøklene i min tabell er NOT NULL. Dette er fordi en leilighet ikke kan eksistere uten en bygning, og en bygning ikke kan eksistere uten et borettslag som eier det.
|
||||
|
||||
Riktignok kan medlemmer eksistere uten å eie en leilighet, så Medlem.leilighet_id kan være NULL.
|
||||
|
||||
De nøklene med NOT NULL har jeg gitt ON DELETE CASCADE så de aldri kan peke på ikke-eksisterende tupler.
|
||||
Om en leilighet slettes blir Medlem.leilighet_id oppdatert til NULL.
|
||||
|
||||
|
||||
Primærnøklene i databasen kan ikke være null, da det er viktig at primærnøklene er unike. Dersom vi lar feltet kunne være NULL er det fortsatt maksimalt en av tuplene som kan ha NULL som id.
|
||||
*/
|
||||
|
||||
CREATE TABLE Borettslag (
|
||||
id INT NOT NULL AUTO_INCREMENT ,
|
||||
navn VARCHAR(255) NOT NULL,
|
||||
|
||||
gatenavn VARCHAR(255) NOT NULL,
|
||||
husnummer INT NOT NULL,
|
||||
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
CREATE TABLE Bygning (
|
||||
id INT NOT NULL AUTO_INCREMENT ,
|
||||
borettslag_id INT NOT NULL,
|
||||
gatenavn VARCHAR(255) NOT NULL,
|
||||
husnummer INT NOT NULL,
|
||||
|
||||
CONSTRAINT fk_bygning_borettslag_id FOREIGN KEY (borettslag_id) REFERENCES Borettslag (id) ON DELETE CASCADE,
|
||||
PRIMARY KEY (id)
|
||||
)
|
||||
|
||||
CREATE TABLE Leilighet (
|
||||
id INT NOT NULL AUTO_INCREMENT ,
|
||||
bygning_id INT NOT NULL,
|
||||
etasje INT NOT NULL,
|
||||
romnr INT NOT NULL,
|
||||
areal INT NOT NULL,
|
||||
|
||||
CONSTRAINT fk_leilighet_bygning_id FOREIGN KEY (bygning_id) REFERENCES Bygning (id) ON DELETE CASCADE,
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
CREATE TABLE Medlem (
|
||||
id INT NOT NULL AUTO_INCREMENT ,
|
||||
fornavn VARCHAR(100) NOT NULL ,
|
||||
etternavn VARCHAR(100) NOT NULL ,
|
||||
epost VARCHAR(320),
|
||||
telefon VARCHAR(20),
|
||||
|
||||
borettslag_id INT NOT NULL ,
|
||||
leilighet_id INT,
|
||||
|
||||
CONSTRAINT fk_medlem_borettslag_id FOREIGN KEY (borettslag_id) REFERENCES Borettslag (id) ON DELETE CASCADE,
|
||||
CONSTRAINT fk_medlem_leilighet_id FOREIGN KEY (leilighet_id) REFERENCES Leilighet (id) ON DELETE UPDATE,
|
||||
|
||||
PRIMARY KEY (id)
|
||||
|
||||
);
|
BIN
ov1/ov1_diagram.png
Normal file
BIN
ov1/ov1_diagram.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 65 KiB |
45
ov1/skjema.puml
Normal file
45
ov1/skjema.puml
Normal file
@ -0,0 +1,45 @@
|
||||
@startuml
|
||||
|
||||
!define table(x) class x << (T,#FFAAAA) >>
|
||||
!define primary_key(x) <u>x</u>
|
||||
hide methods
|
||||
hide stereotypes
|
||||
|
||||
title "B&B - Database"
|
||||
|
||||
table(Borettslag) {
|
||||
* primary_key(id)
|
||||
navn
|
||||
}
|
||||
|
||||
table(Bygning) {
|
||||
* primary_key(id)
|
||||
* borettslag_id
|
||||
* gate
|
||||
* husnummer
|
||||
}
|
||||
|
||||
table(Leilighet) {
|
||||
* primary_key(id)
|
||||
* bygning_id
|
||||
* etasje
|
||||
* leilighetsnummer
|
||||
* areal
|
||||
}
|
||||
|
||||
table(Medlem) {
|
||||
* primary_key(id)
|
||||
* borettslag_id
|
||||
* fornavn
|
||||
* etternavn
|
||||
epost
|
||||
telefon
|
||||
leilighet_id
|
||||
}
|
||||
|
||||
Bygning -> Borettslag
|
||||
Leilighet --> Bygning
|
||||
Medlem -l-> Leilighet
|
||||
Borettslag <- Medlem
|
||||
|
||||
@enduml
|
160
ov2/bok-script-mysql.txt
Normal file
160
ov2/bok-script-mysql.txt
Normal file
@ -0,0 +1,160 @@
|
||||
/*
|
||||
** bok-script-mysql.txt
|
||||
/*
|
||||
** DROP TABLE-setninger som sletter gamle tabeller
|
||||
*/
|
||||
|
||||
DROP TABLE IF EXISTS bok_forfatter;
|
||||
DROP TABLE IF EXISTS forfatter;
|
||||
DROP TABLE IF EXISTS bok;
|
||||
DROP TABLE IF EXISTS forlag;
|
||||
DROP TABLE IF EXISTS konsulent;
|
||||
|
||||
/*
|
||||
** Oppretter tabeller med entitetsintegritet
|
||||
*/
|
||||
CREATE TABLE forlag
|
||||
(
|
||||
forlag_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
forlag_navn VARCHAR(30),
|
||||
adresse VARCHAR(30),
|
||||
telefon CHAR(15),
|
||||
PRIMARY KEY(forlag_id)
|
||||
)ENGINE=INNODB;
|
||||
|
||||
CREATE TABLE bok
|
||||
(
|
||||
bok_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
tittel VARCHAR(30),
|
||||
utgitt_aar INT,
|
||||
forlag_id INT UNSIGNED,
|
||||
PRIMARY KEY(bok_id)
|
||||
)ENGINE=INNODB;
|
||||
|
||||
CREATE TABLE forfatter
|
||||
(
|
||||
forfatter_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
fornavn VARCHAR(20),
|
||||
etternavn VARCHAR(30),
|
||||
fode_aar INT,
|
||||
dod_aar INT,
|
||||
nasjonalitet VARCHAR(20),
|
||||
PRIMARY KEY(forfatter_id)
|
||||
)ENGINE=INNODB;
|
||||
|
||||
CREATE TABLE bok_forfatter
|
||||
(
|
||||
bok_id INT UNSIGNED NOT NULL,
|
||||
forfatter_id INT UNSIGNED NOT NULL,
|
||||
PRIMARY KEY(bok_id, forfatter_id)
|
||||
)ENGINE=INNODB;
|
||||
|
||||
CREATE TABLE konsulent
|
||||
(
|
||||
kons_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
fornavn VARCHAR(20),
|
||||
etternavn VARCHAR(30),
|
||||
epost VARCHAR(30),
|
||||
PRIMARY KEY(kons_id)
|
||||
)ENGINE=INNODB;
|
||||
|
||||
/*
|
||||
** Legger på referanseintegritet (fremmednøkler)
|
||||
*/
|
||||
ALTER TABLE bok
|
||||
ADD FOREIGN KEY(forlag_id)REFERENCES forlag(forlag_id);
|
||||
|
||||
ALTER TABLE bok_forfatter
|
||||
ADD FOREIGN KEY(bok_id)REFERENCES bok(bok_id);
|
||||
|
||||
ALTER TABLE bok_forfatter
|
||||
ADD FOREIGN KEY(forfatter_id)REFERENCES forfatter(forfatter_id);
|
||||
|
||||
|
||||
/*
|
||||
** Legger inn gyldige data i tabellene
|
||||
*/
|
||||
INSERT INTO forlag VALUES(NULL,'Tapir','Trondheim','73590000');
|
||||
INSERT INTO forlag VALUES(NULL, 'Gyldendal','Oslo','22220000');
|
||||
INSERT INTO forlag VALUES(NULL, 'Cappelen','Oslo','22200000');
|
||||
INSERT INTO forlag VALUES(NULL, 'Universitetsforlaget','Oslo','23230000');
|
||||
INSERT INTO forlag VALUES(NULL, 'Aschehaug','Oslo','22000000');
|
||||
INSERT INTO forlag VALUES(NULL, 'Oktober','Oslo','22002200');
|
||||
INSERT INTO forlag VALUES(NULL, 'Tiden','Oslo','22232223');
|
||||
INSERT INTO forlag VALUES(NULL, 'Harper Collins','USA',NULL);
|
||||
|
||||
INSERT INTO bok VALUES(NULL,'Tåpenes',1995,7);
|
||||
INSERT INTO bok VALUES(NULL,'Rebecca',1981,3);
|
||||
INSERT INTO bok VALUES(NULL,'Gutter er gutter',1995,5);
|
||||
INSERT INTO bok VALUES(NULL,'Microserfs',1991,8);
|
||||
INSERT INTO bok VALUES(NULL,'Generation X',1995,8);
|
||||
INSERT INTO bok VALUES(NULL,'Klosterkrønike',1982,3);
|
||||
INSERT INTO bok VALUES(NULL,'Universet',1988,3);
|
||||
INSERT INTO bok VALUES(NULL,'Nålen',1978,3);
|
||||
INSERT INTO bok VALUES(NULL,'Markens grøde',1917,2);
|
||||
INSERT INTO bok VALUES(NULL,'Victoria',1898,2);
|
||||
INSERT INTO bok VALUES(NULL,'Sult',1890,2);
|
||||
INSERT INTO bok VALUES(NULL,'Benoni',1908,2);
|
||||
INSERT INTO bok VALUES(NULL,'Rosa',1908,2);
|
||||
INSERT INTO bok VALUES(NULL,'Et skritt',1997,2);
|
||||
INSERT INTO bok VALUES(NULL,'Den femte',1996,2);
|
||||
INSERT INTO bok VALUES(NULL,'Villspor',1995,2);
|
||||
INSERT INTO bok VALUES(NULL,'Silkeridderen',1994,2);
|
||||
INSERT INTO bok VALUES(NULL,'Den hvite hingsten',1992,2);
|
||||
INSERT INTO bok VALUES(NULL,'Hunder',1992,2);
|
||||
INSERT INTO bok VALUES(NULL,'Bridget Jones',1995,5);
|
||||
INSERT INTO bok VALUES(NULL,'Se terapeuten',1998,3);
|
||||
INSERT INTO bok VALUES(NULL,'Sa mor',1996,3);
|
||||
INSERT INTO bok VALUES(NULL,'Jubel',1995,3);
|
||||
INSERT INTO bok VALUES(NULL,'Tatt av kvinnen',1993,3);
|
||||
INSERT INTO bok VALUES(NULL,'Supernaiv',1996,3);
|
||||
|
||||
INSERT INTO forfatter VALUES(NULL, 'John','Tool',1937, 1969, 'USA');
|
||||
INSERT INTO forfatter VALUES(NULL,'Ken','Follet',NULL, NULL, 'Britisk');
|
||||
INSERT INTO forfatter VALUES(NULL,'Stephen','Hawking',NULL, NULL, 'Britisk');
|
||||
INSERT INTO forfatter VALUES(NULL,'Jose','Saramago',1942, NULL, 'Portugisisk');
|
||||
INSERT INTO forfatter VALUES(NULL,'Douglas','Coupland',1961, NULL, 'Canadisk');
|
||||
INSERT INTO forfatter VALUES(NULL,'Nick','Hornby',1857, NULL, 'Britisk');
|
||||
INSERT INTO forfatter VALUES(NULL,'Knut','Hamsund',1859, 1952, 'Norsk');
|
||||
INSERT INTO forfatter VALUES(NULL,'Henning','Mankell',1948, NULL, 'Svensk');
|
||||
INSERT INTO forfatter VALUES(NULL,'Helen','Fielding',NULL, NULL, 'Britisk');
|
||||
INSERT INTO forfatter VALUES(NULL,'Hal','Sirowitz',NULL, NULL, 'USA');
|
||||
INSERT INTO forfatter VALUES(NULL,'Lars S.','Christensen',NULL, NULL, 'Norsk');
|
||||
INSERT INTO forfatter VALUES(NULL,'Erlend','Loe',NULL, NULL, 'Norsk');
|
||||
|
||||
INSERT INTO bok_forfatter VALUES(1, 1);
|
||||
INSERT INTO bok_forfatter VALUES(2, 2);
|
||||
INSERT INTO bok_forfatter VALUES(3, 6);
|
||||
INSERT INTO bok_forfatter VALUES(4, 5);
|
||||
INSERT INTO bok_forfatter VALUES(5, 5);
|
||||
INSERT INTO bok_forfatter VALUES(6, 4);
|
||||
INSERT INTO bok_forfatter VALUES(7, 3);
|
||||
INSERT INTO bok_forfatter VALUES(8, 2);
|
||||
INSERT INTO bok_forfatter VALUES(9, 7);
|
||||
INSERT INTO bok_forfatter VALUES(10, 7);
|
||||
INSERT INTO bok_forfatter VALUES(11, 7);
|
||||
INSERT INTO bok_forfatter VALUES(12, 1);
|
||||
INSERT INTO bok_forfatter VALUES(13, 1);
|
||||
INSERT INTO bok_forfatter VALUES(14, 8);
|
||||
INSERT INTO bok_forfatter VALUES(15, 8);
|
||||
INSERT INTO bok_forfatter VALUES(16, 8);
|
||||
INSERT INTO bok_forfatter VALUES(17, 8);
|
||||
INSERT INTO bok_forfatter VALUES(18, 8);
|
||||
INSERT INTO bok_forfatter VALUES(19, 8);
|
||||
INSERT INTO bok_forfatter VALUES(20, 9);
|
||||
INSERT INTO bok_forfatter VALUES(21, 10);
|
||||
INSERT INTO bok_forfatter VALUES(22, 10);
|
||||
INSERT INTO bok_forfatter VALUES(23, 11);
|
||||
INSERT INTO bok_forfatter VALUES(24, 12);
|
||||
INSERT INTO bok_forfatter VALUES(25, 12);
|
||||
|
||||
INSERT INTO konsulent VALUES(NULL, 'Anne', 'Hansen', 'anne.hansen@xxx.com');
|
||||
INSERT INTO konsulent VALUES(NULL, 'Bjørn', 'Jensen', 'bjornj@yyy.com');
|
||||
INSERT INTO konsulent VALUES(NULL,'Anne', 'Ås', 'anne.as@zzz.com');
|
||||
|
||||
/*
|
||||
** Avslutter transaksjonen og lagrer tabellene og data fysisk i databasen
|
||||
*/
|
||||
|
||||
COMMIT;
|
||||
|
27
ov2/db_setup.txt
Normal file
27
ov2/db_setup.txt
Normal file
@ -0,0 +1,27 @@
|
||||
❯ mysql -u root -p [12:32:35]
|
||||
Enter password:
|
||||
Welcome to the MariaDB monitor. Commands end with ; or \g.
|
||||
Your MariaDB connection id is 15
|
||||
Server version: 10.9.2-MariaDB Arch Linux
|
||||
|
||||
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
|
||||
|
||||
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
|
||||
|
||||
MariaDB [(none)]> CREATE USER 'idatt2103'@'localhost' IDENTIFIED BY 'idatt2103';
|
||||
Query OK, 0 rows affected (0.051 sec)
|
||||
|
||||
MariaDB [(none)]> CREATE DATABASE oving2;
|
||||
Query OK, 1 row affected (0.001 sec)
|
||||
|
||||
MariaDB [(none)]> GRANT ALL PRIVILEGES ON oving2.* TO 'idatt2103'@'localhost';
|
||||
Query OK, 0 rows affected (0.011 sec)
|
||||
|
||||
MariaDB [(none)]> FLUSH PRIVILEGES;
|
||||
Query OK, 0 rows affected (0.001 sec)
|
||||
|
||||
MariaDB [(none)]> quit
|
||||
Bye
|
||||
>>> elapsed time 4m51s
|
||||
|
||||
|
BIN
ov2/idat_db_ov2_relmod2.docx.pdf
Normal file
BIN
ov2/idat_db_ov2_relmod2.docx.pdf
Normal file
Binary file not shown.
254
ov2/losning.md
Normal file
254
ov2/losning.md
Normal file
@ -0,0 +1,254 @@
|
||||
---
|
||||
geometry: margin=10mm
|
||||
author: Felix Albrigtsen
|
||||
...
|
||||
|
||||
## Oppgave 1
|
||||
### a) Lag en SQL-spørring som utfører operasjonene seleksjon og projeksjon på tabellen Bok.
|
||||
Seleksjon:
|
||||
`SELECT * FROM bok WHERE bok.tittel = 'Victorie'`
|
||||
|
||||
|
||||
|
||||
Begge:
|
||||
`SELECT tittel,utgitt_aar FROM bok;`
|
||||
|
||||
Eksempel-resultat:
|
||||
```
|
||||
MariaDB [oving2]> SELECT tittel,utgitt_aar FROM bok;
|
||||
+--------------------+------------+
|
||||
| tittel | utgitt_aar |
|
||||
+--------------------+------------+
|
||||
| Tåpenes | 1995 |
|
||||
| Rebecca | 1981 |
|
||||
| Gutter er gutter | 1995 |
|
||||
| Microserfs | 1991 |
|
||||
| Generation X | 1995 |
|
||||
...
|
||||
```
|
||||
|
||||
### b) Lag en SQL-spørring som utfører operasjonen produkt på tabellene Forlag og Bok. Beskriv resultatet med egne ord.
|
||||
|
||||
`SELECT * FROM forlag,bok;`
|
||||
|
||||
Eksempel-resultat:
|
||||
```
|
||||
MariaDB [oving2]> SELECT * FROM forlag,bok;
|
||||
+-----------+----------------+-----------+----------+--------+---------+------------+-----------+
|
||||
| forlag_id | forlag_navn | adresse | telefon | bok_id | tittel | utgitt_aar | forlag_id |
|
||||
+-----------+----------------+-----------+----------+--------+---------+------------+-----------+
|
||||
| 1 | Tapir | Trondheim | 73590000 | 1 | Tåpenes | 1995 | 7 |
|
||||
| 2 | Gyldendal | Oslo | 22220000 | 1 | Tåpenes | 1995 | 7 |
|
||||
| 3 | Cappelen | Oslo | 22200000 | 1 | Tåpenes | 1995 | 7 |
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
Her ser vi et produkt av forlag og bok, som et kryssprodukt. Resultatet er alle kombinasjoner/permutasjoner som er mulig. Som vi ser i tabellutdraget over gir ikke dette eksempelet så mye mening siden det viser alle bøker med alle forlag. Denne tabellen blir både lengre og bredere enn tabellene var til å begynne med, siden det må vise mange kombinasjoner med mange felter.
|
||||
|
||||
Om vi derimot bruker WHERE-selektorer, kan vi hente ut nyttig data med produktet.
|
||||
|
||||
### c) Lag SQL-spørringer som utfører operasjonene likhetsforening (equijoin) og naturlig forening(natural join) på tabellene Forlag og Bok. Hva forteller resultatet?
|
||||
|
||||
Spesifisert equijoin:
|
||||
`SELECT * FROM forlag JOIN bok ON forlag.forlag_id = bok.forlag_id;`
|
||||
```
|
||||
MariaDB [oving2]> SELECT * FROM forlag JOIN bok ON forlag.forlag_id = bok.forlag_id;
|
||||
+-----------+---------------+---------+----------+--------+------------------+------------+----------+
|
||||
| forlag_id | forlag_navn | adresse | telefon | bok_id | tittel | utgitt_aar |forlag_id |
|
||||
+-----------+---------------+---------+----------+--------+------------------+------------+----------+
|
||||
| 7 | Tiden | Oslo | 22232223 | 1 | Tåpenes | 1995 | 7 |
|
||||
| 3 | Cappelen | Oslo | 22200000 | 2 | Rebecca | 1981 | 3 |
|
||||
| 5 | Aschehaug | Oslo | 22000000 | 3 | Gutter er gutter | 1995 | 5 |
|
||||
| 8 | Harper Collins| USA | NULL | 4 | Microserfs | 1991 | 8 |
|
||||
| 8 | Harper Collins| USA | NULL | 5 | Generation X | 1995 | 8 |
|
||||
...
|
||||
```
|
||||
|
||||
Naturlig forening:
|
||||
`SELECT * FROM forlag NATURAL JOIN bok;`
|
||||
```
|
||||
+-----------+----------------+---------+----------+--------+--------------------+------------+
|
||||
| forlag_id | forlag_navn | adresse | telefon | bok_id | tittel | utgitt_aar |
|
||||
+-----------+----------------+---------+----------+--------+--------------------+------------+
|
||||
| 7 | Tiden | Oslo | 22232223 | 1 | Tåpenes | 1995 |
|
||||
| 3 | Cappelen | Oslo | 22200000 | 2 | Rebecca | 1981 |
|
||||
| 5 | Aschehaug | Oslo | 22000000 | 3 | Gutter er gutter | 1995 |
|
||||
| 8 | Harper Collins | USA | NULL | 4 | Microserfs | 1991 |
|
||||
| 8 | Harper Collins | USA | NULL | 5 | Generation X | 1995 |
|
||||
|
||||
```
|
||||
|
||||
De to tabellene er like, med unntak av at NATURAL JOIN ikke tar med begge tilfeller av `forlag_id`, da disse to er like. NATURAL JOIN bruker navnet på feltene for å avgjøre likheten.
|
||||
|
||||
Alle våre bøker har en forlag_id(ingen er NULL), altså kommer alle med. Dersom vi hadde tomme felter i dette feltet ville de ikke blitt med i disse foreningene.
|
||||
|
||||
|
||||
|
||||
|
||||
## d) Finn eksempler på attributter eller kombinasjoner av attributter som er unionkompatible. Hvilke relasjonsoperasjoner krever at operandene er unionkompatible? Sett opp SQL-spørringer som utfører disse operasjonene, et eksempel på hver. Beskriv med egne ord hva spørringene gir deg svaret på.
|
||||
|
||||
|
||||
Skjemaene i de to tabellene må være tilsvarende i lengde og datatyper. For å kombinere de to må kolonenne ordnes i samme rekkefølge.
|
||||
|
||||
|
||||
Her slår vi sammen to varchar-attributter med union.
|
||||
```sql
|
||||
MariaDB [oving2]> SELECT nasjonalitet FROM forfatter UNION SELECT adresse FROM forlag;
|
||||
+--------------+
|
||||
| nasjonalitet |
|
||||
+--------------+
|
||||
| USA |
|
||||
| Britisk |
|
||||
| Portugisisk |
|
||||
| Canadisk |
|
||||
| Norsk |
|
||||
| Svensk |
|
||||
| Trondheim |
|
||||
| Oslo |
|
||||
+--------------+
|
||||
8 rows in set (0.001 sec)
|
||||
```
|
||||
Resultatet viser oss alle nasjonaliteter og alle adresser som hører til henholdsvis en forfatter eller forlag.
|
||||
|
||||
|
||||
Her slår vi sammen det samme atributtet(forlag_navn) fra forlag med adresse Trondheim og fra forlag uten telefonnummer.
|
||||
|
||||
```sql
|
||||
MariaDB [oving2]> SELECT forlag_navn FROM forlag WHERE telefon IS NULL UNION SELECT forlag_navn FROM forlag WHERE adresse = 'Trondheim';
|
||||
+----------------+
|
||||
| forlag_navn |
|
||||
+----------------+
|
||||
| Harper Collins |
|
||||
| Tapir |
|
||||
+----------------+
|
||||
2 rows in set (0.001 sec)
|
||||
```
|
||||
|
||||
|
||||
|
||||
# Oppgave 2
|
||||
## a) Bruk SQL til å finne navnene til alle forlagene. Hvilken eller hvilke operasjoner fra relasjonsalgebraen brukte du?
|
||||
```sql
|
||||
MariaDB [oving2]> SELECT forlag_navn FROM forlag;
|
||||
+----------------------+
|
||||
| forlag_navn |
|
||||
+----------------------+
|
||||
| Tapir |
|
||||
| Gyldendal |
|
||||
| Cappelen |
|
||||
| Universitetsforlaget |
|
||||
| Aschehaug |
|
||||
| Oktober |
|
||||
| Tiden |
|
||||
| Harper Collins |
|
||||
+----------------------+
|
||||
8 rows in set (0.001 sec)
|
||||
```
|
||||
Brukt seleksjon.
|
||||
|
||||
## b) Bruk SQL til å finne eventuelle forlag (forlag_id er nok) som ikke har gitt ut bøker. Hvilken eller hvilke operasjoner fra relasjonsalgebraen brukte du?
|
||||
|
||||
```sql
|
||||
MariaDB [oving2]> SELECT forlag_id FROM forlag WHERE forlag_id NOT IN (SELECT forlag_id FROM bok);
|
||||
+-----------+
|
||||
| forlag_id |
|
||||
+-----------+
|
||||
| 1 |
|
||||
| 4 |
|
||||
| 6 |
|
||||
+-----------+
|
||||
3 rows in set (0.014 sec)
|
||||
```
|
||||
|
||||
Brukt seleksjon og projeksjon.
|
||||
|
||||
## c) Bruk SQL til å finne forfattere som er født i 1948. Hvilken eller hvilke operasjoner fra relasjonsalgebraen brukte du?
|
||||
```sql
|
||||
MariaDB [oving2]> SELECT * FROM forfatter WHERE fode_aar = 1948;
|
||||
+--------------+---------+-----------+----------+---------+--------------+
|
||||
| forfatter_id | fornavn | etternavn | fode_aar | dod_aar | nasjonalitet |
|
||||
+--------------+---------+-----------+----------+---------+--------------+
|
||||
| 8 | Henning | Mankell | 1948 | NULL | Svensk |
|
||||
+--------------+---------+-----------+----------+---------+--------------+
|
||||
1 row in set (0.001 sec)
|
||||
|
||||
```
|
||||
Brukt seleksjon
|
||||
|
||||
## d) Bruk SQL til å finne navn og adresse til forlaget som har gitt ut boka 'Generation X'. Hvilken eller hvilke operasjoner fra relasjonsalgebraen brukte du?
|
||||
|
||||
```sql
|
||||
MariaDB [oving2]> SELECT forlag_navn,adresse FROM forlag NATURAL JOIN bok WHERE tittel = "Generation X";
|
||||
+----------------+---------+
|
||||
| forlag_navn | adresse |
|
||||
+----------------+---------+
|
||||
| Harper Collins | USA |
|
||||
+----------------+---------+
|
||||
1 row in set (0.001 sec)
|
||||
```
|
||||
|
||||
Brukt seleksjon og naturlig forening.
|
||||
|
||||
## e) Bruk SQL til å finne titlene på bøkene som Hamsun har skrevet. Hvilken eller hvilke operasjoner fra relasjonsalgebraen brukte du?
|
||||
|
||||
```sql
|
||||
MariaDB [oving2]> SELECT b.tittel FROM bok b,bok_forfatter bf,forfatter f WHERE bf.forfatter_id = f.forfatter_id AND f.etternavn = 'Hamsund' AND bf.bok_id = b.bok_id;
|
||||
+----------------+
|
||||
| tittel |
|
||||
+----------------+
|
||||
| Markens grøde |
|
||||
| Victoria |
|
||||
| Sult |
|
||||
+----------------+
|
||||
3 rows in set (0.001 sec)
|
||||
```
|
||||
|
||||
Brukt seleksjon og projeksjon
|
||||
|
||||
## f) Bruk SQL til å finne informasjon om bøker og forlagene som har utgitt dem. Én linje i oversikten skal inneholde bokas tittel og utgivelsesår, samt forlagets navn, adresse og telefonnummer. Forlag som ikke har gitt ut noen bøker skal også med i listen. Hvilken eller hvilke operasjoner fra relasjonsalgebraen brukte du?
|
||||
|
||||
Formatting:
|
||||
SELECT b.tittel,b.utgitt_aar,f.forlag_navn,f.adresse FROM bok b,forlag f;
|
||||
|
||||
Selection:
|
||||
SELECT * FROM forlag f LEFT JOIN bok b ON b.forlag_id = f.forlag_id;
|
||||
|
||||
|
||||
```sql
|
||||
MariaDB [oving2]> SELECT b.tittel,b.utgitt_aar,f.forlag_navn,f.adresse,f.telefon FROM forlag f LEFT JOIN bok b ON b.forlag_id = f.forlag_id;
|
||||
+--------------------+------------+----------------------+-----------+----------+
|
||||
| tittel | utgitt_aar | forlag_navn | adresse | telefon |
|
||||
+--------------------+------------+----------------------+-----------+----------+
|
||||
| Tåpenes | 1995 | Tiden | Oslo | 22232223 |
|
||||
| Rebecca | 1981 | Cappelen | Oslo | 22200000 |
|
||||
| Gutter er gutter | 1995 | Aschehaug | Oslo | 22000000 |
|
||||
| Microserfs | 1991 | Harper Collins | USA | NULL |
|
||||
| Generation X | 1995 | Harper Collins | USA | NULL |
|
||||
| Klosterkrønike | 1982 | Cappelen | Oslo | 22200000 |
|
||||
| Universet | 1988 | Cappelen | Oslo | 22200000 |
|
||||
| Nålen | 1978 | Cappelen | Oslo | 22200000 |
|
||||
| Markens grøde | 1917 | Gyldendal | Oslo | 22220000 |
|
||||
| Victoria | 1898 | Gyldendal | Oslo | 22220000 |
|
||||
| Sult | 1890 | Gyldendal | Oslo | 22220000 |
|
||||
| Benoni | 1908 | Gyldendal | Oslo | 22220000 |
|
||||
| Rosa | 1908 | Gyldendal | Oslo | 22220000 |
|
||||
| Et skritt | 1997 | Gyldendal | Oslo | 22220000 |
|
||||
| Den femte | 1996 | Gyldendal | Oslo | 22220000 |
|
||||
| Villspor | 1995 | Gyldendal | Oslo | 22220000 |
|
||||
| Silkeridderen | 1994 | Gyldendal | Oslo | 22220000 |
|
||||
| Den hvite hingsten | 1992 | Gyldendal | Oslo | 22220000 |
|
||||
| Hunder | 1992 | Gyldendal | Oslo | 22220000 |
|
||||
| Bridget Jones | 1995 | Aschehaug | Oslo | 22000000 |
|
||||
| Se terapeuten | 1998 | Cappelen | Oslo | 22200000 |
|
||||
| Sa mor | 1996 | Cappelen | Oslo | 22200000 |
|
||||
| Jubel | 1995 | Cappelen | Oslo | 22200000 |
|
||||
| Tatt av kvinnen | 1993 | Cappelen | Oslo | 22200000 |
|
||||
| Supernaiv | 1996 | Cappelen | Oslo | 22200000 |
|
||||
| NULL | NULL | Tapir | Trondheim | 73590000 |
|
||||
| NULL | NULL | Universitetsforlaget | Oslo | 23230000 |
|
||||
| NULL | NULL | Oktober | Oslo | 22002200 |
|
||||
+--------------------+------------+----------------------+-----------+----------+
|
||||
```
|
||||
|
||||
Brukt: seleksjon, produkt, outer join
|
BIN
ov2/oving2.pdf
Normal file
BIN
ov2/oving2.pdf
Normal file
Binary file not shown.
117
ov3/byggOgBo_mysql.sql
Normal file
117
ov3/byggOgBo_mysql.sql
Normal file
@ -0,0 +1,117 @@
|
||||
-- MySQL
|
||||
-- DROP-setninger i tilfelle vi må kjøre scriptet på nytt.
|
||||
|
||||
DROP TABLE leilighet;
|
||||
DROP TABLE andelseier;
|
||||
DROP TABLE bygning;
|
||||
DROP TABLE borettslag;
|
||||
DROP TABLE poststed;
|
||||
|
||||
-- Lager tabellene, legger inn NOT NULL- og UNIQUE-krav der det er naturlig
|
||||
-- Vær forsiktig med å legge inn slike krav, det er vanskelig å forandre
|
||||
-- dem i ettertid.
|
||||
|
||||
CREATE TABLE poststed(
|
||||
postnr SMALLINT,
|
||||
poststed VARCHAR(20) NOT NULL,
|
||||
CONSTRAINT poststed_pk PRIMARY KEY(postnr));
|
||||
|
||||
CREATE TABLE borettslag(
|
||||
bolag_navn VARCHAR(20),
|
||||
bolag_adr VARCHAR(40) NOT NULL UNIQUE,
|
||||
etabl_aar SMALLINT NOT NULL,
|
||||
postnr SMALLINT NOT NULL,
|
||||
CONSTRAINT borettslag_pk PRIMARY KEY(bolag_navn));
|
||||
|
||||
CREATE TABLE bygning(
|
||||
bygn_id INTEGER NOT NULL AUTO_INCREMENT,
|
||||
bygn_adr VARCHAR(40) NOT NULL,
|
||||
ant_etasjer INTEGER DEFAULT 1,
|
||||
bolag_navn VARCHAR(20) NOT NULL,
|
||||
postnr SMALLINT NOT NULL,
|
||||
CONSTRAINT bygning_pk PRIMARY KEY(bygn_id));
|
||||
|
||||
CREATE TABLE leilighet(
|
||||
leil_nr INTEGER NOT NULL AUTO_INCREMENT,
|
||||
ant_rom SMALLINT NOT NULL,
|
||||
ant_kvm REAL NOT NULL,
|
||||
etasje SMALLINT DEFAULT 1,
|
||||
bygn_id INTEGER NOT NULL,
|
||||
and_eier_nr INTEGER NOT NULL UNIQUE,
|
||||
CONSTRAINT leilighet_pk PRIMARY KEY(leil_nr));
|
||||
|
||||
CREATE TABLE andelseier(
|
||||
and_eier_nr INTEGER NOT NULL AUTO_INCREMENT,
|
||||
fornavn VARCHAR(30) NOT NULL,
|
||||
etternavn VARCHAR(30) NOT NULL,
|
||||
telefon CHAR(15),
|
||||
ansiennitet SMALLINT,
|
||||
bolag_navn VARCHAR(20) NOT NULL,
|
||||
CONSTRAINT andelseier_pk PRIMARY KEY(and_eier_nr));
|
||||
|
||||
-- Fremmednøkler
|
||||
|
||||
ALTER TABLE borettslag
|
||||
ADD CONSTRAINT borettslag_fk1 FOREIGN KEY(postnr)
|
||||
REFERENCES poststed(postnr);
|
||||
|
||||
ALTER TABLE bygning
|
||||
ADD CONSTRAINT bygning_fk1 FOREIGN KEY(postnr)
|
||||
REFERENCES poststed(postnr);
|
||||
|
||||
ALTER TABLE bygning
|
||||
ADD CONSTRAINT bygning_fk2 FOREIGN KEY(bolag_navn)
|
||||
REFERENCES borettslag(bolag_navn);
|
||||
|
||||
ALTER TABLE leilighet
|
||||
ADD CONSTRAINT leilighet_fk1 FOREIGN KEY(bygn_id)
|
||||
REFERENCES bygning(bygn_id);
|
||||
|
||||
ALTER TABLE leilighet
|
||||
ADD CONSTRAINT leilighet_fk2 FOREIGN KEY(and_eier_nr)
|
||||
REFERENCES andelseier(and_eier_nr);
|
||||
|
||||
ALTER TABLE andelseier
|
||||
ADD CONSTRAINT andelseier_fk2 FOREIGN KEY(bolag_navn)
|
||||
REFERENCES borettslag(bolag_navn);
|
||||
|
||||
|
||||
|
||||
-- Legger inn gyldige data
|
||||
|
||||
INSERT INTO poststed(postnr, poststed) VALUES(2020, 'Skedsmokorset');
|
||||
INSERT INTO poststed(postnr, poststed) VALUES(6408, 'Aureosen');
|
||||
INSERT INTO poststed(postnr, poststed) VALUES(7033, 'Trondheim');
|
||||
INSERT INTO poststed(postnr, poststed) VALUES(7020, 'Trondheim');
|
||||
|
||||
INSERT INTO borettslag(bolag_navn, bolag_adr, etabl_aar, postnr) VALUES('Tertitten', 'Åsveien 100', 1980, 7020);
|
||||
INSERT INTO borettslag(bolag_navn, bolag_adr, etabl_aar, postnr) VALUES('Sisiken', 'Brurød', 1990, 7033);
|
||||
INSERT INTO borettslag(bolag_navn, bolag_adr, etabl_aar, postnr) VALUES('Lerken', 'Storgt 5', 2000, 6408);
|
||||
|
||||
INSERT INTO andelseier(and_eier_nr, fornavn, etternavn, telefon, ansiennitet, bolag_navn)
|
||||
VALUES(DEFAULT, 'Even', 'Trulsbo', '56667743', 3, 'Tertitten');
|
||||
INSERT INTO andelseier(and_eier_nr, fornavn, etternavn, telefon, ansiennitet, bolag_navn)
|
||||
VALUES(DEFAULT, 'Anna', 'Olsen', '45674588', 10, 'Tertitten');
|
||||
INSERT INTO andelseier(and_eier_nr, fornavn, etternavn, telefon, ansiennitet, bolag_navn)
|
||||
VALUES(DEFAULT, 'Ingrid', 'Olsen', '45785388', 8, 'Tertitten');
|
||||
INSERT INTO andelseier(and_eier_nr, fornavn, etternavn, telefon, ansiennitet, bolag_navn)
|
||||
VALUES(DEFAULT, 'Arne', 'Torp', '78565388', 7, 'Tertitten');
|
||||
INSERT INTO andelseier(and_eier_nr, fornavn, etternavn, telefon, ansiennitet, bolag_navn)
|
||||
VALUES(DEFAULT, 'Arne', 'Martinsen', '78555388', 4, 'Sisiken');
|
||||
|
||||
INSERT INTO bygning(bygn_id, bygn_adr, ant_etasjer, bolag_navn, postnr) VALUES(DEFAULT, 'Åsveien 100a', 3, 'Tertitten', 7020);
|
||||
INSERT INTO bygning(bygn_id, bygn_adr, ant_etasjer, bolag_navn, postnr) VALUES(DEFAULT, 'Åsveien 100b', 3, 'Tertitten', 7020);
|
||||
INSERT INTO bygning(bygn_id, bygn_adr, ant_etasjer, bolag_navn, postnr) VALUES(DEFAULT, 'Åsveien 100c', 6, 'Tertitten', 7020);
|
||||
INSERT INTO bygning(bygn_id, bygn_adr, ant_etasjer, bolag_navn, postnr) VALUES(DEFAULT, 'Storgt 10', 2, 'Sisiken', 7020);
|
||||
|
||||
-- bruker defaultverdien for antall etasjer
|
||||
INSERT INTO bygning(bygn_id, bygn_adr, bolag_navn, postnr) VALUES(DEFAULT, 'Åsveien 100', 'Tertitten', 7020);
|
||||
|
||||
INSERT INTO leilighet(leil_nr, ant_rom, ant_kvm, etasje, bygn_id, and_eier_nr) VALUES(DEFAULT, 5, 110, 3, 1, 1);
|
||||
INSERT INTO leilighet(leil_nr, ant_rom, ant_kvm, etasje, bygn_id, and_eier_nr) VALUES(DEFAULT, 5, 110, 3, 1, 2);
|
||||
INSERT INTO leilighet(leil_nr, ant_rom, ant_kvm, etasje, bygn_id, and_eier_nr) VALUES(DEFAULT, 2, 50, 1, 3, 3);
|
||||
|
||||
-- bruker defaultverdien for etasje
|
||||
INSERT INTO leilighet(leil_nr, ant_rom, ant_kvm, bygn_id, and_eier_nr) VALUES(DEFAULT, 5, 110, 1, 4);
|
||||
|
||||
|
BIN
ov3/ing_db_ov3_sql1.pdf
Normal file
BIN
ov3/ing_db_ov3_sql1.pdf
Normal file
Binary file not shown.
154
ov3/losning.md
Normal file
154
ov3/losning.md
Normal file
@ -0,0 +1,154 @@
|
||||
---
|
||||
geometry: margin=30mm
|
||||
author: Felix Albrigtsen
|
||||
...
|
||||
|
||||
# Øving 3: SQL del 1 (obligatorisk)
|
||||
#### Skrevet av Felix Albrigtsen, felixalb@stud.ntnu.no
|
||||
```
|
||||
Innleveringsfrist: se Blackboard
|
||||
Tidligste godkjenning: datoer blir annonsert
|
||||
Løsningsforslag legges ut i etterkant.
|
||||
Alle obligatoriske øvinger må være godkjente for å få karakter i emnet.
|
||||
```
|
||||
|
||||
# Oppgave 1 SQL
|
||||
|
||||
I denne oppgaven skal vi bruke en borettslag-databasen. Bruk følgende sql-script:
|
||||
byggOgBo_mysql.sql (tekstfil som finnes i BB). Scriptet inneholder data som oppgavene
|
||||
nedenfor spør etter.
|
||||
Sett opp SELECT-setninger som besvarer spørsmålene nedenfor. Kun én setning pr oppgave.
|
||||
|
||||
Databaseskjema:
|
||||
```
|
||||
MariaDB [idatt2103_ov3]> SELECT * FROM andelseier LIMIT 1;
|
||||
+-------------+---------+-----------+----------+-------------+------------+
|
||||
| and_eier_nr | fornavn | etternavn | telefon | ansiennitet | bolag_navn |
|
||||
+-------------+---------+-----------+----------+-------------+------------+
|
||||
| 1 | Even | Trulsbo | 56667743 | 3 | Tertitten |
|
||||
+-------------+---------+-----------+----------+-------------+------------+
|
||||
MariaDB [idatt2103_ov3]> SELECT * FROM borettslag LIMIT 1;
|
||||
+------------+-----------+-----------+--------+
|
||||
| bolag_navn | bolag_adr | etabl_aar | postnr |
|
||||
+------------+-----------+-----------+--------+
|
||||
| Lerken | Storgt 5 | 2000 | 6408 |
|
||||
+------------+-----------+-----------+--------+
|
||||
MariaDB [idatt2103_ov3]> SELECT * FROM bygning LIMIT 1;
|
||||
+---------+---------------+-------------+------------+--------+
|
||||
| bygn_id | bygn_adr | ant_etasjer | bolag_navn | postnr |
|
||||
+---------+---------------+-------------+------------+--------+
|
||||
| 1 | Åsveien 100a | 3 | Tertitten | 7020 |
|
||||
+---------+---------------+-------------+------------+--------+
|
||||
MariaDB [idatt2103_ov3]> SELECT * FROM leilighet LIMIT 1;
|
||||
+---------+---------+---------+--------+---------+-------------+
|
||||
| leil_nr | ant_rom | ant_kvm | etasje | bygn_id | and_eier_nr |
|
||||
+---------+---------+---------+--------+---------+-------------+
|
||||
| 1 | 5 | 110 | 3 | 1 | 1 |
|
||||
+---------+---------+---------+--------+---------+-------------+
|
||||
MariaDB [idatt2103_ov3]> SELECT * FROM poststed LIMIT 1;
|
||||
+--------+---------------+
|
||||
| postnr | poststed |
|
||||
+--------+---------------+
|
||||
| 2020 | Skedsmokorset |
|
||||
+--------+---------------+
|
||||
```
|
||||
|
||||
# Kommentar:
|
||||
|
||||
Flere steder i oppgavene har jeg måtte gjøre antagelser om spørsmålene, så alle løsningene er ikke deifnitive. For eksempel "Sortert etter antallet" i oppgave 10 kan være enten stigende eller avtagende. I tillegg har jeg testet på eksempeldataen gitt i blackboard, men prøvd å gjøre setningene kompatible med alle verdier der det er mulig. Dette resulterer i noen ekstra sjekker i besvarelsen, som ikke har noen effekt på eksempeldataen, men for eksempel ville påvirket leiligheter uten noen andelseier.
|
||||
|
||||
# Besvarelse:
|
||||
|
||||
## 1. Finn alle borettslag etablert i årene 1975-1985.
|
||||
```sql
|
||||
SELECT * FROM borettslag WHERE etabl_aar >= 1975 AND etabl_aar <= 1985;
|
||||
```
|
||||
|
||||
## 2. Skriv ut en liste over andelseiere. Listen skal ha linjer som ser slik ut (tekster i kursiv er data fra databasen): "__fornavn etternavn__, ansiennitet: __ansiennitet år__". Listen skal være sortert på ansiennitet, de med lengst ansiennitet øverst.
|
||||
|
||||
```sql
|
||||
SELECT CONCAT(fornavn, ' ', etternavn, ', ansiennitet: ', ansiennitet) AS andelseier
|
||||
FROM andelseier ORDER BY ansiennitet DESC;
|
||||
```
|
||||
|
||||
## 3. I hvilket år ble det eldste borettslaget etablert?
|
||||
|
||||
```sql
|
||||
SELECT etabl_aar FROM borettslag ORDER BY etabl_aar ASC LIMIT 1;
|
||||
```
|
||||
|
||||
## 4. Finn adressene til alle bygninger som inneholder leiligheter med minst tre rom.
|
||||
|
||||
```sql
|
||||
SELECT bygn_adr FROM bygning b RIGHT JOIN (SELECT * FROM leilighet WHERE ant_rom >= 3) l
|
||||
ON b.bygn_id = l.bygn_id GROUP BY bygn_adr;
|
||||
```
|
||||
|
||||
## 5. Finn antall bygninger i borettslaget "Tertitten".
|
||||
|
||||
```sql
|
||||
SELECT COUNT(*) FROM bygning WHERE bolag_navn = "Tertitten";
|
||||
```
|
||||
|
||||
## 6. Lag en liste som viser antall bygninger i hvert enkelt borettslag. Listen skal være sortert på borettslagsnavn. Husk at det kan finnes borettslag uten bygninger - de skal også med.
|
||||
|
||||
```sql
|
||||
SELECT COUNT(b.bygn_id) as "Antall Bygninger", bl.bolag_navn FROM borettslag bl LEFT
|
||||
JOIN bygning b ON b.bolag_navn = bl.bolag_navn GROUP BY bolag_navn ORDER BY bl.bolag_navn;
|
||||
```
|
||||
|
||||
## 7. Finn antall leiligheter i borettslaget "Tertitten".
|
||||
|
||||
```sql
|
||||
SELECT COUNT(*) FROM leilighet l JOIN bygning b ON l.bygn_id = b.bygn_id
|
||||
WHERE b.bolag_navn = "Tertitten";
|
||||
```
|
||||
|
||||
## 8. Hvor høyt kan du bo i borettslaget "Tertitten"?
|
||||
|
||||
```sql
|
||||
SELECT ant_etasjer FROM bygning WHERE bolag_navn = "Tertitten" ORDER BY
|
||||
ant_etasjer DESC LIMIT 1;
|
||||
```
|
||||
|
||||
## 9. Finn navn og nummer til andelseiere som ikke har leilighet.
|
||||
|
||||
```sql
|
||||
SELECT fornavn, etternavn, telefon FROM andelseier a LEFT JOIN leilighet l
|
||||
ON a.and_eier_nr = l.and_eier_nr WHERE leil_nr IS NULL;
|
||||
```
|
||||
|
||||
## 10. Finn antall andelseiere pr borettslag, sortert etter antallet. Husk at det kan finnes borettslag uten andelseiere - de skal også med.
|
||||
```sql
|
||||
SELECT b.bolag_navn, COUNT(a.and_eier_nr) as antall_andelseiere FROM andelseier a
|
||||
RIGHT JOIN borettslag b ON b.bolag_navn = a.bolag_navn GROUP BY b.bolag_navn
|
||||
ORDER BY antall_andelseiere DESC;
|
||||
```
|
||||
|
||||
## 11. Skriv ut en liste over alle andelseiere. For de som har leilighet, skal leilighetsnummeret skrives ut.
|
||||
```sql
|
||||
SELECT a.fornavn, a.etternavn, l.leil_nr FROM andelseier a LEFT JOIN leilighet l
|
||||
ON a.and_eier_nr = l.and_eier_nr;
|
||||
```
|
||||
|
||||
## 12. Hvilke borettslag har leiligheter med eksakt 4 rom?
|
||||
```sql
|
||||
SELECT bolag_navn FROM leilighet l JOIN bygning b ON l.bygn_id = b.bygn_id
|
||||
WHERE l.ant_rom = 4 GROUP BY bolag_navn;
|
||||
```
|
||||
**NB:** tomt resultat, ingen leiligheter i eksempeldataen har 4 rom.
|
||||
|
||||
## 13. Skriv ut en liste over antall andelseiere pr postnr og poststed, begrenset til de som bor i leiligheter tilknyttet et borettslag. Husk at postnummeret til disse er postnummeret til bygningen de bor i, og ikke postnummeret til borettslaget. Du trenger ikke ta med poststeder med 0 andelseiere. (Ekstraoppgave: Hva hvis vi vil ha med poststeder med 0 andelseiere?)
|
||||
|
||||
```sql
|
||||
SELECT COUNT(l.and_eier_nr) AS 'Antall andelseiere', b.poststed, b.postnr FROM
|
||||
leilighet l LEFT JOIN (SELECT b.bygn_id,p.poststed,p.postnr FROM bygning b LEFT JOIN
|
||||
poststed p ON b.postnr = p.postnr) b ON l.bygn_id = b.bygn_id WHERE
|
||||
l.and_eier_nr IS NOT NULL GROUP BY b.poststed;
|
||||
```
|
||||
|
||||
kortere løsning, men bruker natural join(ikke anbefalt)
|
||||
```sql
|
||||
SELECT l.and_eier_nr, p.poststed, p.postnr FROM leilighet l NATURAL JOIN bygning b
|
||||
NATURAL JOIN poststed p WHERE l.and_eier_nr IS NOT NULL;
|
||||
```
|
BIN
ov3/oving3.pdf
Normal file
BIN
ov3/oving3.pdf
Normal file
Binary file not shown.
160
ov4/bok-script-mysql.txt
Normal file
160
ov4/bok-script-mysql.txt
Normal file
@ -0,0 +1,160 @@
|
||||
/*
|
||||
** bok-script-mysql.txt
|
||||
/*
|
||||
** DROP TABLE-setninger som sletter gamle tabeller
|
||||
*/
|
||||
|
||||
DROP TABLE IF EXISTS bok_forfatter;
|
||||
DROP TABLE IF EXISTS forfatter;
|
||||
DROP TABLE IF EXISTS bok;
|
||||
DROP TABLE IF EXISTS forlag;
|
||||
DROP TABLE IF EXISTS konsulent;
|
||||
|
||||
/*
|
||||
** Oppretter tabeller med entitetsintegritet
|
||||
*/
|
||||
CREATE TABLE forlag
|
||||
(
|
||||
forlag_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
forlag_navn VARCHAR(30),
|
||||
adresse VARCHAR(30),
|
||||
telefon CHAR(15),
|
||||
PRIMARY KEY(forlag_id)
|
||||
)ENGINE=INNODB;
|
||||
|
||||
CREATE TABLE bok
|
||||
(
|
||||
bok_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
tittel VARCHAR(30),
|
||||
utgitt_aar INT,
|
||||
forlag_id INT UNSIGNED,
|
||||
PRIMARY KEY(bok_id)
|
||||
)ENGINE=INNODB;
|
||||
|
||||
CREATE TABLE forfatter
|
||||
(
|
||||
forfatter_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
fornavn VARCHAR(20),
|
||||
etternavn VARCHAR(30),
|
||||
fode_aar INT,
|
||||
dod_aar INT,
|
||||
nasjonalitet VARCHAR(20),
|
||||
PRIMARY KEY(forfatter_id)
|
||||
)ENGINE=INNODB;
|
||||
|
||||
CREATE TABLE bok_forfatter
|
||||
(
|
||||
bok_id INT UNSIGNED NOT NULL,
|
||||
forfatter_id INT UNSIGNED NOT NULL,
|
||||
PRIMARY KEY(bok_id, forfatter_id)
|
||||
)ENGINE=INNODB;
|
||||
|
||||
CREATE TABLE konsulent
|
||||
(
|
||||
kons_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
fornavn VARCHAR(20),
|
||||
etternavn VARCHAR(30),
|
||||
epost VARCHAR(30),
|
||||
PRIMARY KEY(kons_id)
|
||||
)ENGINE=INNODB;
|
||||
|
||||
/*
|
||||
** Legger på referanseintegritet (fremmednøkler)
|
||||
*/
|
||||
ALTER TABLE bok
|
||||
ADD FOREIGN KEY(forlag_id)REFERENCES forlag(forlag_id);
|
||||
|
||||
ALTER TABLE bok_forfatter
|
||||
ADD FOREIGN KEY(bok_id)REFERENCES bok(bok_id);
|
||||
|
||||
ALTER TABLE bok_forfatter
|
||||
ADD FOREIGN KEY(forfatter_id)REFERENCES forfatter(forfatter_id);
|
||||
|
||||
|
||||
/*
|
||||
** Legger inn gyldige data i tabellene
|
||||
*/
|
||||
INSERT INTO forlag VALUES(NULL,'Tapir','Trondheim','73590000');
|
||||
INSERT INTO forlag VALUES(NULL, 'Gyldendal','Oslo','22220000');
|
||||
INSERT INTO forlag VALUES(NULL, 'Cappelen','Oslo','22200000');
|
||||
INSERT INTO forlag VALUES(NULL, 'Universitetsforlaget','Oslo','23230000');
|
||||
INSERT INTO forlag VALUES(NULL, 'Aschehaug','Oslo','22000000');
|
||||
INSERT INTO forlag VALUES(NULL, 'Oktober','Oslo','22002200');
|
||||
INSERT INTO forlag VALUES(NULL, 'Tiden','Oslo','22232223');
|
||||
INSERT INTO forlag VALUES(NULL, 'Harper Collins','USA',NULL);
|
||||
|
||||
INSERT INTO bok VALUES(NULL,'Tåpenes',1995,7);
|
||||
INSERT INTO bok VALUES(NULL,'Rebecca',1981,3);
|
||||
INSERT INTO bok VALUES(NULL,'Gutter er gutter',1995,5);
|
||||
INSERT INTO bok VALUES(NULL,'Microserfs',1991,8);
|
||||
INSERT INTO bok VALUES(NULL,'Generation X',1995,8);
|
||||
INSERT INTO bok VALUES(NULL,'Klosterkrønike',1982,3);
|
||||
INSERT INTO bok VALUES(NULL,'Universet',1988,3);
|
||||
INSERT INTO bok VALUES(NULL,'Nålen',1978,3);
|
||||
INSERT INTO bok VALUES(NULL,'Markens grøde',1917,2);
|
||||
INSERT INTO bok VALUES(NULL,'Victoria',1898,2);
|
||||
INSERT INTO bok VALUES(NULL,'Sult',1890,2);
|
||||
INSERT INTO bok VALUES(NULL,'Benoni',1908,2);
|
||||
INSERT INTO bok VALUES(NULL,'Rosa',1908,2);
|
||||
INSERT INTO bok VALUES(NULL,'Et skritt',1997,2);
|
||||
INSERT INTO bok VALUES(NULL,'Den femte',1996,2);
|
||||
INSERT INTO bok VALUES(NULL,'Villspor',1995,2);
|
||||
INSERT INTO bok VALUES(NULL,'Silkeridderen',1994,2);
|
||||
INSERT INTO bok VALUES(NULL,'Den hvite hingsten',1992,2);
|
||||
INSERT INTO bok VALUES(NULL,'Hunder',1992,2);
|
||||
INSERT INTO bok VALUES(NULL,'Bridget Jones',1995,5);
|
||||
INSERT INTO bok VALUES(NULL,'Se terapeuten',1998,3);
|
||||
INSERT INTO bok VALUES(NULL,'Sa mor',1996,3);
|
||||
INSERT INTO bok VALUES(NULL,'Jubel',1995,3);
|
||||
INSERT INTO bok VALUES(NULL,'Tatt av kvinnen',1993,3);
|
||||
INSERT INTO bok VALUES(NULL,'Supernaiv',1996,3);
|
||||
|
||||
INSERT INTO forfatter VALUES(NULL, 'John','Tool',1937, 1969, 'USA');
|
||||
INSERT INTO forfatter VALUES(NULL,'Ken','Follet',NULL, NULL, 'Britisk');
|
||||
INSERT INTO forfatter VALUES(NULL,'Stephen','Hawking',NULL, NULL, 'Britisk');
|
||||
INSERT INTO forfatter VALUES(NULL,'Jose','Saramago',1942, NULL, 'Portugisisk');
|
||||
INSERT INTO forfatter VALUES(NULL,'Douglas','Coupland',1961, NULL, 'Canadisk');
|
||||
INSERT INTO forfatter VALUES(NULL,'Nick','Hornby',1857, NULL, 'Britisk');
|
||||
INSERT INTO forfatter VALUES(NULL,'Knut','Hamsund',1859, 1952, 'Norsk');
|
||||
INSERT INTO forfatter VALUES(NULL,'Henning','Mankell',1948, NULL, 'Svensk');
|
||||
INSERT INTO forfatter VALUES(NULL,'Helen','Fielding',NULL, NULL, 'Britisk');
|
||||
INSERT INTO forfatter VALUES(NULL,'Hal','Sirowitz',NULL, NULL, 'USA');
|
||||
INSERT INTO forfatter VALUES(NULL,'Lars S.','Christensen',NULL, NULL, 'Norsk');
|
||||
INSERT INTO forfatter VALUES(NULL,'Erlend','Loe',NULL, NULL, 'Norsk');
|
||||
|
||||
INSERT INTO bok_forfatter VALUES(1, 1);
|
||||
INSERT INTO bok_forfatter VALUES(2, 2);
|
||||
INSERT INTO bok_forfatter VALUES(3, 6);
|
||||
INSERT INTO bok_forfatter VALUES(4, 5);
|
||||
INSERT INTO bok_forfatter VALUES(5, 5);
|
||||
INSERT INTO bok_forfatter VALUES(6, 4);
|
||||
INSERT INTO bok_forfatter VALUES(7, 3);
|
||||
INSERT INTO bok_forfatter VALUES(8, 2);
|
||||
INSERT INTO bok_forfatter VALUES(9, 7);
|
||||
INSERT INTO bok_forfatter VALUES(10, 7);
|
||||
INSERT INTO bok_forfatter VALUES(11, 7);
|
||||
INSERT INTO bok_forfatter VALUES(12, 1);
|
||||
INSERT INTO bok_forfatter VALUES(13, 1);
|
||||
INSERT INTO bok_forfatter VALUES(14, 8);
|
||||
INSERT INTO bok_forfatter VALUES(15, 8);
|
||||
INSERT INTO bok_forfatter VALUES(16, 8);
|
||||
INSERT INTO bok_forfatter VALUES(17, 8);
|
||||
INSERT INTO bok_forfatter VALUES(18, 8);
|
||||
INSERT INTO bok_forfatter VALUES(19, 8);
|
||||
INSERT INTO bok_forfatter VALUES(20, 9);
|
||||
INSERT INTO bok_forfatter VALUES(21, 10);
|
||||
INSERT INTO bok_forfatter VALUES(22, 10);
|
||||
INSERT INTO bok_forfatter VALUES(23, 11);
|
||||
INSERT INTO bok_forfatter VALUES(24, 12);
|
||||
INSERT INTO bok_forfatter VALUES(25, 12);
|
||||
|
||||
INSERT INTO konsulent VALUES(NULL, 'Anne', 'Hansen', 'anne.hansen@xxx.com');
|
||||
INSERT INTO konsulent VALUES(NULL, 'Bjørn', 'Jensen', 'bjornj@yyy.com');
|
||||
INSERT INTO konsulent VALUES(NULL,'Anne', 'Ås', 'anne.as@zzz.com');
|
||||
|
||||
/*
|
||||
** Avslutter transaksjonen og lagrer tabellene og data fysisk i databasen
|
||||
*/
|
||||
|
||||
COMMIT;
|
||||
|
3
ov4/db_setup.sql
Normal file
3
ov4/db_setup.sql
Normal file
@ -0,0 +1,3 @@
|
||||
CREATE DATABASE idatt2103_ov4;
|
||||
GRANT ALL PRIVILEGES ON idatt2103_ov4.* TO 'idatt2103'@'localhost';
|
||||
FLUSH PRIVILEGES;
|
BIN
ov4/ing_db_ov4_sql2.pdf
Normal file
BIN
ov4/ing_db_ov4_sql2.pdf
Normal file
Binary file not shown.
116
ov4/levinfo_mysql.txt
Normal file
116
ov4/levinfo_mysql.txt
Normal file
@ -0,0 +1,116 @@
|
||||
DROP TABLE IF EXISTS ordredetalj;
|
||||
DROP TABLE IF EXISTS prisinfo;
|
||||
DROP TABLE IF EXISTS ordrehode;
|
||||
DROP TABLE IF EXISTS delinfo;
|
||||
DROP TABLE IF EXISTS levinfo;
|
||||
|
||||
CREATE TABLE delinfo(
|
||||
delnr INTEGER,
|
||||
beskrivelse VARCHAR(30) NOT NULL,
|
||||
CONSTRAINT delinfo_pk PRIMARY KEY(delnr));
|
||||
|
||||
CREATE TABLE levinfo(
|
||||
levnr INTEGER,
|
||||
navn VARCHAR(20) NOT NULL,
|
||||
adresse VARCHAR(20) NOT NULL,
|
||||
levby VARCHAR(20) NOT NULL,
|
||||
fylke VARCHAR(20) NOT NULL,
|
||||
postnr INTEGER NOT NULL,
|
||||
CONSTRAINT levinfo_pk PRIMARY KEY(levnr));
|
||||
|
||||
CREATE TABLE ordrehode(
|
||||
ordrenr INTEGER,
|
||||
dato DATE NOT NULL,
|
||||
levnr INTEGER NOT NULL,
|
||||
status CHAR(1) NOT NULL,
|
||||
CONSTRAINT ordrehode_pk PRIMARY KEY(ordrenr),
|
||||
CONSTRAINT ordrehode_fk FOREIGN KEY(levnr) REFERENCES levinfo(levnr));
|
||||
|
||||
CREATE TABLE ordredetalj(
|
||||
ordrenr INTEGER,
|
||||
delnr INTEGER NOT NULL,
|
||||
kvantum INTEGER NOT NULL,
|
||||
CONSTRAINT ordredetalj_pk PRIMARY KEY(ordrenr,delnr),
|
||||
CONSTRAINT ordredetalj_fk1 FOREIGN KEY(ordrenr) REFERENCES ordrehode(ordrenr),
|
||||
CONSTRAINT ordredetalj_fk2 FOREIGN KEY(delnr) REFERENCES delinfo(delnr));
|
||||
|
||||
CREATE TABLE prisinfo(
|
||||
delnr INTEGER,
|
||||
levnr INTEGER,
|
||||
katalognr CHAR(6),
|
||||
pris REAL,
|
||||
CONSTRAINT prisinfo_pk PRIMARY KEY(delnr, levnr),
|
||||
CONSTRAINT prisinfo_fk1 FOREIGN KEY(delnr)REFERENCES delinfo(delnr),
|
||||
CONSTRAINT prisinfo_fk2 FOREIGN KEY(levnr)REFERENCES levinfo(levnr));
|
||||
|
||||
insert into delinfo(delnr, beskrivelse) values(51173,'Binders');
|
||||
insert into delinfo(delnr, beskrivelse) values(1,'Kontorstol');
|
||||
insert into delinfo(delnr, beskrivelse) values(51200,'Linjalsett');
|
||||
insert into delinfo(delnr, beskrivelse) values(3,'Pult');
|
||||
insert into delinfo(delnr, beskrivelse) values(4,'Skrivebord');
|
||||
insert into delinfo(delnr, beskrivelse) values(1909,'Skriveunderlag');
|
||||
insert into delinfo(delnr, beskrivelse) values(201,'Svarte kulepenner');
|
||||
insert into delinfo(delnr, beskrivelse) values(202,'Blå kulepenner');
|
||||
|
||||
insert into levinfo(levnr, navn, adresse, levby, fylke, postnr) values(6,'Kontorekspressen AS','Skolegata 3','Oslo','Oslo',1234);
|
||||
insert into levinfo(levnr, navn, adresse, levby, fylke, postnr) values(82,'Kontordata AS','Åsveien 178','Trondheim','S-Trøndelag',7023);
|
||||
insert into levinfo(levnr, navn, adresse, levby, fylke, postnr) values(9,'Kontorutstyr AS','Villa Villekulla','Ås','Østfold',1456);
|
||||
insert into levinfo(levnr, navn, adresse, levby, fylke, postnr) values(44,'Billig og Bra AS','Aveny 56','Oslo','Oslo',1222);
|
||||
insert into levinfo(levnr, navn, adresse, levby, fylke, postnr) values(12,'Mister Office AS','Storgt 56','Ås','Østfold',1456);
|
||||
insert into levinfo(levnr, navn, adresse, levby, fylke, postnr) values(81,'Kontorbutikken AS','Gjennomveien 78','Ål','Telemark',3345);
|
||||
|
||||
insert into ordrehode(ordrenr, dato, levnr, status) values(11,'1986-05-10',6,'c');
|
||||
insert into ordrehode(ordrenr, dato, levnr, status) values(12,'1986-07-17',82,'c');
|
||||
insert into ordrehode(ordrenr, dato, levnr, status) values(13,'1986-09-13',44,'p');
|
||||
insert into ordrehode(ordrenr, dato, levnr, status) values(14,'1986-12-17',44,'p');
|
||||
insert into ordrehode(ordrenr, dato, levnr, status) values(15,'1987-01-03',44,'p');
|
||||
insert into ordrehode(ordrenr, dato, levnr, status) values(16,'1987-01-31',6,'c');
|
||||
insert into ordrehode(ordrenr, dato, levnr, status) values(17,'1987-05-14',6,'c');
|
||||
insert into ordrehode(ordrenr, dato, levnr, status) values(18,'1987-05-12',82,'p');
|
||||
|
||||
|
||||
insert into ordredetalj(ordrenr, delnr, kvantum) values(11,1,5);
|
||||
insert into ordredetalj(ordrenr, delnr, kvantum) values(11,201,100);
|
||||
insert into ordredetalj(ordrenr, delnr, kvantum) values(11,202,100);
|
||||
insert into ordredetalj(ordrenr, delnr, kvantum) values(11,1909,6);
|
||||
insert into ordredetalj(ordrenr, delnr, kvantum) values(11,51200,20);
|
||||
insert into ordredetalj(ordrenr, delnr, kvantum) values(12,3,2);
|
||||
insert into ordredetalj(ordrenr, delnr, kvantum) values(12,201,50);
|
||||
insert into ordredetalj(ordrenr, delnr, kvantum) values(12,202,60);
|
||||
insert into ordredetalj(ordrenr, delnr, kvantum) values(13,51173,20);
|
||||
insert into ordredetalj(ordrenr, delnr, kvantum) values(14,201,100);
|
||||
insert into ordredetalj(ordrenr, delnr, kvantum) values(14,202,100);
|
||||
insert into ordredetalj(ordrenr, delnr, kvantum) values(14,51173,30);
|
||||
insert into ordredetalj(ordrenr, delnr, kvantum) values(15,201,100);
|
||||
insert into ordredetalj(ordrenr, delnr, kvantum) values(15,202,100);
|
||||
insert into ordredetalj(ordrenr, delnr, kvantum) values(16,201,50);
|
||||
insert into ordredetalj(ordrenr, delnr, kvantum) values(16,202,50);
|
||||
insert into ordredetalj(ordrenr, delnr, kvantum) values(16,51173,20);
|
||||
insert into ordredetalj(ordrenr, delnr, kvantum) values(16,1909,10);
|
||||
insert into ordredetalj(ordrenr, delnr, kvantum) values(17,1,10);
|
||||
insert into ordredetalj(ordrenr, delnr, kvantum) values(17,3,1);
|
||||
insert into ordredetalj(ordrenr, delnr, kvantum) values(17,4,5);
|
||||
insert into ordredetalj(ordrenr, delnr, kvantum) values(18,3,2);
|
||||
insert into ordredetalj(ordrenr, delnr, kvantum) values(18,4,8);
|
||||
|
||||
insert into prisinfo(delnr, levnr, katalognr, pris) values(51173,6,'37S',0.57);
|
||||
insert into prisinfo(delnr, levnr, katalognr, pris) values(51173,44,'312/2',0.44);
|
||||
insert into prisinfo(delnr, levnr, katalognr, pris) values(51173,82,'300021',0.35);
|
||||
insert into prisinfo(delnr, levnr, katalognr, pris) values(1,6,'97s',120.00);
|
||||
insert into prisinfo(delnr, levnr, katalognr, pris) values(1,9,'x120',219.99);
|
||||
insert into prisinfo(delnr, levnr, katalognr, pris) values(51200,6,'54s',7.35);
|
||||
insert into prisinfo(delnr, levnr, katalognr, pris) values(1909,9,'X7770',3.00);
|
||||
insert into prisinfo(delnr, levnr, katalognr, pris) values(201,44,'100/1',1.60);
|
||||
insert into prisinfo(delnr, levnr, katalognr, pris) values(201,6,'21s',1.90);
|
||||
insert into prisinfo(delnr, levnr, katalognr, pris) values(202,44,'101/1',1.50);
|
||||
insert into prisinfo(delnr, levnr, katalognr, pris) values(202,9,'22s',1.76);
|
||||
insert into prisinfo(delnr, levnr, katalognr, pris) values(3,82,'2077',1299.00);
|
||||
insert into prisinfo(delnr, levnr, katalognr, pris) values(4,82,'2177',899.00);
|
||||
insert into prisinfo(delnr, levnr, katalognr, pris) values(201,82,'3140',2.60);
|
||||
insert into prisinfo(delnr, levnr, katalognr, pris) values(202,82,'3141',1.50);
|
||||
insert into prisinfo(delnr, levnr, katalognr, pris) values(3,6,'34P',1199.00);
|
||||
insert into prisinfo(delnr, levnr, katalognr, pris) values(4,6,'67P',550.00);
|
||||
insert into prisinfo(delnr, levnr, katalognr, pris) values(1909,6,'53P',0.85);
|
||||
insert into prisinfo(delnr, levnr, katalognr, pris) values(202,6,'345u',6.50);
|
||||
insert into prisinfo(delnr, levnr, katalognr, pris) values(3,9,'a48',1050.00);
|
||||
|
350
ov4/losning.md
Normal file
350
ov4/losning.md
Normal file
@ -0,0 +1,350 @@
|
||||
---
|
||||
geometry: margin=30mm
|
||||
author: Felix Albrigtsen
|
||||
...
|
||||
|
||||
# Øving 4
|
||||
|
||||
## a. List ut all informasjon (ordrehode og ordredetalj) om ordrer for leverandør nr 44.
|
||||
|
||||
```sql
|
||||
SELECT *
|
||||
FROM ordrehode oh
|
||||
LEFT JOIN ordredetalj od
|
||||
ON oh.ordrenr = od.ordrenr
|
||||
WHERE levnr = 44;
|
||||
```
|
||||
|
||||
## b. Finn navn og by ("LevBy") for leverandører som kan levere del nummer 1.
|
||||
|
||||
```sql
|
||||
SELECT li.navn, li.levby
|
||||
FROM prisinfo pi
|
||||
LEFT JOIN levinfo li
|
||||
ON li.levnr = pi.levnr
|
||||
WHERE pi.delnr = 1;
|
||||
```
|
||||
|
||||
## c. Finn nummer, navn og pris for den leverandør som kan levere del nummer 201 til billigst pris.
|
||||
|
||||
```sql
|
||||
SELECT li.levnr, li.navn, pi.pris
|
||||
FROM prisinfo pi
|
||||
LEFT JOIN levinfo li
|
||||
ON li.levnr = pi.levnr
|
||||
WHERE pi.delnr = 201
|
||||
ORDER BY pi.pris
|
||||
ASC
|
||||
LIMIT 1;
|
||||
```
|
||||
|
||||
## d. Lag fullstendig oversikt over ordre nr 16, med ordrenr, dato, delnr, beskrivelse, kvantum, (enhets-)pris og beregnet beløp (=pris*kvantum).
|
||||
|
||||
Her har jeg brukt NATURAL JOIN i stedet for en equijoin for kortere spørringer, men de kunne like gjerne skrives som `JOIN ON a.egenskap = b.egenskap` for hver av egenskapene.
|
||||
```sql
|
||||
SELECT ordrenr, dato, delnr, beskrivelse, kvantum, pris AS stykkpris, kvantum * pris AS beløp
|
||||
FROM prisinfo
|
||||
NATURAL JOIN ordredetalj
|
||||
NATURAL JOIN ordrehode
|
||||
NATURAL JOIN delinfo
|
||||
WHERE ordrenr = 16;
|
||||
```
|
||||
|
||||
## e. Finn delnummer og leverandørnummer for deler som har en pris som er høyere enn prisen for del med katalognr X7770.
|
||||
```sql
|
||||
SELECT delnr, levnr
|
||||
FROM prisinfo pi
|
||||
WHERE pi.pris > (
|
||||
SELECT pris
|
||||
FROM prisinfo
|
||||
WHERE katalognr = "X7770"
|
||||
);
|
||||
```
|
||||
|
||||
## f.
|
||||
### i) Tenk deg at tabellen levinfo skal deles i to. Sammenhengen mellom by og fylke skal tas ut av tabellen. Det er unødvendigå lagre fylkestilhørigheten for hver forekomst av by. Lag én ny tabell som inneholder byer og fylker. Fyll denne med data fra levinfo. Lag også en tabell som er lik levinfo unntatt kolonnen Fylke. (Denne splittingen av tabellen levinfo gjelder bare i denneoppgaven. I resten av oppgavesettet antar du at du har den opprinnelige levinfo-tabellen.)
|
||||
|
||||
Jeg lager nye tabeller og overfører all relevant data fra levinfo.
|
||||
```sql
|
||||
|
||||
CREATE TABLE byer(
|
||||
levby VARCHAR(20) NOT NULL,
|
||||
fylke VARCHAR(20) NOT NULL,
|
||||
CONSTRAINT pk_byer PRIMARY KEY(levby)
|
||||
);
|
||||
|
||||
INSERT INTO byer (levby, fylke)
|
||||
SELECT levby, fylke
|
||||
FROM levinfo
|
||||
GROUP BY levby;
|
||||
|
||||
CREATE TABLE levinfo_nofylke(
|
||||
levnr INTEGER,
|
||||
navn VARCHAR(20) NOT NULL,
|
||||
adresse VARCHAR(20) NOT NULL,
|
||||
levby VARCHAR(20) NOT NULL,
|
||||
postnr INTEGER NOT NULL,
|
||||
CONSTRAINT levinfo_nofylke_pk PRIMARY KEY(levnr));
|
||||
|
||||
INSERT INTO levinfo_nofylke (levnr,navn,adresse,levby,postnr)
|
||||
SELECT levnr,navn,adresse,levby,postnr
|
||||
FROM levinfo;
|
||||
|
||||
```
|
||||
|
||||
### ii) Lag en virtuell tabell (view) slik at brukerne i størst mulig grad kan jobbe på samme måte mot de to nye tabellene som den gamle. Prøv ulike kommandoer mot tabellen (select, update, delete, insert). Hvilke begrensninger, hvis noen, har brukerne i forhold til tidligere?
|
||||
|
||||
```sql
|
||||
CREATE VIEW levinfo_medfylke AS
|
||||
SELECT li.*, b.fylke
|
||||
FROM levinfo_nofylke li
|
||||
LEFT JOIN byer b
|
||||
ON li.levby = b.levby;
|
||||
|
||||
```
|
||||
|
||||
Select fungerer akkurat som før, ingen merkbar forskjell.
|
||||
```sql
|
||||
MariaDB [idatt2103_ov4]> SELECT * FROM levinfo_medfylke WHERE fylke = "Oslo";
|
||||
+-------+---------------------+-------------+-------+--------+-------+
|
||||
| levnr | navn | adresse | levby | postnr | fylke |
|
||||
+-------+---------------------+-------------+-------+--------+-------+
|
||||
| 6 | Kontorekspressen AS | Skolegata 3 | Oslo | 1234 | Oslo |
|
||||
| 44 | Billig og Bra AS | Aveny 56 | Oslo | 1222 | Oslo |
|
||||
+-------+---------------------+-------------+-------+--------+-------+
|
||||
2 rows in set (0.051 sec)
|
||||
|
||||
MariaDB [idatt2103_ov4]> SELECT * FROM levinfo_medfylke WHERE levnr > 20;
|
||||
+-------+-------------------+-----------------+-----------+--------+--------------+
|
||||
| levnr | navn | adresse | levby | postnr | fylke |
|
||||
+-------+-------------------+-----------------+-----------+--------+--------------+
|
||||
| 44 | Billig og Bra AS | Aveny 56 | Oslo | 1222 | Oslo |
|
||||
| 81 | Kontorbutikken AS | Gjennomveien 78 | Ål | 3345 | Telemark |
|
||||
| 82 | Kontordata AS | Åsveien 178 | Trondheim | 7023 | S-Trøndelag |
|
||||
+-------+-------------------+-----------------+-----------+--------+--------------+
|
||||
3 rows in set (0.001 sec)
|
||||
|
||||
```
|
||||
|
||||
Update fungerer akkursat som før når man endrer egenskaper som ikke er fylke/by.
|
||||
|
||||
Om man bruker UPDATE til å endre en verdi i kolonnen "by", vil byen endre seg, og fylket vil automatisk følge etter, og bli satt til det fylket som hører til den nye byen, gitt i `byer`.
|
||||
Dette er ønsket oppførsel, og gjør oppdateringen lettere.
|
||||
```sql
|
||||
+-------+---------------------+------------------+-----------+--------+--------------+
|
||||
| levnr | navn | adresse | levby | postnr | fylke |
|
||||
+-------+---------------------+------------------+-----------+--------+--------------+
|
||||
| 6 | Kontorekspressen AS | Skolegata 3 | Oslo | 1234 | Oslo |
|
||||
| 9 | Kontorutstyr AS | Villa Villekulla | Ås | 1456 | Østfold |
|
||||
| 12 | Mister Office AS | Storgt 56 | Ås | 1456 | Østfold |
|
||||
| 44 | Billig og Bra AS | Pilestredet 4 | Oslo | 1222 | Oslo |
|
||||
| 81 | Kontorbutikken AS | Gjennomveien 78 | Ål | 3345 | Telemark |
|
||||
| 82 | Kontordata AS | Åsveien 178 | Trondheim | 7023 | S-Trøndelag |
|
||||
+-------+---------------------+------------------+-----------+--------+--------------+
|
||||
|
||||
MariaDB [idatt2103_ov4]> UPDATE levinfo_medfylke SET levby = "Oslo" WHERE levnr = 82;
|
||||
Query OK, 1 row affected (0.011 sec)
|
||||
Rows matched: 1 Changed: 1 Warnings: 0
|
||||
|
||||
+-------+---------------------+------------------+-------+--------+----------+
|
||||
| levnr | navn | adresse | levby | postnr | fylke |
|
||||
+-------+---------------------+------------------+-------+--------+----------+
|
||||
| 6 | Kontorekspressen AS | Skolegata 3 | Oslo | 1234 | Oslo |
|
||||
| 9 | Kontorutstyr AS | Villa Villekulla | Ås | 1456 | Østfold |
|
||||
| 12 | Mister Office AS | Storgt 56 | Ås | 1456 | Østfold |
|
||||
| 44 | Billig og Bra AS | Pilestredet 4 | Oslo | 1222 | Oslo |
|
||||
| 81 | Kontorbutikken AS | Gjennomveien 78 | Ål | 3345 | Telemark |
|
||||
| 82 | Kontordata AS | Åsveien 178 | Oslo | 7023 | Oslo |
|
||||
+-------+---------------------+------------------+-------+--------+----------+
|
||||
```
|
||||
|
||||
Et problem dukker derimot opp dersom man prøver å endre "fylke" direkte. Om man endrer på "fylke" i den nye viewet/vinduet, vil vi endre på tabellen `byer`i stedet for å endre på tabellen `levinfo_nofylke`. Altså kan man ved å endre på "fylke" på levnr 9 i eksempelet over fra "Østfold" til "Vestfold", vil det også endre på levnr 12.
|
||||
|
||||
```
|
||||
+-------+---------------------+------------------+-------+--------+----------+
|
||||
| levnr | navn | adresse | levby | postnr | fylke |
|
||||
+-------+---------------------+------------------+-------+--------+----------+
|
||||
| 6 | Kontorekspressen AS | Skolegata 3 | Oslo | 1234 | Oslo |
|
||||
| 9 | Kontorutstyr AS | Villa Villekulla | Ås | 1456 | Østfold |
|
||||
| 12 | Mister Office AS | Storgt 56 | Ås | 1456 | Østfold |
|
||||
| 44 | Billig og Bra AS | Pilestredet 4 | Oslo | 1222 | Oslo |
|
||||
| 81 | Kontorbutikken AS | Gjennomveien 78 | Ål | 3345 | Østfold |
|
||||
| 82 | Kontordata AS | Åsveien 178 | Oslo | 7023 | Oslo |
|
||||
+-------+---------------------+------------------+-------+--------+----------+
|
||||
|
||||
MariaDB [idatt2103_ov4]> UPDATE levinfo_medfylke SET fylke = "Vestfold" WHERE levnr = 9;
|
||||
Query OK, 1 row affected (0.011 sec)
|
||||
Rows matched: 1 Changed: 1 Warnings: 0
|
||||
|
||||
+-------+---------------------+------------------+-------+--------+----------+
|
||||
| levnr | navn | adresse | levby | postnr | fylke |
|
||||
+-------+---------------------+------------------+-------+--------+----------+
|
||||
| 6 | Kontorekspressen AS | Skolegata 3 | Oslo | 1234 | Oslo |
|
||||
| 9 | Kontorutstyr AS | Villa Villekulla | Ås | 1456 | Vestfold |
|
||||
| 12 | Mister Office AS | Storgt 56 | Ås | 1456 | Vestfold |
|
||||
| 44 | Billig og Bra AS | Pilestredet 4 | Oslo | 1222 | Oslo |
|
||||
| 81 | Kontorbutikken AS | Gjennomveien 78 | Ål | 3345 | Østfold |
|
||||
| 82 | Kontordata AS | Åsveien 178 | Oslo | 7023 | Oslo |
|
||||
+-------+---------------------+------------------+-------+--------+----------+
|
||||
```
|
||||
|
||||
De to tabellene i viewet henger ikke sammen med en triviell relasjon som en-til-en, så om en prøver å slette en tuppel får man en feilmelding.
|
||||
|
||||
```sql
|
||||
MariaDB [idatt2103_ov4]> DELETE FROM levinfo_medfylke WHERE levnr = 44;
|
||||
ERROR 1288 (HY000): The target table levinfo_medfylke of the DELETE is not updatable
|
||||
```
|
||||
|
||||
Inserts fungerer heller ikke i mitt tilfelle, da tabellen bruker OUTER JOIN som ikke er tillatt i følge [Dokumentasjonen](https://mariadb.com/kb/en/inserting-and-updating-with-views/).
|
||||
```
|
||||
MariaDB [idatt2103_ov4]> INSERT INTO levinfo_medfylke (levnr, navn, adresse, levby, postnr) VALUES (85, "Utstyrsbutikken AS", "Sem Sælandsvei 1", "Trondheim", 7034);
|
||||
ERROR 1471 (HY000): The target table levinfo_medfylke of the INSERT is not insertable-into
|
||||
```
|
||||
|
||||
Alle endringer som INSERT, UPDATE og DELETE kan fortstatt gjøres uten problem i de opprinnelige tabellene, de som vinduet baserer seg på.
|
||||
|
||||
|
||||
### g. Anta at en vurderer å slette opplysningene om de leverandørene som ikke er representert i Prisinfo-tabellen. Finn ut hvilke byer en i tilfelle ikke får leverandør i. (Du skal ikke utføre slettingen.) (Tips: Svaret skal bli kun én by, "Ål".)
|
||||
|
||||
```sql
|
||||
SELECT DISTINCT levby FROM levinfo WHERE levby NOT IN (SELECT levby FROM prisinfo LEFT JOIN levinfo ON prisinfo.levnr = levinfo.levnr);
|
||||
```
|
||||
|
||||
... men hvorfor er `SELECT DISTINCT levby FROM levinfo WHERE levnr NOT IN (SELECT levnr FROM prisinfo);` feil?
|
||||
|
||||
### h. Finn leverandørnummer for den leverandør som kan levere ordre nr 18 til lavest totale beløp (vanskelig).
|
||||
|
||||
deler og kvantum i ordren:
|
||||
> SELECT delnr, kvantum FROM ordredetalj WHERE ordrenr = 18;
|
||||
|
||||
Alle leverandører som kan levere delnr(minst en av) i ordre 18:
|
||||
> SELECT * FROM prisinfo RIGHT JOIN ordredetalj ON prisinfo.delnr = ordredetalj.delnr WHERE ordredetalj.ordrenr = 18;
|
||||
|
||||
Antall delnr (individuelle deltyper) hver leverandør kan levere:
|
||||
> SELECT levnr, COUNT(*) FROM kan_levere_deler GROUP BY levnr;
|
||||
|
||||
Finn alle levnr fra kan_levere_deler som kan levere like mange delnr som det er i ordre 18.
|
||||
> SELECT levnr FROM kan_levere_deler GROUP BY levnr HAVING (COUNT(*) = (SELECT COUNT(*) FROM ordredetalj WHERE ordrenr = 18));
|
||||
|
||||
Finn totalpris per del, fra leverandørene som kan levere alle delene
|
||||
> SELECT kld.levnr, pris*kvantum FROM kan_levere_deler kld RIGHT JOIN kan_levere_alle kla ON kld.levnr = kla.levnr;
|
||||
|
||||
Finn totalpris for hele ordren per leverandør:
|
||||
> SELECT kld.levnr, SUM(pris*kvantum) AS totalpris FROM kan_levere_deler kld RIGHT JOIN kan_levere_alle kla ON kld.levnr = kla.levnr GROUP BY kld.levnr ORDER BY totalpris;
|
||||
|
||||
```sql
|
||||
-- levnr og prisinfo for alle deler i ordre 18 hos alle leverandører som har delen
|
||||
CREATE VIEW kan_levere_deler AS
|
||||
SELECT pi.levnr, pi.delnr, pi.pris, kvantum
|
||||
FROM ordredetalj od LEFT JOIN prisinfo pi ON od.delnr = pi.delnr
|
||||
WHERE od.ordrenr = 18;
|
||||
|
||||
-- levnr og totalsum for alle leverandører som har alle delene
|
||||
CREATE VIEW kan_levere_alle AS
|
||||
SELECT levnr, SUM(pris*kvantum) AS totalpris
|
||||
FROM kan_levere_deler
|
||||
GROUP BY levnr HAVING (
|
||||
COUNT(*) = (SELECT COUNT(*) FROM ordredetalj WHERE ordrenr = 18)
|
||||
);
|
||||
|
||||
-- Hent ut kun leverandøren med den laveste totalprisen
|
||||
SELECT * FROM kan_levere_alle ORDER BY totalpris ASC LIMIT 1;
|
||||
|
||||
```
|
||||
|
||||
|
||||
# Oppgave 2: SQL med NULL-verdier
|
||||
|
||||
### a. Sett opp en SELECT-setning som er UNION mellom alle forlag med Oslo-nummer (telefonnummer begynner med 2) og alle som ikke er Oslo-nummer. Får du med forlaget med NULL-verdi på telefonnummer? Hvis ikke,utvid unionen med en mengde til.
|
||||
|
||||
```sql
|
||||
SELECT *
|
||||
FROM forlag
|
||||
WHERE telefon LIKE '2%'
|
||||
UNION
|
||||
SELECT *
|
||||
FROM forlag
|
||||
WHERE telefon NOT LIKE '2%'
|
||||
UNION
|
||||
SELECT *
|
||||
FROM forlag
|
||||
WHERE telefon IS NULL;
|
||||
```
|
||||
|
||||
### b. Sett opp SQL-setninger som finner gjennomsnittlig alder på forfattere der fødselsåret er oppgitt. For forfattere der dødsåret ikke er oppgitt, skal du kun ta med de som er født etter 1900.
|
||||
|
||||
#### Kan løses med view, enkelt å lese:
|
||||
```sql
|
||||
CREATE VIEW forfatter_fra_til AS
|
||||
SELECT forfatter_id, fornavn, etternavn, fode_aar AS fra, dod_aar AS til
|
||||
FROM forfatter
|
||||
WHERE fode_aar IS NOT NULL AND dod_aar IS NOT NULL
|
||||
|
||||
UNION
|
||||
|
||||
SELECT forfatter_id, fornavn, etternavn, fode_aar AS fra, YEAR(current_date()) as til
|
||||
FROM forfatter
|
||||
WHERE fode_aar IS NOT NULL AND dod_aar IS NULL AND fode_aar > 1900;
|
||||
|
||||
-- eksempel: se alle aldre:
|
||||
SELECT forfatter_id, fornavn, etternavn, til-fra AS alder FROM forfatter_fra_til;
|
||||
|
||||
-- finn gjennomsnittsalderen:
|
||||
SELECT SUM(til-fra)/COUNT(*) FROM forfatter_fra_til;
|
||||
```
|
||||
|
||||
#### Kan også løses uten view, med en lang spørring.
|
||||
```sql
|
||||
SELECT SUM(alder) / COUNT(*) FROM (
|
||||
SELECT dod_aar - fode_aar AS alder
|
||||
FROM forfatter
|
||||
WHERE fode_aar IS NOT NULL AND dod_aar IS NOT NULL
|
||||
|
||||
UNION
|
||||
|
||||
SELECT YEAR(current_date()) - fode_aar AS alder
|
||||
FROM forfatter
|
||||
WHERE fode_aar IS NOT NULL AND dod_aar IS NULL AND fode_aar > 1900
|
||||
) AS forfatter_alder;
|
||||
```
|
||||
|
||||
Uttrykkene summerer de fem forfatterne som stemmer med kravene, og gir resultatet 68.0 år.
|
||||
|
||||
### c. Sett opp SQL-setninger som finner hvor stor andel av forfatterne som ble med i beregningene under b).
|
||||
|
||||
```sql
|
||||
SELECT COUNT(forfatter_alder.forfatter_id), COUNT(forfatter.forfatter_id) FROM
|
||||
(
|
||||
-- forfattere som blir telt med i gjennomsnittet
|
||||
SELECT * FROM forfatter
|
||||
WHERE fode_aar IS NOT NULL
|
||||
AND ( dod_aar IS NOT NULL OR fode_aar > 1900 )
|
||||
) AS forfatter_alder
|
||||
RIGHT JOIN forfatter
|
||||
ON forfatter.forfatter_id = forfatter_alder.forfatter_id;
|
||||
```
|
||||
|
||||
Gir resultatet
|
||||
```
|
||||
+-------------------------------------+-------------------------------+
|
||||
| COUNT(forfatter_alder.forfatter_id) | COUNT(forfatter.forfatter_id) |
|
||||
+-------------------------------------+-------------------------------+
|
||||
| 5 | 12 |
|
||||
+-------------------------------------+-------------------------------+
|
||||
|
||||
```
|
||||
|
||||
Alternativ løsning som bruker vinduet opprettet tidligere, viser andel som prosent:
|
||||
```sql
|
||||
SELECT CONCAT(100 * COUNT(fft.forfatter_id) / COUNT(f.forfatter_id), '%') AS prosent_aldersbereging
|
||||
FROM forfatter_fra_til fft
|
||||
RIGHT JOIN forfatter f
|
||||
ON fft.forfatter_id = f.forfatter_id;
|
||||
|
||||
+------------------------+
|
||||
| prosent_aldersbereging |
|
||||
+------------------------+
|
||||
| 41.6667% |
|
||||
+------------------------+
|
||||
```
|
||||
|
3
ov5/db_setup.sql
Normal file
3
ov5/db_setup.sql
Normal file
@ -0,0 +1,3 @@
|
||||
CREATE DATABASE idatt2103_ov5;
|
||||
GRANT ALL PRIVILEGES ON idatt2103_ov5.* TO 'idatt2103'@'localhost';
|
||||
FLUSH PRIVILEGES;
|
Loading…
Reference in New Issue
Block a user