SQL join(INNER JOIN ) - sql

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'

Related

SQL Query (joins between tables)

there is two tables: country , countrylanguage and the common columns are code in country table and countrycode in countrylanguage.
how to retrieve the name of country and count of spoken language in each.
here is what I wrote:
select country.name , countrylanguage.language from country , countrylangauge where countrylanguage.language in (select count(language) from countrylanguage group by countrycode);
If you are using an ANSI compliant database engine (c.f. Wikipedia), you can use JOIN ... ON to join both tables based on the code columns.
SELECT country.name,
count(countrylanguage.language) AS language_count
FROM country
JOIN countrylanguage ON country.code = countrylanguage.countrycode
This performs an inner join, so only the records present in both country and countrylanguagetables will be returned. You can use OUTER JOIN otherwise.
If you are using a database which does not support ANSI joins, the join can be performed in a WHERE clause as follows:
SELECT country.name,
count(countrylanguage.language) AS language_count
FROM country,
countrylanguage
WHERE country.code = countrylanguage.countrycode
Try this following script-
SELECT A.name country_name,
B.language,
COUNT(B.language) total_count
FROM country A
INNER JOIN countrylangauge B ON A.Code = B.countrycode
GROUP BY A.Code
Because you want to take into account that countries could have no languages, you should use a left join:
select c.name, count(cl.language) as num_languages
from country c left join
countrylangauge cl
on cl.countrycode = c.countrycode
group by c.countrycode, c.name;
You appear to be learning SQL. If so, you should not be learning about commas in the FROM clause at all. You should only be learning about JOIN, which is the proper way to join tables together.

Not unique table/alias?

I get this error: Not unique table/alias: 'postcode'
"SELECT sub.city AS city, sub.postalcode AS postalcode FROM
(SELECT postcode.city AS city, customers.postalcode AS postalcode, COUNT(customers.postalcode) AS postcode_numbers
FROM orders, postcode
INNER JOIN customers ON orders.userID = customers.ID
INNER JOIN postcode ON customers.postalcode = postcode.city
GROUP BY customers.postalcode) sub
WHERE sub.postcode_numbers > 3";
Remove postcode table in the from statement
SELECT sub.city AS city, sub.postalcode AS postalcode FROM
(SELECT postcode.city AS city, customers.postalcode AS postalcode, COUNT(customers.postalcode) AS postcode_numbers
FROM orders
INNER JOIN customers ON orders.userID = customers.ID
INNER JOIN postcode ON customers.postalcode = postcode.city
GROUP BY customers.postalcode) sub
WHERE sub.postcode_numbers > 3
You have postcode in both your from clause and your second join clause. Remove it from the from clause and you should be OK:
SELECT sub.city AS city, sub.postalcode AS postalcode FROM
(SELECT postcode.city AS city, customers.postalcode AS postalcode, COUNT(customers.postalcode) AS postcode_numbers
FROM orders -- Removed postcode from here
INNER JOIN customers ON orders.userID = customers.ID
INNER JOIN postcode ON customers.postalcode = postcode.city
GROUP BY customers.postalcode) sub
WHERE sub.postcode_numbers > 3
You can write this as:
SELECT p.city, c.postalcode , COUNT(*) AS num_orders
FROM orders o JOIN
customers c
ON o.userID = c.ID JOIN
postcode p
ON c.postalcode = p.city
GROUP BY p.city, c.postalcode
HAVING COUNT(*) > 3;
It is unclear whether you want one row per city or per city/postalcode. This assumes the latter. If you want one row per city, remove postalcode from both the SELECT and the GROUP BY.
Notes:
Never use commas in the FROM clause. Always use proper, explicit, standard JOIN syntax. That is your specific problem.
Table aliases make the query easier to write and to read.
The unaggregated columns in the SELECT should match the GROUP BY keys.
A subquery is not necessary.
You are using postcode table in both FROM clause and and INNER JOIN clause, neither of which have an alias, when you do an INNER JOIN you don't need to have that table in the FROM clause, and other way around of course.
If you want to join the tables in FROM clause you would do something like this:
SELECT
sub.city AS city, sub.postalcode AS postalcode
FROM
(SELECT
postcode.city AS city, customers.postalcode AS postalcode,
COUNT(customers.postalcode) AS postcode_numbers
FROM
orders, postcode
INNER JOIN
customers ON orders.userID = customers.ID
--INNER JOIN postcode ON customers.postalcode = postcode.city
WHERE
postcode.city = customers.postalcode
GROUP BY
customers.postalcode) sub
WHERE
sub.postcode_numbers > 3;
So basically you would lose the INNER JOIN postcode... line
The other way to do this is to use only the INNER JOIN clause, which is my preferred way. To do this you only need to lose the postcode in FROM clause, like so:
SELECT
sub.city AS city, sub.postalcode AS postalcode
FROM
(SELECT
postcode.city AS city, customers.postalcode AS postalcode,
COUNT(customers.postalcode) AS postcode_numbers
FROM
orders
INNER JOIN
customers ON orders.userID = customers.ID
INNER JOIN
postcode ON customers.postalcode = postcode.city
GROUP BY
customers.postalcode) sub
WHERE
sub.postcode_numbers > 3;
Hope this helps!

Using Oracle in select query

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');

Nested 'Where'?

I have a table named Actor, with only a column for City (CityId). I want to return the number of actors in a particular State (StateId). The catch however is that I have separate tables for City, County, and finally State (City has CountyId, County has StateId). How do I this in a T-SQL query?
I have a solution that involves nested Select statements, something like:
SELECT COUNT(1)
FROM Actor a
WHERE a.CityId IN
(SELECT CityId FROM City WHERE CountyId IN...)
...but is there a more efficient way to do this? Thanks
You can use this query to get your output
----------------------------------------------------------
SELECT COUNT(ActorId)
FROM Actor a
INNER JOIN City c ON a.cityId = c.cityId
INNER JOIN Country con ON c.countryId = con.countryId
INNER JOIN STATE s ON con.stateId = s.stateId
GROUP BY s.stateId
Use JOINS to query your data.
I am using INNER JOIN here.
Assuming that you have CountryId in your City Table, You can do it following way.
In case you don't have countryId in your City Table you have to apply one more INNER JOIN on State Table.
SELECT COUNT(1) FROM Actor a INNER JOIN
City b ON a.CityId = b.CityId
WHERE b.CountryId IN (...)
You can easily put the JOINS across different table that you have and then use the Group By clause to find out the total number of actors from specific state.
I have used the column name on the basis of my wild guess, you can change them with the original name that you have in your database.
SELECT StateId,
Count(ActorId) AS Total
FROM ACTOR
INNER JOIN City ON Actor.CityId = City.CityId
INNER JOIN County ON County.CountyId = City.CountyId
INNER JOIN State ON State.StateId = County.StateId
GROUP BY State.StateId
Assuming the relation names, you can do something like this with joins:
select s.ID, s.Name, count(*)
from Actors a
inner join Cities c on c.ID = a.CityID
inner join County cn on cn.ID = c.CountyID
inner join State s on s.ID = cn.StateID
group by s.ID, s.Name
If you only need the StateId you don't even need to join with states, this will do:
select cn.StateID, count(*)
from Actors a
inner join Cities c on c.ID = a.CityID
inner join County cn on cn.ID = c.CountyID
group by cn.StateID

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