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).
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)
I'm trying to teach myself SQL, and have been using SQLZoo (http://sqlzoo.net) among other resources. (Which seems to be using MariaDB, according to the error message.)
One of their exercises asks to show the name and population of every country in Europe (from a table 'world' where country name, population, continent and some other stuff are all listed), but to show the populations as a percentage of Germany's population. They mention the CONCAT and ROUND functions right there, so I'm assuming they want a '%' sign and no decimal places.
I tried:
SELECT name,
(CONCAT
(ROUND(100 * population/(SELECT population FROM world WHERE name= 'Germany'), 0),
'%')
FROM world
WHERE continent= 'Europe'
I figured that I would have to just sort of nest everything in one big, fat mess. My outermost layer in the original SELECT is to add the '%' at the end of the calculation, followed by shaving off the decimal places, followed by the actual calculation: calculating the population by its percentage of Germany's populations in decimal form by simply dividing the country's population by Germany's, multiplied by 100 so I can just shave off the decimal places, slap a percentage sign on it, and be done with it.
The problem is that this sends me back an error message. The error tells me to check the syntax at the end (FROM world WHERE continent = 'Europe').
Can someone tell me where this is going wrong?
You have unbalanced parentheses problem. Try this version of your query:
SELECT
name,
CONCAT(ROUND(100 * population /
(SELECT population FROM world WHERE name= 'Germany'), 0), '%')
FROM world
WHERE continent = 'Europe'
Try this if you get a lot of 0 when using concat and round.
select name, concat(cast(round(100*population/(select population from world where name='Germany'),0) as int),'%') as percentage from world where continent = 'Europe'
I was using SQL zoo for brushing up my SQL knowledge and found the following problem:
"Some countries have populations more than three times that of any of
their neighbours (in the same continent). Give the countries and
continents."
The solution I have put down for this is:
SELECT name, continent
FROM world w
WHERE NOT EXISTS (
SELECT *
FROM world nx
WHERE nx.continent = w.continent
AND nx.population <= 3*w.population)
The interpreter is saying that I have "too few columns" (on number 8 problem on SQL zoo). I am not sure what is incorrect here. Any suggestion or help is appreciated.
That page has a "Show correct result" button, which should tell you exactly what's incorrect about the results, if not the SQL statement you used.
When I use your SQL statement for that problem, I get the right columns, but the wrong rows, so I must assume you've typo'd somewhere.
One correct answer for that question is:
SELECT name, continent
FROM world w
WHERE population IS NOT NULL
AND NOT EXISTS (
SELECT * FROM world x
WHERE x.continent = w.continent
AND population IS NOT NULL
AND x.name != w.name
AND x.population > w.population/3
)
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.