Upload
oswin-kelley
View
219
Download
2
Embed Size (px)
Citation preview
1
Exercise 1
Given the following tables:
employee (person_name, street, city)
works (person_name, company_name, salary)
company (company_name, city)
manages (person_name, manager_name)
2
Find the name of employees who earn more than $10,000 and live in Hong Kong.
select w.person_name from works as w where w.salary > 10000 and w.person_name in
(select e.person_name from employee as e where e.city = “Hong Kong”)
Alternative solutions
select w.person_name from works as w, employee as e where w.salary > 10000 and e.city = “Hong Kong”
and w.person_name = e.person_name
employee (person_name, street, city)works (person_name, company_name, alary)company (company_name, city)manages (person_name, manager_name)
3
Find the name of the employees who are not managers.
(select person_name
from employee)
except
(select manager_name
from manages)
employee (person_name, street, city)works (person_name, company_name, alary)company (company_name, city)manages (person_name, manager_name)
4
Alternative solutions
select person_name
from employee
where not exists
(select *
from manages
where employee.person_name = manages.manager_name)
select person_name
from employee
where person_name not in
(select manager_name
from manages)
employee (person_name, street, city)works (person_name, company_name, alary)company (company_name, city)manages (person_name, manager_name)
5
RA SQL Given the following tables:
employee (person_name, street, city)
works (person_name, company_name, salary)
company (company_name, city)
manages (person_name, manager_name)
Find the names of all persons who work for “First Bank Corporation” and live in the city where the company is located.
. _ . .
person_name company_name _ "First Bank Corporation"
(
( ( )))
employee person name employee city company city
company nameemployee works company
6
Find the names of all persons who work for “First Bank Corporation” and live in the city where the company is located.
select E.person_name
from employee as E, works as W, company as C
where E.person_name = W.person_name
and W.company_name = C.company_name
and C.company_name = “First Bank Corporation”
and E.city = C.city
employee (person_name, street, city)works (person_name, company_name, alary)company (company_name, city)manages (person_name, manager_name)
7
Find the names, cities of employees who work for exactly ONE company
select e.person_name, e.city
from employee as e
where unique
(select *
from works as w
where w.person_name = e.person_name)
employee (person_name, street, city)works (person_name, company_name, salary)company (company_name, city)manages (person_naame, manager_name)
8
Find the names of all employees who earn more than SOME employee of Small Bank Corporation.
select w1.person_name
from works as w1
where w1.salary > some
(select w2.salary
from works as w2
where w2.company_name = “Small Bank Corporation”)
Alternative solution
select w1.person_name
from works as w1
where exists
(select *
from works as w2
where w2.company_name = “Small Bank Corporation” and w1.salary > w2.salary)
employee (person_name, street, city)works (person_name, company_name, salary)company (company_name, city)manages (person_naame, manager_name)
9
Find the company located in Hong Kong that has the largest number of employees
select temp.company_name
from (select w.company_name, count(distinct w.person_name) as cnt
from works as w, company as c
where w.company_name = c.company_name
and c.city = “Hong Kong”
group by w.company_name) as temp
where temp.cnt in (select max (cnt)
from temp)
employee (person_name, street, city)works (person_name, company_name, salary)company (company_name, city)manages (person_naame, manager_name)
Can also be ‘=’
10
Find all companies located in Hong Kong and have total payroll less than 100,000
select company.company_namefrom works, companywhere works.company_name = company.company_name
and company.city = “Hong Kong”group by company.company_namehaving sum(works.salary) < 100,000
employee (person_name, street, city)works (person_name, company_name, salary)company (company_name, city)manages (person_naame, manager_name)
11
Question: Consider the following schemas.CUST (cust-id, name), andWITHDRAW (w-id, cust-id, acc-id, date, amount)
Write an SQL query to retrieve all the names of the customers who have withdrawn more than 1k dollars in a single withdrawal. If a customer made several such withdrawals, her/his name should be reported only once.
12
Answer: Consider the following schemas.CUST (cust-id, name), andWITHDRAW (w-id, cust-id, acc-id, date, amount)
Write an SQL query to retrieve all the names of the customers who have withdrawn more than 1k dollars in a single withdrawal. If a customer made several such withdrawals, her/his name should be reported only once.
select distinct namefrom CUST as T1, WITHDRAW as T2where T1.cust-id = T2.cust-id and T2.amount > 1k
13
Question: Consider the following schemas.CUST (cust-id, name), andWITHDRAW (w-id, cust-id, acc-id, date, amount)
Sometimes there may be a “shared” account, namely, an account with multiple owners.
Write an SQL query to return the acc-id of all the shared accounts.You may assume that all the owners of a shared account have made withdrawals from the account.
14
Answer: Consider the following schemas.CUST (cust-id, name), andWITHDRAW (w-id, cust-id, acc-id, date, amount)
Sometimes there may be a “shared” account, namely, an account (acc-id) with multiple owners (cust-id).
Write an SQL query to return the acc-id of all the shared accounts.You may assume that all the owners of a shared account have made withdrawals from the account.
select T1.acc-idfrom WITHDRAW as T1, WITHDRAW as T2where T1.cust-id <> T2.cust-id and T1.acc-id = T2.acc-id
15
Question: Consider the following schemas.CUST (cust-id, name), andWITHDRAW (w-id, cust-id, acc-id, date, amount)
Let us use the name “interesting account” to refer to the account from which the withdrawal with smallest amount was made.
Retrieve the acc-id of accounts from which withdrawals have been made, except the interesting account.
16
Answer: Consider the following schemas.CUST (cust-id, name), andWITHDRAW (w-id, cust-id, acc-id, date, amount)
Let us use the name “interesting account” to refer to the account from which the withdrawal with smallest amount was made.
Retrieve the acc-id of accounts from which withdrawals have been made, except the interesting account.
select distinct acc-id from WITHDRAW where acc-id not in
(select acc-id from WITHDRAW where amount = (select min (amount) from WITHDRAW))
17
Consider table: deposit (dep-id, acc-id, cust-id, amount). We want to retrieve the cust-id of the customers who deposited into two accounts with acc-id ‘A1’ and ‘A2’, respectively.
Write an SQL query with intersect.
(select distinct cust-id from deposit where acc-id = ‘A1’)intersect(select distinct cust-id from deposit where acc-id = ‘A2’)
Write a nested SQL query without intersect.
select distinct cust-id from deposit where acc-id = ‘A1’ and cust-id in (select cust-id from deposit where acc-id = ‘A2’)
dep-id acc-id cust-id amount
070940 A1 1 2K
070941 A1 1 1K
070943 A2 1 1K
070945 A2 2 3K
070959 A3 3 2K
080341 A3 2 5K
18
Again consider table: deposit (dep-id, acc-id, cust-id, amount). We want to retrieve the cust-id of the customers who deposited into two accounts with acc-id ‘A1’ and ‘A2’, respectively.
Write an SQL query that contains only one select .
select distinct T1.cust-idfrom deposit as T1, deposit as T2where T1.cust-id = T2.cust-id and T1.acc-id = ‘A1’ and T2.acc-id = ‘A2’
dep-id acc-id cust-id amount
070940 A1 1 2K
070941 A1 1 1K
070943 A2 1 1K
070945 A2 2 3K
070959 A3 3 2K
080341 A3 2 5K
19
Find the ids of the accounts which have been deposited into by more than one customer.
Write a SQL query without group by:
select D1.acc-idfrom deposit as D1, deposit as D2where D1.cust-id <> D2.cust-id and D1.acc-id = D2.acc-id
dep-id acc-id cust-id amount
070940
A1 1 2K
070941
A1 1 1K
070943
A2 1 1K
070945
A2 2 3K
070959
A3 3 2K
080341
A3 2 5K
20
Find the ids of the accounts which have been deposited into by more than one customer.
Write a SQL query with group by:
select acc-idfrom deposit group by acc-idhaving count (distinct cust-id) >= 2
If there is no distinct here, A1 will also be displayed.
dep-id acc-id cust-id amount
070940
A1 1 2K
070941
A1 1 1K
070943
A2 1 1K
070945
A2 2 3K
070959
A3 3 2K
080341
A3 2 5K
21
Again consider table: deposit (dep-id, acc-id, cust-id, amount). We want to retrieve the cust-id of the customers who deposited into the account with acc-id = ‘A1’ or ‘A2’ but not both.
Write an SQL query that contains only one SELECT.
select cust-id from deposit where acc-id = ‘A1’ or acc-id = ‘A2’group by cust-idhaving count (distinct acc-id) = 1
Indispensable!
dep_id acc-id cust-id amount
070940 A1 1 2K
070941 A1 1 1K
070943 A2 1 1K
070945 A2 2 3K
070959 A3 3 2K
080341 A3 2 5K
22
deposit (dep-id, acc-id, cust-id, amount). Retrieve the cust-id of the customer who deposited the largest number of times.
select cust-id from deposit group by cust-idhaving count (*) >= all (select count (*) from deposit
group by cust-id)
dep-id acc-id cust-id amount
070940 A1 1 2K
070941 A1 1 1K
070943 A2 1 1K
070945 A2 2 3K
070959 A3 3 2K
080341 A3 2 5K
23
Question: As with natural join, outer joins are not compulsory operators. That is, we can implement an outer join using “conventional” SQL.
Let us verify this for left outer join.
CS-PROF (prof-id, name)
SUPERVISION (prof-id, stu-id)
Write an alternative query that returns the same information as
select prof-id, name, stu-idfrom CS-PROF left outer join SUPERVISION on CS-PROF.prof-id = SUPERVISION.prof-id
24
Answer: CS-PROF (prof-id, name) SUPERVISION (prof-id, stu-id)
select prof-id, name, stu-idfrom CS-PROF left outer join SUPERVISION on CS-PROF.prof-id = SUPERVISION.prof-id
(select T1.prof-id, name, stu-id from CS-PROF as T1, SUPERVISION as T2 where T1.prof-id = T2.prof-id)union(select prof-id, name, NULL from CS-PROF as T1 where not exists
(select * from SUPERVISION as T2 where T1.prof-id = T2.prof-id))
We can see that left outer join simplifies the query significantly.
25
Question: Consider MARKS(stu-id, course-id, score)
Write a query to retrieve the stu-id of every student who scored at least 80 in all the courses s/he took, but scored less than 90 in at least one course.
Your query should not contain more than 2 select.
26
Answer: Consider MARKS(stu-id, course-id, score).
Write a query to retrieve the stu-id of every student who scored at least 80 in all the courses s/he took, but scored less than 90 in at least one course.
(select stu-id from MARKS where score < 90) except(select stu-id from MARKS where score < 80)
27
Answer: Consider MARKS (stu-id, course-id, score).
Write a query to retrieve the stu-id of every student who scored at least 80 in all the courses s/he took, but scored less than 90 in at least one course.
select stu-id from MARKSgroup by stu-idhaving min (score) >= 80 and min (score) < 90