You are on page 1of 9

TUGAS

SISTEM DATABASE I

Diajukkan Untuk Memenuhi Tugas 3 Sistem Database I

Oleh

FARHAN GUNADI

140810190009

UNIVERSITAS PADJADJARAN

FAKULTAS MATEMATIKA DAN ILMU PENGETAHUAN ALAM

PROGRAM S1 TEKNIK INFORMATIKA

JATINANGOR

2020
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 name GDP (B) population (M)


Djokovic 2015 USA 18,558 325
Djokovic 2014 China 11,383 1,383
Nadal 2013 Japan 4,412 126
Djokovic 2012 Germany 3,467 80
Djokovic 2011 UK 2,853 65
Nadal 2010 Spain 1,242 46
Federer 2009 Switzerland 651 8
Nadal 2008 Serbia 37 9
Federer 2007

Federer 2006

Federer 2005

Federer 2004
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).

Πcountry( (σ’2010’ <=year <=’2013’ (Year_Ranked_First) ⨝name Tennis_Palyer)


(b) List names and GDPs of countries from which there are no tennis player in
our database.

Πname, GDP (Countries)− Πname, GDP (Countries ⨝C.name=TP.country Tennis_Palyer)


(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.

σ(P1.ATP_rank<P2.ATP_rank)∧(P1.GDP<P2.GDP)(
ρP1(Tennis_Player ⨝TP.country=C.name Countries)× ρP2 (Tennis_Player
⨝Tennis_Player.country=C.name Countries))

(d) List name, age, ATP rank and country’s GDP of tennis players from Spain or Serbia.

ΠTennis_player.name,Tennis_player.age,Tennis_player.ATP_rank,Countries.GDP (σname = ‘Spain’


V σname =’Serbia’ Countries) ⨝Countries.name = Tennis_player.country Tennis_Player)

(e) List name, ATP rank and country of tennis players who were ranked first in 2010
or later but not before 2010.

Πname,country,ATP_rank (Πname (σ2010<=year (Year_Ranked_First)) - Πname


(σ2010>year (Year_Ranked_First))) ⨝name Tennis_Palyer)

(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).

ΠC.name,C.population( (σATP_rank <= ‘5’ ^ age >=’30’ (Tennis_Player) ⨝name (σyear >=
‘2004’ (Year_Ranked_First))) ⨝Tennis_Player.name = C.name Countries)
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).
SELECT A.country AS country, COUNT(*) AS num_years
FROM Tennis_Players A, Year_Ranked_First B
WHERE A.name = B.name
GROUP BY A.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.
SELECT A1.name player1, A2.name player2
FROM Tennis_Players A1, Tennis_Players A2, Countries B1, Countries B2
WHERE A1.country = B1.name
AND A2.country = B2.name
AND A1.ATP_rank < A2.ATP_rank
AND B1.population < B2.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).
SELECT A1.name player1, A2.name player2, A1.country
FROM Tennis_Players A1, Tennis_Players A2
WHERE A1.country = A2.country
AND A1.name < A2.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).
SELECT C.name, C.gdp, AVG(A.age)
FROM Tennis_Players A, Countries C
WHERE A.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).
SELECT C.name AS country, C.gdp, C.population, MIN(A.age) AS min_age
FROM Countries C
LEFT OUTER JOIN Tennis_Players A ON (C.name = A.country)
GROUP BY C.name,C.gdp

(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).

SELECT DISTINCT A1.country


FROM Tennis_Players A1, Tennis_Players A2, Year_Ranked_First B1, Year_Ranked_First B2
WHERE A1.country = A2.country
AND A1.name = B1.name
AND A2.name = B2.name
AND B1.year <= 2010
AND B2.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).
Select distinct D1.dish
from Foods F1,Foods F2,Dishes D1,Dishes D2
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
(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).
Select D.dish, count(*) as num_ingredients, sum(F.calories) as total_calories
from Dishes D,Foods F
where D.food = F.food
group by D.dish
having sum(F.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).
Select D.dish, sum(F.calories) as total_calories
from Dishes D,Foods F
where D.food = F.food
group by D.dish
having sum(F.calories) >= 200
and count(*) = 3;

You might also like