Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 6

NAMA : ROISYAL BARIZ

NPM : 140810190023
KELAS :A

Homework 3: Relational Algebra and SQL


Tennis_Players (name, country, ATP_rank, age, points)

name country ATP_rank age points

Djokovic Serbia 1 29 15040

Murray UK 2 29 10195

Federer Switzerland 3 34 5945

Nadal Spain 4 30 5290

Wawrinka Switzerland 5 31 4720

Nishikori Japan 6 26 4290

Raonic Serbia 7 25 4285

Years_Ranked_First (name, year) Countries (name, GDP, population)


name year

Djokovic 2015

Djokovic 2014

Nadal 2013
GDP (B) population (M)
Djokovic 2012 name
Djokovic 2011 USA 18,558 325

Nadal 2010 China 11,383 1,383

Federer 2009 Japan 4,412 126

Nadal 2008 Germany 3,467 80

Federer 2007 UK 2,853 65

Federer 2006 Spain 1,242 46

Federer 2005 Switzerland 651 8

Federer 2004 Serbia 37 9


Part 1 (30 points): Relational Algebra

Consider relation instances on the previous page, with the given schemas. In each
question below, write a relational algebra expression that computes the required answer.

(a) List names of home countries of tennis players who were ranked first between 2013
and 2010 (inclusive).
Answer:
πcountry((σ2010≤year≤2013(Years_Ranked_First)) ⋈ name Tennis_Players)
(b) List names and GDPs of countries from which there are no tennis player in
our database.
Answer:
πname,GDP(Country) – πname,GDP(Country ⋈
Country.name=Tennis_Players.country Tennis_Players)

(c) List pairs of tennis players such that (i) the ATP rank of the first is lower (better) than
that of the second, and (ii) the GDP of his home country is lower than that of the
second.
Answer:
σ(P1.ATP_rank<P2.ATP_rank)∧(P1.GDP<P2.GDP)
(ρP1(Tennis_Players ⋈ Tennis_Players.country=Country.name Country)×ρP2(Tennis_Players ⋈
Tennis_Players.country=Country.name Country))

(d) List name, age, ATP rank and country’s GDP of tennis players from Spain or Serbia.
Answer:
πTennis_Players name, Tennis_Players.age, Tennis_Players.ATP_rank,Country.GDP
((σname='Spain' ∨ name='Serbia'(Country)) ⋈ Country.name= Tennis_Players.country
Tennis_Players)

(e) List name, ATP rank and country of tennis players who were ranked first in 2010
or later but not before 2010.
Answer:
π π
name,ATP_rank,country ( name ( σ2010≤year(Years_Ranked_First)) - πname(σ
2010>year(Years_Ranked_First)) ⋈ name Tennis_Players)

(f) List names and populations of countries of tennis players who are currently
ranked 5 or lower (better), are currently 30 years old or older, and were ranked
first in some year since 2004 (including 2004).
Answer:
πCountry.name,Country.population((σ ATP_rank ≤ 5 ∧ age ≥ 30(Tennis_Players) ⋈
name(σyear≥2004(Years_Ranked_First))) ⋈ Tennis_Player.name=Country.name Country)
Part 2 (30 points): SQL

Consider again relation instances on page 2, with the given schemas. In each question
below, write a SQL query that computes the required answer.

(a) For each country, compute the number of years in which one of its tennis
players was ranked first. Result should have the schema (country, num_years).
Answer:
select TP.country as country, count(*) as num_years from Tennis_Players TP,
Years_Ranked_First YRF where TP.name = YRF.name group by TP.name

(b) List pairs of tennis players (player1, player2) in which player1 both has a lower
(better) ATP rank than player 2 and comes from a less populous country.
Answer:
select TP1.name player1, TP2.name player2 from Tennis_Players
TP1, Tennis_Players TP2,Countries C1, Countries C2 where
TP1.country = C1.name and TP2.country = C2.name and
TP1.atp_rank < TP2.atp_rank and C1.population < C2.population

(c) List pairs of players from the same country. List each pair exactly once. That is,
you should list either (Djokovic, Raonic, Serbia) or (Raonic, Djokovic, Serbia), but
not both. Result should have the schema (player1, player2, country).
Answer:
select TP1.name player1, TP2.name player2, TP1.country from
Tennis_Players TP1, Tennis_Players TP2 where TP1.country =
TP2.country and TP1.name < TP2.name

(d) For countries with at least 2 tennis players, list country name, GDP and average
age of its tennis players. Result should have the schema (country, GDP, avg_age).
Answer:
select C.name, C.gdp, AVG(TP.age) from Tennis_Players TP,
Countries C where TP.country = C.name group by C.name, C.gdp
having count(*) >= 2

(e) List country name, GDP and population of each country. For countries that have
tennis players in our database, also list the minimum age of its tennis players. Result
should have the schema (country, GDP, population, min_age).
Answer:
select C.name as country, C.gdp, C.population, MIN(TP.age) as
min_age from Countries C left outer join Tennis_Players TP on
(C.name = TP.country) group by C.name, C.gdp, C.population

(f) List names of countries who had a top-ranked tennis player both in 2010 or earlier
(i.e., between 2004 and 2010, inclusive) and after 2010 (i.e., between 2011 and
2015, inclusive).
Answer:
select distinct TP1.country from Tennis_Players TP1,
Tennis_Players TP2, Years_Ranked_First YRF1,
Years_Ranked_First YRF2 where TP1.country = TP2.country and
TP1.name = YRF1.name and TP2.name = YRF2.name and YRF1.year <=
2010 and YRF2.year > 2010;
Part 3 (20 points) SQL

Foods (food, category, calories) Dishes (dish, food)

(a) (10 points) Write two equivalent SQL queries that lists dishes in which one of
the ingredients is a meat and another is a veg. List each dish exactly once. Sort
results in alphabetical order. Result should have the schema (dish).
Answer:
Select distinct D1.dish
from Dishes D1, Dishes D2, Foods F1, Foods F2
where D1.dish = D2.dish and
D1.food = F1.food and
  D2.food = F2.food and
  F1.category = 'meat' and
  F2.category = 'veg'
Order by D1.dish
 

Select distinct D1.dish


from Dishes D1, Foods F1
where D1.food = F1.food and
F1.category = 'meat' and
D1.dish in(select distinct D2.dish
from Dishes D2,Foods F2
where D2.food = F2.food and  
F2.category ='veg')
order by D1.dis

(b) (5 points) Write a SQL query that computes the number of ingredients and the
number of calories per dish. Only return dishes that have fewer than 250 total
calories. Result should have the schema (dish, num_ingredients, total_calories).
Answer:
select D.dish, count(*) as num_ingredients,
sum(calories) as total_calories from Dishes D,
Foods F where D.food = F.food
group by D.dish having sum(calories) < 250

(c) (5 points) Write a SQL query that list dishes with exactly 3 ingredients, along with the
total number of calories per dish. Only return dishes that have at least 200 total calories.
Result should have the schema (dish, total_calories).
Answer:
select D.dish, sum(calories) as total_calories from Dishes D,
Foods F where D.food = F.food
group by D.dish having sum(calories) >= 200 and count(*) = 3

You might also like