HW #2 Answer Key
Chapter 3:
#3.2
A relation schema is a type definition. A relation is an instance of that schema. For example, student(ss#, name) is a relation schema and
ss# name
123-45-6789 Tom Jones
456-78-9012 Joe Brown
is a relation based upon that schema.
#3.3
person (driver-id, name, address)
car (license, year, model)
accident (report-number, location, date)
owns (driver-id, license)
participated (license, driver-id, report-number, damage amount)
#3.5
(a) P person-name (s company-name = "First Bank Corporation" (works))
(b) P person-name, city (employee |X| (s company-name = "First Bank Corporation" (works)))
(c) P person-name, street, city (employee |X|
(s salary > 10K Ù company-name = "First Bank Corporation" (works)))
(d) P person-name (works |X| employee|X| company)
(e) P person-name ((employee |X| manages)
|X| manager-name = employee2.person-name Ù employee.street = employee2.street Ù employee.city = employee2.city (r employee2 (employee))
(f) P person-name (s company-name != "First Bank Corporation" (works))
(g) P person-name (works) ¾ (P works.person-name (works
|X| (works.salary<=works2.salary Ù works2.company-name = "Small Bank Corporation")
r
works2 (works)))(h) P company-name (company ¸
P
city (s company-name = "Small Bank Corporation" (company)))#3.6
The rewritten query is:
P
customer-name, customer-city (borrower |X| loan |X| customer)(a) Jackson has a loan, but no address is given for Jackson in the customer relation. Since no tuple in customer joins with the jackson tuple of borrower, jackson does not appear in the result.
(b) The best solution is to insert an address for Jackson in the customer relation. Null values may be used if no values are known; alternatively a special value (such as unknown) that is an unlikely value for an actual address might be used.
(c)
P
customer-name, customer-city ((borrower
#3.7
The left outer theta join of r(R) and s(S) can be defined as
(r theta-join s) È ((r - P R (r theta-join s)) ´ (null, null, null, … null))
where the tuple of nulls is of size equal to the number of attributes in S.
Similarly, the right outer theta join of r(R) and s(S) can be defined as
(r theta-join s) È ((s - P S (r theta-join s)) ´ (null, null, null, … null))
where the tuple of nulls is of size equal to the number of attributes in R.
And the full outer theta join of r(R) and s(S) can be defined as
(r theta-join s) È ((r - P R (r theta-join s)) ´ (null, null, null, … null))
È ((s - P S (r theta-join s)) ´ (null, null, null, … null))
where the first tuple of nulls is the same size as R and the second tuple of nulls is the same size as S.
#3.8
My mistake -- I told you that you would not be responsible for the updates section in the relational algebra, and then I assigned a question on that section. This question will not be graded.
#3.9
(a) P account-number (s count-names>2(account-number G count(customer-name) as count-names (depositor)))
(b) t1 ¬ (r d1(depositor) ´ r d2(depositor) ´ r d3(depositor))
t2 ¬ s d1.account-number = d2.account-number Ù d2.account-number = d3.account-number (t1)
P d1.account-number (s d1.customer-name != d2.customer-name Ù d2.customer-name != d3.customer-name Ù d1.customer-name != d3.customer-name (t2)
#3.16
(a) P A (s B=17 (r))
(b) r
s
(c) P A (r) È (r ¸ s B (P C (s)))
(d) P r.A (r
s )
(s c=r2.A Ù r.B > r2.B (r r2(r)))
#4.1
One typographical note: The second attribute of the participated relation in figure 4.12 should be license, not car. License is an attribute name; car is a relation name.
(a) select count (distinct name)
from accident, participated, owns, person
where person.driver-id = owns.driver-id and
owns.license = participated.license and
participated.report-number = accident.report-number and
date between 89/00/00 and 89/12/31
(b) select count (distinct *)
from accident
where exists
(select *
from participated, owns, person
where accident.driver = participated.driver and
owns.driver-id# = person.driver-id# and
participated.license = owns.license and
person.name = "John Smith")
(c) insert into accident
values ("AZ573", 04/17/2003, "Aspen Hill")
insert into participated
values ("000-23-5543", "HJN464", "AZ573", 3500)
(d) delete car
where model = "Mazda" and license in
(select license
from person p, owns o
where p.name = "John Smith" and p.driver-id# = o.driver-id#)
Note: this deletes every Mazda that John Smith owns, if he owns more than one.
(e) update participated
set damage-amount = 3000
where report-number = "AR2197" and license = "AABB2000"
#4.2
(a) select employee-name
from works
where company-name = "First Bank Corporation"
(b) select e.employee-name, city
from works w, employee e
where company-name = "First Bank Corporation" and
e.employee-name = w.employee-name
(c) select e.employee-name, street, city
from works w, employee e
where company-name = "First Bank Corporation" and
e.employee-name = w.employee-name and
w.salary > 10,000
(d) select e.employee-name
from works w, employee e, company c
where c.city = e.city and
e.employee-name = w.employee-name and
w.company-name = company.company.name
(e) select e.employee-name
from employee e, employee x, manages m
where e.employee-name = m.employee-name and
x.employee-name = m.manager-name and
e.street = x.street and
e.city = x.city
(f) select employee-name
from works
where company-name != "First Bank Corporation"
(g) select employee-name
from works
where salary > all
(select salary
from works
where company-name = "Small Bank Corporation")
(h) select T.company-name
from company T
where not exists
((select R.city
from company R
where R.company-name = "Small Bank Corporation")
except
(select S.city
from company S
where S.company-name = T.company-name))
(i) select w.employee-name
from works w
where w.salary >
(select avg (x.salary)
from works x
where w.company-name = x.company-name )
(j) select company-name
from works
group-by company-name
having count (distinct employee-name) >= all
(select count (distinct employee-name)
from works
group-by company-name)
(k) select company-name
from works
group-by company-name
having sum (salary) <= all
(select sum (salary)
from works
group-by company-name)
(l) select company-name
from works
group-by company-name
having avg (salary) >
(select avg ( salary)
from works
where company-name = "First Bank Corporation")
#4.4 given the following relation schemas:
R = (A, B, C)
S = (D, E, F)
Give an SQL expression equivalent to the following queries
(a) P A(r)
select A
from r
(b) s B=17 (r)
select *
from r
where B=17
(c) r X s
select *
from r, s
(d) P A,F ( s C=D (r X s))
select A, F
from r, s
where C=D
#4.5 with R = (A, B, C) and r1 and r2 both relations on schema R, give an SQL expression equivalent to:
(a) r1 È r2
(select *
from r1)
union
(select *
from r2)
(b) r1 Ç r2
here are two possible solutions:
(select *
from r1)
intersect
(select *
from r2)
or alternatively with a nested subquery
select *
from r1
where (A, B, C) in (select *
from r2)
(c) r1 ¾ r2
select *
from r1
where (A, B, C) not in
(select *
from r2)
another possible solution would be to use the except clause
(d) P AB (r1) P BC (r2)
select r1.A, r1.B, r2.C
from r1, r2
where r1.B = r2.B
#4.6 With R= (A, B) and S= (A, C), and r, s relations on schemas R,S respectively, write an SQL expression for the following:
(a)
select A
from r
where B=17
(b)
select r.A, r.B, s.C
from r, s
where r.A = s.A
(c)
select s.A
from s, r r1, r r2
where s.A = r1.A and s.A = r2.A and
r1.B > r2.B
#4.7
There are a number of ways to express this.
Comparing (x not in S) with (x <> all S), for a given value x1,
Clearly if x1 satisfies (x1 <> all S), then for any value y in S, x1 <> y, which shows that x1 is not a value contained in S. In other words, x1 not in S.
In the other direction, if x1satisfies the condition (x1 not in S), then for any value y in S, the condition (y <> x1) will be satisfied. In other words, x1 <> all S
#4.8 will not be graded
#7.2 A decomposition of R into R1 and R2 is a lossless join if R1 Ç R2 à R1 or R1 Ç R2 à R2
R1 Ç R2 = (A).
We have A à BC, so A is a candidate key for R1. Therefore the join is lossless: A à ABC, so A à R1
We could also show that
1) A à BC, so A à B, and B à D, so Aà D.
2) A à BC, and B à D, so A à DC. CD à E, so Aà E
3) by the above, A à D and Aà E, so A à DE.
Therefore A is also a candidate key for R2. Therefore the join is lossless: A à ADE, so A à R2.
#7.4
A à B
C à B
#7.5 sound means that they do not generate incorrect functional dependencies.
Definition of functional dependencies:
A à B holds on schema R if, in any legal relation r in R, for every pair of tuples t1 and t2 in relation r, if t1[A] = t2[A] then we also have t1[B] = t2[B]
Armstrong's Axioms:
Reflexivity: if A is a set of attributes and B is a subset of A, then Aà B
By definition, if t1[A] = t2[A] then on every attribute X within set A, t1[X]=t2[X]. Since B is a subset of A, every attribute X that appears within B also appears within A, so t1[B]=t2[B] .
Augmentation: if A à B holds and C is a set of attributes, then AC à BC
For any attribute X in C, X à X (if t1[X]=t2[X] then t1[X]=t2[X] is a tautology).
By reflexivity, AC à C since C is a subset of AC. By our initial assumption, we also have A à B; by reflexivity again, this means that AC à B. By the definition of FDs, then, AC à BC
Transitivity: if A à B holds and B à C holds, then A à C.
By the definition of FDs, A à B means if t1[A] = t2[A] then we also have t1[B] = t2[B]. By the definition of FDs again, Bà C means if t1[B] = t2[B] then we also have t1[C] = t2[C]. Since equality is transitive, therefore we have if t1[A]=t2[A] then t1[C]=t2[C], which by definition is A à C
#7.11
1. A à BC
2. CD à E
3. B à D
4. E à A
Candidate keys:
(1)
1 and the trivial Aà A gives us with A à ABC
3. gives us A à ABCD
2. gives us A à ABCDE: A is a candidate key
(2)
2 gives us CD à E
2 and 4, by transitivity, gives us CD à AE
since A à ABCDE, this gives us CD à ABCDE. CD is also a candidate key
(3)
3 and Augmentation gives us BC à CD. CD is a candidate key, so BC is also a candidate key.
(4) E à A, and A is a candidate key, so E is also a candidate key.
#7.12
Compute B+ from the dependencies of 7.11.
1) start with B à B, the trivial dependency
2) using FD#3, B à BD
3) that is all.
#7.15
There are several ways to write this query; I have chosen a simple one
(a) select b
from r
group-by b
having count ( distinct c) > 1
(b) create assertion dependency-preserve check
(not exists
(select b
from r
group-by b
having count ( distinct c) > 1))
#7.16
let r be the following relation:
A B C D E
a1 b1 c1 d1 e1
a2 b2 c1 d2 e2
now P A,B,C (r) is:
A B C
a1 b1 c1
a2 b2 c1
and P C,D,E (r) is:
C D E
c1 d1 e1
c1 d2 e2
now the result of P A,B,C (r) natural-join P C,D,E (r) gives us all the following tuples:
A B C D E
a1 b1 c1 d1 e1
a2 b2 c1 d2 e2
a1 b1 c1 d2 e2
a2 b2 c1 d1 e1
Which is erroneous. Therefore lossy join.
#7.21
Bà D is the non-trivial dependency with the left-hand side not being a superkey, so splitting into {(A,B,C,E) , (B, D)} is in BCNF
#7.23
With BCNF it is sometimes not possible to preserve all the dependencies. As a result, we are sometimes forced to choose between violating some dependencies and having the database in BCNF.