Получите ограниченное количество ОТДЕЛЬНЫХ полей, упорядоченных по некоторому значению, если вы не можете УПОРЯДОЧИТЬ ИХ ПО невыбранным столбцам

#sql #hiveql

Вопрос:

Вопрос

У меня есть стол tmpcalc в Улье, который выглядит так:

 | country_name | unemp | ------------------------------- | Latvia | 22 | | Spain | 24 | | Spain | 21 | | Austria | 3 | | Lithuania | 20 | | Belgium | 5 | | Greece | 21 |  

Я хочу создать запрос для получения названия 3 различных стран, которые связаны с самыми высокими unemp значениями:

 Spain Latvia Greece  

Что я пробовал

Обычно я ожидал бы, что это сработает:

 SELECT DISTINCT(country_name) FROM tmpcalc ORDER BY unemp DESC LIMIT 3;  

Однако HiveQL не позволяет вам упорядочивать значения по значениям, для которых вы не выбираете, так что это бесполезно.


Обычно я решаю эту проблему с помощью чего-то вроде этого:

 SELECT country_name FROM (  SELECT country_name, unemp  FROM tmpcalc  ORDER BY unemp DESC) a LIMIT 3;  

Это возвращает список всех стран, отсортированных в порядке убывания. Однако у нас есть проблема с тем, что «Испания» дублируется в этом списке, так как имеет два из 3 самых высоких unemp значений:

 Spain Latvia Spain  

К сожалению, простое добавление DISTINCT вокруг внешнего country_name поля не работает, так как это нарушает порядок и теперь возвращает три страны в алфавитном порядке:

 SELECT DISTINCT(country_name) FROM (  SELECT country_name, unemp  FROM tmpcalc  ORDER BY unemp DESC) a LIMIT 3;  
 Austria Belgium Greece  

Комментарии:

1. Как страна дважды попадает в ваш первоначальный список?

2. Что делать, если вы добавите ограничение после ORDER BY unemp DESC в подзапросе, например ORDER BY unemp DESC limit 1000 ?

3. @JeffUK Это уровни безработицы в разных странах на протяжении многих лет. В исходной таблице в каждом кортеже был дополнительный атрибут «год», но я опустил его, чтобы вопрос был кратким.

4. Не могли бы вы сначала сгруппировать таблицу с помощью max(), а затем получить список различных стран и значений?

5. @JeffUK, в конце концов, именно этим я и занялся 🙂

Ответ №1:

Это самый простой ответ, который я нашел:

 SELECT country_name FROM (  SELECT country_name, MAX(unemp) AS unemp  FROM tmpcalc  GROUP BY country_name  ORDER BY unemp DESC LIMIT 5 );  

Важным моментом является удаление всех записей из одной страны, за исключением самой высокой (через MAX и GROUP BY ), прежде чем применять ограничение.