28
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 )

1 Exercise 1 Given the following tables: employee (person_name, street, city) works (person_name, company_name, salary) company (company_name, city)

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

28

What will happen if some of values of score are NULL in table ?

All aggregate operations except count(*) ignore tuples with null values on the aggregated attributes.