Berra2k
Berra2k

Reputation: 328

SQL Select MAX and MIN value from a table

I'm using MySql. I have a table that I created from a table of countries. The table pulls the continent and counts the number of countries in that table.

Table creation works fine. I want to then pull the continent with the highest number of countries and the continent with the lowest number of countries.

create table cops as (select 
continent,
count(name) as number_of_countries
from country
group by continent);

select 
continent,
number_of_countries
from cops
where number_of_countries = (select MIN(number_of_countries)) OR (select MAX(number_of_countries));

I'm getting the entire table:

continent   number_of_countries
Antarctica  5
South America   14
Oceania 28
North America   37
Europe  46
Asia    51
Africa  58

All I want though is:

continent   number_of_countries
Antarctica  5
Africa  58

Sorry I don't know how to make a table on here so the rows are screwy.

Also, is there any way to:

  1. Combine the queries into one and get the desired result?
  2. Rank the continents by the number of countries (having a new rank column so for example africa would be 1, asia 2, etc.)?

Upvotes: 1

Views: 7511

Answers (3)

ohmu
ohmu

Reputation: 19752

One way to accomplish this is using UNION which can allow you to combine results from multiple queries (provided they have identical columns). E.g.,

-- Get continent with greatest number of countries.
SELECT
    continent,
    number_of_countries
FROM cops
WHERE continent = (
    SELECT continent
    FROM cops
    ORDER BY number_of_countries DESC
    LIMIT 1
)

UNION

-- Get continent with least number of countries.
SELECT
    continent,
    number_of_countries
FROM cops
WHERE continent = (
    SELECT continent
    FROM cops
    ORDER BY number_of_countries ASC
    LIMIT 1
)

Upvotes: 2

spencer7593
spencer7593

Reputation: 108380

The WHERE clause in your query is wrong. Replacing that with something like this should give you the result you are looking for:

  where number_of_countries = ( SELECT MIN(number_of_countries) FROM cops )
     or number_of_countries = ( SELECT MAX(number_of_countries) FROM cops )

There are other query patterns that will give an equivalent result. As an example of one pattern, using a join to an inline view:

  SELECT c.continent
       , c.number_of_countries
    FROM ( SELECT MIN(n.number_of_countries) AS min_noc
                , MAX(n.number_of_countries) AS max_noc
             FROM cops n
         ) m
    JOIN cops c
      ON c.number_of_countries IN (m.min_noc,m.max_noc)

Upvotes: 0

Barranka
Barranka

Reputation: 21047

Since you already have a table called cops which holds the number of countries per continent, you could do something like this:

-- The UNION approach
select *
from cops
where number_of_countries = (select min(number_of_countries) from cops)
union
select *
from cops
where number_of_countries = (select max(number_of_countries) from cops);

or something like this:

select *
from cops
where number_of_countries in (
          (select min(number_of_countries) from cops),
          (select max(number_of_countries) from cops)
      );

And for your second question: use user variables:

select cops.*, @n := n + 1 as rank
from (select @n := 0) as init,
     cops
order by number_of_countries desc

Upvotes: 1

Related Questions