Såg att en del fallit bort vilket gör att man bör få ett felmeddelande
create view utgift as
select b.reg_nr, sum(k.summa) as kostnad
from bil b, kostnad k
måste vara
create view utgift as
select b.reg_nr, sum(k.summa) as kostnad
from bil b, kostnad k
where b.id = k.bil_id
group by b.reg_nr;
Lösningsförslag till några frågor.
Man kan skapa vyer genom
create view inkomst as
select b.reg_nr, sum(u.kostnad) as summa
from bil b, uthyrning u
where b.id = u.bil_id group by b.reg_nr;
och
create view utgift as
select b.reg_nr, sum(k.summa) as kostnad
from bil b, kostnad k
where b.id = k.bil_id
group by b.reg_nr
och då kan man hitta bilen som kostat minst med vyn utgift:
select * from utgift where kostnad =
(select min(kostnad) from utgift);
reg_nr | kostnad
--------+---------
FTE543 | 5380.00
Man kan hitta bilen som ger största vinsten genom att använda båda vyerna:
select reg_nr, summa - kostnad as vinst
from inkomst natural join utgift
where summa - kostnad =
(select max (summa - kostnad) from
inkomst natural join utgift);
reg_nr | vinst
--------+---------
FTE543 | 3145.00
Som koll på att man gjort rätt kan man använda båda vyerna så:
select reg_nr, summa as inkomst, kostnad, summa - kostnad as vinst
from inkomst natural join utgift;
reg_nr | inkomst | kostnad | vinst
--------+---------+---------+----------
FTE543 | 8525.00 | 5380.00 | 3145.00
USB220 | 1697.00 | 7684.00 | -5987.00
UUZ445 | 401.00 | 6591.00 | -6190.00
Och om man med "kostar minst" menar kostnad för kunden är det ju lätt
utan vyer:
select b.reg_nr, k.dygnspris, k.kilometerpris from
bil b, modell m, kategori k
where b.model_id = m.id and m.kategori_id = k.id
and k.dygnspris = (select min (dygnspris) from kategori);
reg_nr | dygnspris | kilometerpris
--------+-----------+---------------
FTE543 | 299.00 | 2.00
När man skapar vyer så lagras dessa i databasen och med många långa och krångliga vyer blir det mycket extra i databasen så, speciellt i applikationsprogram med mycket komplicerade frågeställningar brukar man istället använda "WITH" för att skapa konstruktioner som bara existerar under exekvering av SQL-satsen. Dessa, ofta svåröverblickbara, SQL-satser syns ju inte för användarna utan ligger gömda i programkoden så det gör inget att de är svåra att läsa och förstå för gemene man. Några av frågorna ovan blir då som följer.
Vilken bil har kostat företaget minst? :
with utgift as (select b.reg_nr, sum(k.summa) as kostnad
from bil b, kostnad k where b.id = k.bil_id
group by b.reg_nr)
select * from utgift where kostnad =
(select min(kostnad) from utgift);
reg_nr | kostnad
--------+---------
FTE543 | 5380.00
Vilken bil ger störst vinst? :
with inkomst as (select b.reg_nr, sum(u.kostnad) as summa
from bil b, uthyrning u
where b.id = u.bil_id group by b.reg_nr),
utgift as (select b.reg_nr, sum(k.summa) as kostnad
from bil b, kostnad k
where b.id = k.bil_id
group by b.reg_nr)
select reg_nr, summa - kostnad as vinst
from inkomst natural join utgift
where summa - kostnad =
(select max (summa - kostnad) from
inkomst natural join utgift);
reg_nr | vinst
--------+---------
FTE543 | 3145.00
Och
Frågan "Ta ut totalkostnad för en viss bränsletyp över en period" kan besvaras ganska enkelt genom att vara lite finurlig när man skapar en vy för bilar och deras bränsletyp:
create view bilbränsle as select b.id as bil_id, m.bränsle_typ
from bil b, modell m where b.model_id = m.id;
Jag har alltså döpt om bil.id till bil_id, samma namn som används i kostnadstabellen för att referera till bil.id. Då kan jag använda naturlig join för att kombinera mig fram till kostnaden för en viss bränsletyp. Alltså kan jag få svar på den mer explicita frågan "Vad var totalkostnaden för bensin under mars månad 2016?" med SQL-satsen:
select sum(summa) from kostnad natural join bilbränsle
where typ = 'Bränsle' and bränsle_typ = 'bensin'
and datum > '2016-02-29' and datum < '2016-04-01';
sum
---------
6425.00
Kan också besvaras med en "SELECT WITH"-sats:
with bilbränsle as (select b.id as bil_id, m.bränsle_typ
from bil b, modell m where b.model_id = m.id)
select sum(summa) from kostnad natural join bilbränsle
where typ = 'Bränsle' and bränsle_typ = 'bensin'
and datum > '2016-02-29' and datum < '2016-04-01';
sum
---------
6425.00
Vilken bil ger störst vinst? :
with inkomst as (select b.reg_nr, sum(u.kostnad) as summa
from bil b, uthyrning u
where b.id = u.bil_id group by b.reg_nr),
utgift as (select b.reg_nr, sum(k.summa) as kostnad
from bil b, kostnad k
where b.id = k.bil_id
group by b.reg_nr)
select reg_nr, summa - kostnad as vinst
from inkomst natural join utgift
where summa - kostnad =
(select max (summa - kostnad) from
inkomst natural join utgift);
reg_nr | vinst
--------+---------
FTE543 | 3145.00
Jag får samma resultat om jag gör såhär:
select reg_nr, summa as inkomst, kostnad, summa - kostnad as vinst
from inkomst
natural join utgift
where summa - kostnad = (select max( summa - kostnad) from inkomst natural join utgift);
Jag får samma resultat om jag gör såhär:
select reg_nr, summa as inkomst, kostnad, summa - kostnad as vinst
from inkomst
natural join utgift
where summa - kostnad = (select max( summa - kostnad) from inkomst natural join utgift);
Men då har du väl kvar vy-definitionerna? Släng dem med
DROP VIEW inkomst, utgift;
Avsikten med "WITH ... SELECT" är just att slippa lagra vyer.
Om du i postgresql ger kommandot "\d" ser du vilka tabeller, vyer, sekvenser, mm som lagrats i databasen.
Släng alla vyer och använd WITH istället. Jag säger inte att det är ett bättre sätt, bara att man kan göra så för att slippa vyhanteringen.
...
DÅ till frågan, TROR ni att det är möjligt för mig att lära mig skapa en sådan databas till 10 januari och hur avancerat är det egentligen?
Hur gick det? Blev de impade av din mestadels kopierade lösning ?
Spelnyheter från FZ
Copyright © 1999–2025 Geeks AB. Allt innehåll tillhör Geeks AB.
Citering är tillåten om källan anges.