Справка по SQL с MAX-запросом - PullRequest
2 голосов
/ 09 июля 2011

У меня есть таблица стран с именем bbc (имя, регион, область, население, ВВП)

Мне нужна таблица с регионом, названием и населением крупнейших (наиболее населенных) стран по регионам.До сих пор я пробовал это:

SELECT region, name, MAX(population)
FROM bbc
GROUP BY region

Это дало мне сообщение об ошибке: ORA-00979: не выражение GROUP BY

Я пытался изменить на регион GROUP BY, nameно это не дает мне правильную таблицу

Ответы [ 3 ]

7 голосов
/ 09 июля 2011

Вы можете использовать аналитику для таких запросов:

SELECT name, region, population
  FROM (SELECT region, name, population
             , MAX(population) OVER (PARTITION BY region) maxpop
          FROM bbc)
 WHERE population = maxpop;

Встроенное представление дает вам таблицу, которая выглядит как ваша базовая таблица, плюс дополнительный столбец с максимальным населением для региона.Выбор высшего уровня дает вам страну, регион и население самой большой страны в каждом регионе.

Для иллюстрации на ограниченном примере:

SELECT * FROM bbc;

REGION          NAME        POPULATION
--------------- -------     ----------
North America   USA         300000000
North America   Canada      100000000
North America   Mexico       50000000
South America   Brazil       50000000
South America   Argentina    40000000
South America   Venezuela    20000000

Добавьте аналитическую функцию:

SELECT region, NAME, population
     , MAX(population) OVER (PARTITION BY region) maxpop
  FROM bbc;

REGION          NAME                POPULATION      MAXPOP
--------------- -------             ----------      ----------
North America   USA                 300000000       300000000
North America   Canada              100000000       300000000
North America   Mexico               50000000       300000000
South America   Brazil               50000000        50000000
South America   Argentina            40000000        50000000
South America   Venezuela            20000000        50000000

Тогда готовое произведение:

NAME    REGION             POPULATION
------- ---------------    -----------
USA     North America       300000000
Brazil  South America        50000000

Еще одно редактирование.Вы можете избежать выбора гнезда, но не подзапроса:

SELECT NAME, region, population
  FROM bbc
 WHERE (region, population) IN
       (SELECT region, MAX(population)
          FROM bbc
         group by region);
3 голосов
/ 10 июля 2011

Вот самый простой и самый короткий способ сделать это, так как Oracle имеет тестирование кортежей, это может сделать код короче:

Во-первых, получите максимальное население для каждого региона:

SELECT region, MAX(population)
FROM bbc
GROUP BY region

Затем протестируйте страны против него:

select region, name, population 
from bbc 
where (region, population) in
      (SELECT region, MAX(population)
       FROM bbc
       GROUP BY region)
order by region

Если вы хотите поддерживать много СУБД, используйте EXISTS:

select region, name, population 
from bbc o
where exists
      (SELECT null -- neutral. doesn't invoke Cargo Cult Programming ;-)
       FROM bbc
       WHERE region = o.region 
       GROUP BY region
       HAVING o.population = MAX(population) )
order by region

Запрос, протестированный здесь, у обоих одинаковый вывод: http://sqlzoo.net/0.htm

http://www.ienablemuch.com/2010/05/why-is-exists-select-1-cargo-cult.html

0 голосов
/ 09 июля 2011

В подавляющем большинстве ваз ошибка ORA-00979 вызвана тем, что неагрегированный столбец не включен в предложение GROUP BY.В этом случае вам также необходимо включить name в предложение GROUP BY.Кроме того, вам не следует вызывать функцию MAX в выражении FROM.

SELECT region, name, MAX(population)
FROM bbc
GROUP BY region, name
...