I'm trying to solve some tasks from this http://sqlzoo.net/wiki/SELECT_within_SELECT_Tutorial
At the last task(number 8) I wrote a query:
select name, continent from world a
where a.population >
(select 3*max(population) from world b
where b.continent = a.continent)
but this query doesn't return any rows. But works almost the same query(just added an additional conditin in the end of subquery). But what's the matter? Why doesn't it return raws even if names of countries are the same?
select name, continent from world a
where a.population >
(select 3*max(population) from world b
where b.continent = a.continent and a.name <> b.name)
Let me translate what both query does to english, so you can realize the difference.
first query; compare and get all countries who are on the same continent and have more than 3 times of the maximum populated country in that continent.
second query; compare and get all countries who are on the same continent and have more than 3 times of the maximum populated country in that continent except himself.
in your first query the maximum populated country cannot be more than 3 times more populated than himself if he is the max populated country himself so your query returns 0 results.
but on the second query the maximum populated country EXCEPT himself can have population 3 times more than other countries in the same continent.
Related
This is my very first question on Quora. Thanks for any recommendations , solutions and remarks. I was not provided with many specifics and data, this is a assignments where one must use his or her imagination to fill in particular data and variables. What counts is the correct logic, approach and covering possibilities. Your help is highly appreciated! Thank you!
Country and Continent table
Required Visual Result for Question 3
Questions:
Write a query that would select all countries with GDP of more than 1 000 000 000 USD
Write a query that would return all countries in Europe (specifically) with GDP of more than 1 000 000 000 USD
Write a query that lists all continents with GDP per continent (as the sum of the GDP of all countries). Each country belong to one continent only.
For what result should look like - please resort to "Required Visual Result for Question 3" image.
My Solutions:
select * from countries where GDP > 1000000000
select * from countries where continent_id = 2 and GDP>1000000000;
select sum(GDP) from countries where continent_id = 4;
However, here in 3) I can only have the GDP sum displayed, and do not know how to have the continent's name on the left side as well. Please, if possible, assist with having the continent's name displayed and then right next to it and on the right handside - the relevant GDP sum.
Welcome!
Your image shows the tables as country and continent but your queries refer to countries? So which is it please?
On the basis your image is correct but the queries are wrong then number 3 would be as below:
With no 3 your currently only going to get the some for the continent with the ID of 4.
select sum(GDP) from country where continent_id = 4;
So what you want to do is remove the WHERE and the GROUP BY continent_id to give you 1 result per continent.
select sum(GDP) from country where 1 GROUP BY continent_id
No to get the continent name included in your results you can use the JOIN syntax.
In this instance you want all your records from country and just the records from continent that match your join condition which will be the continent_id from country and the id from the continent table.
SELECT
`continent`.`name`, sum(`GDP`)
FROM `country`
LEFT JOIN `continent`
ON `country`.`continent_id` = `continent`.`id`
GROUP BY `continent_id`
ORDER BY `continent`.`name` ASC;
That should give you the results 1 per continent as required.
I've specified the table names as its clearer how to target specific columns from each table.
I just started an sql exercise-style tutorial BUT I still haven't grasped the concept of correlated queries.
name, area and continent are fields on a table.
The query is to Find the largest country (by area) in each continent, show the continent, the name and the area.
The draft work so far:
SELECT continent, name, population FROM world x
WHERE area >= ALL
(SELECT area FROM world y
WHERE y.continent=x.continent
AND population>0)
Tried reading up on it on a few other blogs.
need to understand the logic behind correlated queries.
I assume the query you posted work. You just need clarification of what it does.
SELECT continent, name, population
FROM world x
WHERE area >= ALL (
SELECT area FROM world y
WHERE y.continent=x.continent
AND population>0
)
The query translates to
"Get the continent, name, and population of a country where area is bigger than or equal to all other countries in the same continent".
The WHERE clause in the inner query is to link the 2 queries (in this case countries in the same continent). Without the WHERE, it will get the country with the largest are in the world.
You can think of a correlated subquery as a looping mechanism. This is not necessarily how it is implemented, but it describes what it does.
Consider data such as:
row continent area population
1 a 100 19
2 a 200 10
3 a 300 20
4 b 15 2000
The outer query loops through each row. Then it looks at all matching rows. So, it takes record 1:
row continent area population
1 a 100 19
It then runs the subquery:
(SELECT w2.area
FROM world w2
WHERE w2.continent = w.continent AND
w2.population > 0
)
And substitutes in the values from the outer table:
(SELECT w2.area
FROM world w2
WHERE w2.continent = 'a' AND
w2.population > 0
)
This returns the set (100, 200, 300).
Then it applies the condition:
where w1.area >= all (100, 200, 300)
(This isn't really valid SQL but it conveys the idea.)
Well, we know that w1.area = 100, so this condition is false.
The process is then repeated for each of the rows. For the "a" continent, the only row that meets the condition is the third one -- the one with the largest area.
I am trying to find the average value from column B based on the distinct (country) of column A.
Argentina 49.5600
Argentina 31.5100
Austria 353.0700
Austria 67.8800
Belgium 6.2700
Belgium 0.1700
This is part of the table. I am trying to average the values in column B based on country, such as 49.5 + 31.5 averaged for only Argentina, etc.
I have tried several combinations so far with no luck.
select shipcountry, round(avg(freight), 1)
from Table.Orders
order by shipcountry;
select shipcountry,
(select round(avg(freight), 1)
from Table.Orders)
from Table.Orders
order by shipcountry;
The first query only returns one row with a single country and value. The second query returns the countries, but column B is averaged altogether. Is there a way to separate the averages by country?
No subquery needed, you're just missing the GROUP BY clause:
SELECT shipcountry, ROUND(AVG(freight),1)
FROM Table.Orders
GROUP BY shipcountry;
GROUP BY in the docs
I have an assignment where I need to use the world DB in mySQL to find the 5 largest cities and their countries in countries where the government form is any type of monarchy. I am trying it with the distinct clause, and the only info that appears correct is the government column. Everything else is for India. Does anyone have an idea?
select distinct city.name, governmentform, city.population, countrycode
from country, city
where governmentform like='%monarchy%'
order by city.population desc
limit 5;
I have a Users table with these values (stripped down for the example):
Name
City
County
StateProvince
Country
Continent
Strength
Endurance
Intelligence
I basically want a query that returns the highest stat by region for yourself. If you have the highest Strength (67) in the country, highest Endurance (59) in your City, and not the highest Intelligence anywhere, I'd like a 2 row result of:
('Strength', 67, 'Country', 'United States')
('Endurance', 59, 'City', 'Redmond')
Note that if you have the highest Strength in the country, you will also have the highest strength in the state/province, county, and city (but I'd like those not to be returned in the result). I can do this all using multiple SELECT queries, however, I'd like to know how to do this in one single query for efficiency (or if that's even a good idea?). I'd imagine the logic would go something like (pseudo code):
(SELECT FROM Users ORDERBY Strength WHERE Country = 'MyCountry' LIMIT 1) IF Name != 'Me' (SELECT FROM Users ORDERBY Strength WHERE StateProvince = 'MyState' LIMIT 1) ... and so on
Furthermore, the above would also need to work with Endurance and Intelligence. Thanks!
Check this link MySQL control-flow-functions
SELECT CASE 1 WHEN 1 THEN 'one' WHEN 2 THEN 'two' ELSE 'more' END;