Beruflich Dokumente
Kultur Dokumente
University of Hertfordshire
Department of Computer Science
PNAME
mansell
dury
currie
gooch
gooch
minogue
TITLE
mr
mrs
mrs
mr
mrs
miss
DOB
23-May-61
05-Jun-64
13-Jan-55
12-Apr-53
03-Jun-59
03-Aug-69
CHILDREN
2
0
3
1
1
0
DOI
20-Apr-87
12-Mar-91
10-Jul-88
04-Sep-90
05-Aug-89
COST
0.15
5.00
1.89
0.90
1.66
GP
Dr.Williams
Dr.Taylor
Dr.Thatcher
Dr.Spock
Dr.Spock
Dr.Williams
DRUG
DNO
d1
d2
d5
d7
d6
DNAME
sweet dreams
bliss
fly high
split
slow down
UNIT
tab
mg
mg
tab
gm
DOSE
PNO
p4
p2
p4
p1
p7
p8
p4
p4
p1
p4
p1
p8
p4
DNO
d5
d6
d5
d1
d1
d7
d6
d7
d7
d2
d6
d2
d1
DOSEDATE
01-Feb-94
12-Jul-94
10-Sep-94
02-Oct-94
20-Oct-94
05-Nov-94
30-Nov-94
02-Jan-95
03-Mar-95
01-Apr-95
05-May-95
31-May-95
05-Jun-95
QTY
5
3
5
3
6
2
2
8
6
3
2
1
6
Note that this database was created some years ago, and so 02-Jan-95 was interpreted
by Oracle at creation time to mean 02-Jan-1995. If you type the string 02-Jan-95 now
it will assume you are referring to 02-Jan-2095.
I might recreate the database, in which case the above will not apply.
REFERENCE ONLY
This shows you how the tables were created, you do not need to do this to yourself as
you can copy populated tables from your lecturer
ORACLE SQL Data Definition Language (DDL)
CREATING A TABLE
BASIC FORMAT OF COMMAND:
CREATE TABLE tablename (columnname format
{,columnname format}
{,primary key/foreign key format});
eg
CREATE TABLE Patient
(Pno
VARCHAR2(4) NOT NULL,
Pname
VARCHAR2(15) NOT NULL,
Title
VARCHAR2(4),
Dob
DATE,
Children
NUMBER(2),
GP
VARCHAR2(15),
Primary Key (Pno) );
CREATE TABLE Drug
(Dno
VARCHAR2(4) NOT NULL,
Dname
VARCHAR2(20),
Unit
VARCHAR2(3),
Doi
DATE,
Cost
NUMBER(6,2),
Primary Key (Dno) );
CREATE TABLE Dose
(Pno
VARCHAR2(4) NOT NULL,
Dno
VARCHAR2(4) NOT NULL,
DoseDate
DATE
NOT NULL,
Qty
NUMBER(4),
Primary Key (Pno,Dno,Dosedate),
Foreign Key (Pno) references Patient(Pno),
Foreign Key (Dno) references Drug(Dno) );
ORACLE DATA TYPES
When a table is created in Oracle it needs to know what type of data is to be stored in
each column (attribute).
The main data types recognised by Oracle are:
char(n)
fixed length character string of n characters
number(n,d)
number made up of n digits with d decimal places.
number(n)
whole number made up of n digits
date
varchar2(n)
variable length character string having maximum length
n
3
REFERENCE ONLY
ORACLE SQL DDL
CREATING AN INDEX
BASIC FORMAT OF COMMAND:
CREATE [UNIQUE] INDEX indexname
ON tablename(columnname{,columname});
eg
Insert
Update
Delete
Select
BASIC FORMAT:
SELECT
FROM
WHERE
a1,a2,.
r1,r2,.
p;
[attribute(s)]
[relation(s)]
[predicate]
Select Examples:
1.
*
drug;
Get the drug names of all drugs in the database together with their code
numbers.
select
from
dname,dno
drug;
Result is output of all rows in drug table but just showing the two columns:
DNAME
sweet dreams
bliss
..
DNO
d1
d2
..
3.
dname
drug
unit='tab';
Result:
DNAME
sweet dreams
split
4.
I need drug nos of drugs in tablet form that cost more than 50p each.
select
from
where
and
dno
drug
unit='tab'
cost>0.50;
Result:
DNO
d7
5.
List patient nos of patients who have Dr. Spock, Dr. Taylor, or Dr. Thatcher as
their GPs.
select
from
where
or
or
pno
patient
gp='Dr.Spock'
gp='Dr.Taylor'
gp='Dr.Thatcher';
Alternatively:
select
from
where
6.
Get the patient nos of all patients except those of Drs Spock, Taylor and
Thatcher.
select
from
where
7.
pno
patient
gpin
('Dr.Spock','Dr.Taylor',Dr.Thatcher')
pno
patient
gpnotin
('Dr.Spock',Dr.Taylor','Dr.Thatcher');
I want the patient names of patients who have been given drug d7.
select
from
where
and
pname
patientp,dosed
p.pno=d.pno
d.dno='d7';
6
beware: finding the names of patients who have NOT been given drug d7 takes
a bit of thought
8.
Get the patient names of Dr. Spock's patients who have been given drug d7.
select
from
where
and
and
9.
Find the patient names of patients who have been given drugs costing more
than 1.75 per unit.
select
from
where
and
and
10.
pname
patientp,dosed
p.pno=d.pno
d.dno='d7'
p.gp='Dr.Spock';
pname
patient
p.pno =
d.dno =
dr.cost
p, dose d, drug dr
d.pno
dr.dno
> 1.75 ;
I know you gave me patient names of patients who have been given drug d7 in
query 7 but I've lost the result so please do it again.
select
from
where
pname
patient
pnoin
(selectpno
fromdose
wheredno='d7');
Now you know a way to find who has not taken drug d7.
11.
pname
patient
pnoin
(selectpno
fromdose
wherednoin
(selectdno
fromdrug
wherecost>1.75));
AGGREGATE FUNCTIONS
Common set or aggregate functions can be used in SQL
The ones supported in most systems are:
COUNT
SUM
AVG
MAX
MIN
avg(cost)as"meancost"
drug
unit='tab';
Output:
meancost
0.53
13.
count(distinctgp)
patient;
Output:
count
4
14.
15.
16.
Now get the total quantities of each of the drugs that we have prescribed.
select
dno,sum(qty)as"total"
from dose
groupby
dno;
8
Output
dno
d1
d2
d5
d6
d7
17.
total
15
4
10
7
16
Fine, but I really only wanted those drugs with 10 or more units used.
select
from
groupby
having
dno,sum(qty)as"total"
dose
dno
sum(qty)>=10;
Output:
dno
d1
d5
d7
18.
total
15
10
16
dno,sum(qty)as"total"
dose
dno
sum(qty)>=10
totaldesc;
Output:
dno
d7
d1
d5
19.
total
16
15
10
I don't want any drugs that have been given to patient p7 to be included in the
totals
select
from
where
groupby
having
orderby
dno,sum(qty)as"total"
dose
pno!='p7'
dno
sum(qty)>=10
totaldesc;
Output
dno
total
9
d7
d5
16
10
22.
I want to add a new patient but all I have is his pno and name.
insert into patient (pname,pno)
values ('major','p9') ;
24.
I now have some further data on this patient that I want to put in the table.
update patient
set title = 'mr', dob = '3-Nov-1941'
where pno = 'p9' ;
25.
For some reason all of Dr Williams' patients have had their dose quantities
recorded wrongly!
update dose
set qty = qty 1
where pno in
(select pno
from patient
where gp = 'Dr.Williams');
I want to delete all the data on patient p2 from the dose table
delete
from dose
where pno = 'p2' ;
27.
11
dname
drug
doi > '31-Dec-1988' ;
29. List drug names of drugs more than 5 years old together with their age in days
select
from
where
30. List patient nos of patients who were given drugs within 5 years of their
introduction
select
from
where
and
pno
drug dr, dose ds
dr.dno = ds.dno
months_between(dosedate,doi) <= 60 ;
12
PATTERN MATCHING
32. List patients of Dr. Tailor or is it Dr. Taylor
select
from
where
*
patient
gp like 'Dr.Ta_lor%';
33. List the data we have on drugs with the word 'dreams' in their name.
select
from
where
*
drug
dname like '%dreams%';
34. All we know about this patient was they were born after Jan 1st 1970 and they
have the letters 'nog' somewhere in their name;
select
from
where
and
*
patient
pname like '%nog%'
dob > '1-jan-1970' ;
35. I'm not interested in the drugs that have names starting with 'slow', but I want data
on the others.
select
from
where
*
drug
dname not like 'slow%' ;
36. I want information on Dr. William's patients but I'm not sure how the names of
GPs are stored in the database
select
from
where
*
patient
upper(gp) like '%WILLIAMS%';
13
salary
20k
15k
18k
37. List of names of employees who earn more than their boss.
Select
from
where
and
e.name
employee e, employee b
e.boss = b.name
e.salary > b.salary ;
Employee (e)
name
boss
Hubert
Harriet
Heather Hubert
Harriet
salary
20k
15k
18k
Employee (b)
name
boss
Hubert
Harriet
Heather Hubert
Harriet
salary
20k
15k
18k
intermediate table
e.name e.boss e.salary
Hubert Harriet 20k
Heather Hubert 15k
b.name
Harriet
Hubert
b.boss
Harriet
b.salary
18k
20k
Result:
Name
Hubert
FURTHER SQL EXAMPLES:
38.
39.
40.
pname
patient p
exists
(select
from
where
and
*
dose d
p.pno = d.pno
d.dno = 'd7') ;
41.
pname
patient p
not exists
(select
from
where
and
*
dose d
p.pno = d.pno
d.dno = 'd7) ;
42.
List wanted of patients together with the drugs they have been given (include
those who have not been given any drugs).
select
from
pno,dno
dose
union
select
from
where
pno,'none'
patient p
not exists
(select
from
where
*
dose d
p.pno=pno) ;
(NB You can achieve the same thing with an OUTER JOIN SQLPlus has a simple
version of an outer join)
15
Using null
- Say incomplete details of a drug are put in:
insert into drug(dno,cost)
values ('d10',2.99);
43
- Then if we want to know which drugs have not had a name entered for them:
select dno
from drug
where dname is null;
44
dno
drug
dname is not null;
CALCULATIONS
45
46
For each drug how much is the maximum quantity given above the average
quantity?
select
from
group
16
DATA INDEPENDENCE
LOGICAL DATA INDEPENDENCE
- a change to the logical structure of the data should result in no need to change the
logic of existing uses of the data.
PHYSICAL DATA INDEPENDENCE
- a change to the mechanisms for accessing and storing data should result in no need
to change the logic of existing uses of the data.
VIEWS
A view is a virtual table
ie a table that does not exist in its own right but looks to the user as if it did.
A view is a way to let each user see the parts of the database that they need, in the
format that is most easily understood by them.
1.
Joan is only ever interested in drugs costing more that 1 per unit.
a)
b)
*
deardrugs
doi >'1-Jan-1989';
select
from
where
and
dno,unit,doi,cost
drug
doi >'1-Jan-1989'
cost > 1.00;)
Output
dno
d2
d6
unit
mg
gm
doi
12-Mar-91
5-Aug-89
cost
5.00
1.66
17
2.
Jane is only interested in prescriptions of 5 or more units and wants to use her
own names for the columns and wants them in a different order.
create view bigdose(drug,qty,patient,dategiven)
as
select
dno,qty,pno,dosedate
from
dose
where
qty >=5;
3.
Jim also is only interested in what is in Jane's view but doesn't need patient
data and also wants to use his own terms
create view newbigdose(drugno,dose,date)
as
select
drug,qty,dategiven
from
bigdose
where
dategiven > '1-Jan-1991' ;
4.
Jack wants all the data in the dose table but frequently needs the patients'
names as well
create view patdose(pno,pname,dno,dosedate,qty)
as
select
p.pno,pname,dno,dosedate,qty
from
patient p,dose d
where
p.pno = d.pno;
note in this case, as the attributes in the view have the same
names as those in the defining query, you could omit the
attribute names shown in italics.
5.
Jo doesn't deal in codes and often wants the names of patients, which drugs
they have been given and how much.
create view patdrug(patname,drug,qty)
as
select
pname, dname,qty
from
patient p,drug dr,dose ds
where
p.pno = ds.pno
and
ds.dno = dr.dno;
patname
dury
..
minogue
minogue
minogue
drug
sweet dreams
.
sweet dreams
split
slow down
qty
6
.
3
6
2
18
any columns in the view are derived from an expression or aggregate (set)
function
the insert is in conflict with the where condition of the view and the WITH
CHECK OPTION is specified
there is a column in the underlying base table defined as NOT NULL which is not
in the view
attempting to update a column in conflict with the view's qualification and the
WITH CHECK OPTION is specified
Example 1)
create view drugcost(dno,cost)
as
select dno, cost from drug;
dno
cost
d1
0.15
d2
5.00
d5
1.89
d7
0.90
d6
1.66
OK to modify this view because
a)
it is drawn from only one base table
b)
none of the missing columns is NOT NULL
Example 2)
create view agecost(doi,cost)
as
select doi, cost from drug:
doi
20-Apr-87
12-May-91
10-Jul-88
4-Sep-90
5-Aug-89
cost
0.15
5.00
1.89
0.90
1.66
19
Here we can
- update e.g. update agecost set cost = 1.15 where cost = 0.15;
- delete e.g. delete from agecost where cost = 5.00;
- but we CANNOT insert ( because the key, which is not included in the view is
NOT NULL)
Example 3)
There are potential problems if the view has a restriction on the values in a column.
Updating that value might mean the whole row disappears from the view
and cannot be retrieved. Putting 'with check option' into the definition of
the view prevents this.
create view deardrugs (dno,unit,doi,cost)
as
select
dno,unit,doi,cost
from
drug
where
cost > 1.00
with
check option;
dno
d2
d5
d6
unit
mg
mg
gm
Then update
set
where
doi
12-Mar-91
10-Jul-88
5-Aug-89
cost
5.00
1.89
1.66
deardrugs
cost = 0.50
dno = 'd2';
20
c)
without a view:
ii)
with a view:
select
from
where
and
and
select
from
where
d)
dname
patient p,drug dr,dose ds
p.pno = ds.pno
ds.dno = dr.dno
pname= 'minogue' ;
dname
patdrug
patname = 'minogue';
21
2.
3.
4.
5.
6.
7.
List names of drugs which cost less than 1.00 per unit.
8.
List names of drugs that are in 'mg' or 'gm' units together with their date of
introduction.
9.
10.
List patient nos and dates of birth of patients who have between 1 and 3
children and whose GP is Dr.Williams.
SECTION B
11.
Get the names of patients who have been given drug d1.
12.
13.
14.
List patient nos of patients who have been given drugs in tablet form.
15.
List names of patients who have been given drugs in tablet form.
16.
Who are the GPs who have patients who have been given bliss?
17.
Get patient name, drug name and dosedate for doses given to patients with two
children or less, of drugs costing more than 1.00, in quantities of 5 or less.
SECTION C
18.
19.
20.
21.
22.
What is the total amount of the drug 'split' that has been prescribed?
23.
What is the patient no of the patient who has been given the highest dosage of
drug d7 (in one prescription)?
24.
What is the total number of patients that each GP has in the hospital?
25.
List the total dosage of each different drug given to patient p4 starting with the
highest and leaving out any totals less than 5.
SECTION D
26.
Put in a new patient, Mrs. Lee who has 2 children and was born on 23-May50. ( i.e. 1950)
27.
Modify the database to reflect that all of Dr.Spock's patients have been taken
over by Dr.Owen.
28.
Modify the database to reflect that mrs currie has died and we wish to remove
any reference to her.
SECTION E
29.
30.
31.
Get names of patients who were less than 30 years old at the start of this year.
32.
List names of patients given drugs in tablet form after their 30th birthday.
33.
34.
23
List all the drug names together with quantity prescribed to patients of all GPs
other than Dr. Spock.
36.
List patient names of patients who have the same GP as mr. mansell.
37.
List names of drugs introduced after the drug 'slow down' was.
SECTION F
Set up views which will look like the following to the users:
38.
39.
40.
Get the names of patients who have been given drug d1 (compare with q11)
42.
What was the date and the cost of the most expensive prescription for the drug
'split' since the beginning of 1995?
43.
Get the drug names, total qty and total cost for drugs in tablet form.
44.
Get the drug name of the drug that has cumulatively been the most costly drug
prescribed since the start of 1995.
45.
Which (if any) of the above views can be used for inserting, updating and
deleting?
24
select *
from drug;
2.
3.
select qty,dosedate
from dose
where pno = 'p4';
4.
select *
from patient
where title in ('mrs','miss','ms');
5.
select pname
from patient
where GP != 'Dr.Spock';
6.
select dob
from patient
where pname = 'gooch'
and title = 'mr';
7.
select dname
from drug
where cost < 1.00;
8.
select dname,doi
from drug
where unit = 'mg'
or unit = 'gm'
9.
select pno
from patient
where children between 1 and 3;
or
select pno
from patient
where children >= 1
and children <= 3;
10.
or
25
SECTION B
11.
select pname
from patient p.dose d
where p.pno = d.pno
and dno = 'd1' ;
or
select pname
from patient
where pno in
(select pno
from dose
where dno = 'd1');
12.
select dname
from drug dr,dose d
where dr.dno = d.dno
and pno = 'p1' ;
or
select dname
from drug
where dno in
(select dno
from dose
where pno = 'p1');
13.
select pname,dno,qty
from patient p,dose d
where p.pno = d.pno
and gp = 'Dr.Williams'
and qty >= 5 ;
14.
or
15.
or
16.
select distinct gp
from patient p,dose d,drug dr
where p.pno = d.pno
and d.dno = dr.dno
and dname = 'bliss';
or
select distinct gp
from patient
where pno in
(select pno
from dose
where dno in
(select dno
from drug
where dname='bliss'));
26
17.
select pname,dname,dosedate
from patient .dose d,drug dr
where p.pno = d.pno
and d.dno = dr.dno
and cost > 1.00
and qty <= 5
and children <= 2;
SECTION C
18.
19.
20.
21.
22.
23.
24.
25.
SECTION D
26.
27.
Update patient
set gp = 'Dr.Owen'
where gp = Dr.Spock' ;
28.
we have to remove rows from both the dose table and the patient table. One
way is to use a transaction to make sure that both these actions happen,
another way is to have declared a referential contraint with cascade delete
when the tables were created. Here we assume no cascade delete is in place:
set autocommit off;
Delete
from dose
where pno in
(select pno
from patient
where pname = 'currie'
and title = 'mrs') ;
Delete
from patient
where pname = 'currie'
and title = 'mrs' ;
Commit;
Set autocommit on;
SECTION E
29.
select *
from patient
where pname like 'gooc%' ;
30.
select *
from dose
where dosedate >= '1-jan-95'
and dosedate <= '31-dec-1995' ;
31.
select pname
from patient
where trunc((To_Date('1-jan-1995') dob)/365.25)<30;
32.
select pname
from drug dr, dose d, patient p
where dr.dno = d.dno
28
select *
from patient
where title is null or dob is null or children is null
or gp is null;
34.
35.
select dname,sum(qty)
from drug dr, dose d, patient p
where dr.dno = d.dno
and d.pno = p.pno
and gp != 'Dr.Spock'
group by dname
UNION
select dname, 0
from drug dr
where dno not in
(select dno
from dose d, patient p
where p.pno = d.pno
and gp!= 'Dr.Spock') ;
36.
select pname
from patient
where gp in
(select gp
from patient
where pname = 'mansell' and title = 'mr');
37.
select dname
from drug
where doi>
(select doi
from drug
where dname = 'slow down');
SECTION F
38.
39.
40.
41.
select patname
from patientdose
where drugno = 'd1'
42.
select dategiven,dosecost
from drugdose
where drugname = 'split'
and dosecost in
(select max(dosecost)
from drugdose
where drugname = 'split')
43.
select drugname,totalqty,totalcost
from drugsummary ds,drug dr
where ds.drugname = dr.dname
and unit = 'tab';
44.
select drugname
from drugdose
group by drugname
having sum(dosecost) in
(select max(sum(dosecost))
from drugdose
group by drugname);
30
Key:
{.} means optionally a further 1 or more
[.] means optional once
A|B means A or B
32