Using Oracle in select query - sql

Question: Given the CITY and COUNTRY tables, query the sum of the populations of all cities where the CONTINENT is 'Asia'.
City table contains fields: CountryCode, Population
Country table contains fields: Code, Continent
(CITY.CountryCode and COUNTRY.Code are matching key columns.)
I tried the following query: (I know this can be solved using Inner join)
Select sum(city.population) from city
where city.countrycode in (Select code from Country where continent = 'Asia')
Hacker rank gives following error:
ERROR at line 3:
ORA-00933: SQL command not properly ended

Do you need a semi colon?
Something along these lines......
Per city..........
SELECT City.Name, SUM(City.Population)
FROM City INNER JOIN Country ON Country.Code = City.CountryCode
WHERE
Country.Continent = 'ASIA'
GROUP BY
City.Name;
Per Country & City
SELECT Country.Name, City.Name, SUM(City.Population)
FROM City INNER JOIN Country ON Country.Code = City.CountryCode
WHERE
Country.Continent = 'ASIA'
GROUP BY
Country.Name, City.Name;
Just the Total for ASIA
SELECT SUM(City.Population)
FROM City INNER JOIN Country ON Country.Code = City.CountryCode
WHERE
Country.Continent = 'ASIA';

What we are doing here is querying the city table and finding all matches in the country table by using the identifying field in both those tables:
country.code in your country table
city.countrycode in your city table
Whenever country.code = city.countrycode and country.continent= 'Asia', you will be returned the sum of that population.
Select sum(city.population) from city inner join country on country.code = city.countrycode
where country.continent= 'Asia';
I also recommend you select the city the population count belongs to:
Select city.name, sum(city.population) from city inner join country on country.code = city.countrycode
where country.continent= 'Asia';

This is the right code
Select sum(city.population)
from city inner join country on country.code = city.countrycode
where country.continent= 'Asia';

Select SUM(City.POPULATION) from City join Country ON city.countrycode=country.code
where country.continent='Asia'

Use ; at the end of the code.
Select sum(city.population) from city
where city.countrycode in (Select code from Country where continent = 'Asia');

Related

SQL, choosing maximum values from another table

This one I've been spending the last hours on. Still haven't found an answer so I figured I'd ask.
I have two tables:
Country - Code, Name, Populaion.
City - CountryCode, Name, Population.
The Foreign key is the CountryCode which response to country.Code.
I'm trying to find the most populated city in each country, where the output is the name of the country and the city. I know this could be done with Max(), but I'm having a struggle limiting my table to showing all the countries name and showing onle the name of the most populated city.
SELECT country.name, city.name, MAX(city.Population)
FROM city
LEFT JOIN country
ON city.CountryCode=Country.Code
GROUP BY city.name, country.name, city.population
ORDER BY city.population DESC;
This only gives me all the countries and all the cities. Could anyone help me narrow it down so it only shows every countries name but with their largest city?
You want to first the max population in each country and then join it with the city table to know which city it belongs to. After that, join it with the country table to get the required result.
select co.name,
ct.name,
ct.population
from (
select c1.*
from city c1
join (
select countryCode,
max(population) population
from city
group by countryCode
) c2 on c1.countryCode = c2.countryCode
and c1.population = c2.population
) ct
join country co on ct.countryCode = co.code;
Another way of finding max in group using left join:
select co.name,
ct.name,
ct.population
from (
select c1.*
from city c1
left join city c2 on c1.countryCode = c2.countryCode
and c1.population < c2.population
where c2.countryCode is null
) ct
join country co on ct.countryCode = co.code;

Group By SQL Statement - Get countries with more than 5 cities

I am trying to pull the countries that have more than 5 cities.
Tables:
City city_id, city, country_id, last_update
Country country_id, country, last_update
I think I am very close to getting this figured out, but I'm not quite there. Any pointers?
SELECT DISTINCT country
FROM country C, city O
WHERE O.country_id = C.country_id AND O.country_id
IN (SELECT country_id FROM city group by country_id having count(country_id) > 5);
select country
from country inner join city on city.country_id = country.country_id
group by country
having count(distinct city) > 5
Use the below query..
SELECT country
FROM country C
JOIN city O
ON O.country_id = C.country_id
GROUP BY country
HAVING count(distinct O.city)>5
you can try like this
select countryid, count(distinct city_id) from country c join city ct c.country_id=ct.country_id
group by countryid
having count(distinct city_id) > 5
SELECT DISTINCT
country
FROM country C
WHERE EXISTS (SELECT COUNT(DISTINCT city_id)
FROM city CITY
WHERE CITY.country_id = C.country_id
GROUP BY CITY.country_id
HAVING COUNT(DISTINCT city_id) > 5);
The below query works for your requirement.
SELECT C.country
FROM country C
INNER JOIN
city O
ON O.country_id = C.country_id
GROUP BY C.country
HAVING count(distinct O.city)>5;

For each country, find city that has the highest population and the city's population

I am using the Mondial database schema and am trying to find: For each country, find city that has the highest population and the city's population.
Right now I have:
SELECT Country.Name, city.name, MAX(city.population) Population
FROM city
Join Country
On Country.Code=City.Country
WHERE city.population IS NOT NULL
GROUP BY Country.Name, city.name
ORDER BY Country.Name;
This gives me ALL of the cities in each country and their populations and not just the largest city.
Use analytical functions. Something like this should work (untested):
select
country.name,
city.name,
city.population
from
country
join
(
select
country,
name,
population,
row_number() over ( partition by population desc) as rn
from
city
) city on
city.country = country.code
and city.rn = 1
order by
country.name
Don't know in oracle but if done in SQL Server it can be done like this:
Select * from
(select
Country.Name,
city.name,
city.population,
ROW_NUMBER() over(partition by Country.Name order by Country.Name,city.population desc) RowNum
from Country inner join city city on Country.Code=City.Country) tbl
where RowNum = 1
function similar to row_number in oracle will help.
Hope This help.
This seems to work.
It's also useful for filtering query results according to column containing an aggregate function.
SELECT ct.name AS "Country", c1.name AS "City", c1.population AS "Population"
FROM city c1
JOIN country ct
ON c1.country = ct.code
WHERE c1.population = (SELECT max(population)
FROM city c2
WHERE c1.country = c2.country)
ORDER BY country
Here you have already done Group by Country.name so you can just have single country detail, so instead of going for the MAX(population) you can just do order by city.population also remove the group by for city.name
E.g.
SELECT Country.Name, city.name, city.population Population
FROM city
Join Country
On Country.Code=City.countrycode
WHERE city.population IS NOT NULL
GROUP BY Country.Name
ORDER BY city.population desc;
This will not give you the countries in sorted order but that can also be done after adding another order by on top of it if you really want country name also sorted.
SELECT Country.Name, city.name, city.population Population
FROM city
Join Country
On Country.Code=City.countrycode
WHERE city.population IS NOT NULL
GROUP BY Country.Name
ORDER BY country.name, city.population desc;
Hope that helps to simplify the SQL query. This I have tested in MySQL.
You cannot use MAX in multiple select
try this:
SELECT Country.Name, city.name, city.population
FROM city
Join Country
On Country.Code=City.Country
WHERE city.population IS NOT NULL and city.population in (SELECT MAX(population) FROM city limit 1)
GROUP BY Country.Name, city.name
ORDER BY Country.Name;

SQL join(INNER JOIN )

This part requires you to write a simple inner join of several tables.
Write a SQL statement that returns a data set with all airports in London. The data set must contain, for each airport, the name of the city, the country, the airport code and its latitude and longi-tude
My answer here:
SELECT City.name, Country.name, Airport.code, Airport.latitude,
Airport.longtitude
FROM City, Airport, Country
WHERE Country.id = City.Country
AND Airport.city = City.id
AND City.name = "London"
Am I right? Do I need to write the keywords like "INNER JOIN" or "ON" on my code?
This is ok.
SELECT City.name, Country.name, Airport.code, Airport.latitude, Airport.longtitude
FROM City, Airport, Country
WHERE
Country.id = City.Country
AND Airport.city = City.id
AND City.name = "London"
But can also be write like this
SELECT City.name, Country.name, Airport.code, Airport.latitude, Airport.longtitude
FROM
City
inner join Country ON Country.id = City.Country
inner join Airport ON Airport.city = City.id
WHERE
City.name = "London"
Given that the question asks for a 'a simple inner join', then yes, you'll need to use those keywords! INNER JOIN is used to link tables that have matching columns. For example, if one table contains details about a city, another table can refer to it via its ID column, and a query using INNER JOIN can retrieve details from both. If the city details change, they only need to be changed in one table.
In your example, the query would look something like this:
SELECT
c.name,
cty.name,
ap.code,
ap.latitude,
ap.longtitude
FROM
Airport ap
INNER JOIN City c ON ap.city = c.id
INNER JOIN Country cty ON c.Country = cty.id
WHERE
c.name = "London"
SELECT City.name, Country.name, Airport.code, Airport.latitude,
Airport.longtitude
from Airport
inner join city on Airport.city = City.id
inner join Country ON Country.id = City.Country
where
city.name='London'

SQL query - IS NULL

Tables:
Country
-------
PK CountryID
Name
City
-------
PK CityID
FK CountryID
Name
Airport
--------
PK AirportID
FK CityID
Name
My task is to select names of countries that have no airport.
I can imagine only one solution with EXCEPT (or MINUS)
SELECT Country.Name
FROM Country EXCEPT (SELECT DISTINCT Country.Name FROM Country, City, Airport
WHERE City.CountryID = Country.CountryID AND Airport.CityID = City.CityID);
But is it possible not to use EXCEPT but something like IS NULL?
SELECT cn.CountryID
FROM Country cn
LEFT JOIN City ct ON cn.CountryID = ct.CountryID
LEFT JOIN Airport ar on ar.CityID=ct.CityID
WHERE ar.AirportID is null
If you need to make this query with IS NULL try following query:
SQLFiddle demo
select ct.CountryId,max(ct.Name) from Country ct
left join City c on ct.CountryId=c.CountryId
left join Airport a on a.CityId=c.CityID
group by ct.CountryId
HAVING max(a.AirportID) IS NULL
You can use this, but it's basically the same thing you have with different syntax.
SELECT Country.Name
FROM Country
Where Country.Name Not IN
(
SELECT DISTINCT Country.Name FROM Country, City, Airport
WHERE City.CountryID = Country.CountryID AND Airport.CityID = City.CityID
);