Similar to this question: NOT IN vs IN Do Not Return Complimentary Results
Basically I am trying to answer this question: Find each country that belongs to a continent where all populations are less than 25000000. Show name, continent and population.
Number 7 here has all the table details: http://sqlzoo.net/wiki/SELECT_within_SELECT_Tutorial
This query works: it effectively takes all countries belonging to a continent which has no country with a pop greater than 25mm
SELECT name, continent, population
FROM world x
WHERE continent NOT IN(SELECT DISTINCT continent FROM world
WHERE population >= 25000000)
This query does not work. I am trying to use having without having an aggregate function in the select statement. Is this allowed? Currently my subquery returns no results, so I am obviously mistaken somewhere.
SELECT name, continent, population
FROM world x
WHERE continent in (SELECT continent FROM world
having max(population) < 25000000)
Figured it out, thank you #Michael Berkowsiki for the hint in the comment above.
SELECT name, continent, population
FROM world x
WHERE continent in (SELECT continent FROM world
group by continent
having max(population) < 25000000)
"Each column referenced in the SELECT statement must be referenced in the GROUP BY clause, unless the column is an argument for an aggregate function included in the SELECT clause." ("Modern Database Management" 10th Edition, Jefferey A. Hoffer, Page 276)
So in this case, I believe your answer needs to be modified as:
SELECT name, continent, population
FROM world x
WHERE continent in (SELECT continent FROM world
group by name, continent, population
having max(population) < 25000000)
Related
I am trying to learn sql and i have downloaded a world database.
My problem is that i cannot find out how to pick the continents with more than 10 countries in them
My database is:
name: (alle countries in the world)
continent: (Africa, Americas, Asia-Pacific, Europe, Middle East, North America, South America, South Asia)
If someone can push me in the right direction, i would be really glad!
I know a part of what i need to do, but i am not sure where to put more code to get the result.
SELECT continent, COUNT(*)
FROM world
GROUP BY continent
I got the help i needed, thank you!
The code i'm using is:
SELECT continent, COUNT(*)
FROM world
GROUP BY continent
HAVING COUNT(name) > 10
What you are missing is the HAVING statement that allows you to filter the results of an aggregation. (As opposed to the WHERE clause, that is executed before the rest of the query).
SELECT continent, COUNT(*)
FROM world
GROUP BY continent
HAVING COUNT(*)>10
I'm trying to do question 9 here:
https://sqlzoo.net/wiki/SELECT_within_SELECT_Tutorial
I currently have the code:
SELECT continent, SUM(y.population) as Population
FROM world AS y
GROUP BY(y.continent)
HAVING SUM(y.population) < 250000000;
This returns the continents with a sum of their respective populations less than 250000000. I know I need to encase this in another select to make use of the continent returned, but don't know how to do this?
I tried something like this:
SELECT A.continent from world A
INNER JOIN(
SELECT B.continent, SUM(B.population) as Population
FROM world B
GROUP BY(B.continent)
HAVING SUM(B.population) < 250000000
) ON A.continent = B.continent;
^This was to try and get a single list of the continents which i could then encase in another select to iterate through and print the country names, although I feel there must be a way to directly iterate through the continent column from the first example?
This is likely something pretty trivial, but regardless any help would be great
there are multiple ways to solve this - i used a count of all countries on the continent = count of countries with population<25000000
your main mistake is in logic - SUM - it should be EACH country, not the summary
select name,w1.continent,population
from world w1
join
(
SELECT distinct continent, count(name) cnt
FROM world x
WHERE population<=25000000
group by continent
)w2
on w1.continent=w2.continent
where cnt=(select count(name) from world where w1.continent=continent)
Find the largest country (by area) in each continent, show the continent, the name and the area:
continent as Continent,
name as Name,
area as Area
FROM world x
WHERE area >= ALL(
SELECT
area
FROM world y
WHERE y.continent = x.continent
AND area > 0
)
I don't get why you have to do y.continent = x.continent in this case. Can someone explain what is happening here? Beginner to SQL thank you.
It's called a correlated subquery and returns all of the records where the continent matches the continent for that particular record in the "outer" query.
I don't get why you have to do y.continent = x.continent in this case.
If you didn't, it would return all records from world and not just the ones where the continent matches.
The query looks to roughly translate to:
Give me all of the countries whose area is greater than or equal to all of the other countries on the same continent
I'm trying the 5th question in the Nested Select of SQL zoo (using Oracle engine) http://sqlzoo.net/wiki/SELECT_within_SELECT_Tutorial
Show the name and the population of each country in Europe. Show the
population as a percentage of the population of Germany.
I know the correct answer (given below), but something puzzled me.
SELECT name, CONCAT(ROUND(population/(SELECT population
FROM world WHERE name = 'Germany'),2)*100,'%')
FROM world WHERE continent = 'Europe'
When I run the following modified query, only one row (Albania) is returned.
SELECT name, population/(SELECT population
FROM world WHERE name = 'Germany')
FROM world WHERE continent = 'Europe'
Wondering if anyone can shed light on the inner workings of Oracle as to why only Albania is returned? Its puzzling to me why it doesn't work without ROUND().
The correct answer is actually:
SELECT name,
CONCAT(ROUND(population/(SELECT population FROM world WHERE name = 'Germany')*100,0),'%')
FROM world
WHERE continent = 'Europe'
Note the results set rounds to zero decimal spaces.
That said, I tried your exact code above and still get results for all countries:
SELECT name,
population/(SELECT population FROM world WHERE name = 'Germany')
FROM world
WHERE continent = 'Europe'
You're right to be puzzled as it should certainly return regardless of using ROUND() or not, but since I cannot recreate it, I can't explain it.
A more efficient Oracle query (that gets rid of the sub-query) is to use an analytic function:
SELECT name,
ROUND(
population
/ MAX( CASE name WHEN 'Germany' THEN population END ) OVER ()
* 100
) || '%'
FROM world;
However, sqlzoo appears to use MariaDB so you can't put that query into the website (but if you recreate the table in Oracle then you can test it).
I'm learning SQL and from a programming point of view I'm struggling to understand why this query is behaving the way it is (from SQLZOO Q6)
The question:
"Find the largest country (by area) in each continent, show the continent, the name and the area:"
SELECT continent, name, area from world a
WHERE area >= ALL
(SELECT area from world b WHERE a.continent = b.continent AND area>0)
I get the above, fairly simple nested select statement.
However, what I don't get is why changing this line causes a blank result:
WHERE area >= ALL - Change it to - WHERE area > ALL
Why does this give me a blank result?
Update: I'm using MySQL
By selecting with >, you're asking for all countries that are greater than all countries on the same continent. No country can have an area greater than that of all countries on the same continent: even if it is the biggest country on a continent, it is still not bigger than itself.