#sql #db2 #subquery #average #min
#sql #db2 #подзапрос #среднее #min
Вопрос:
Я работаю над db2 из ibm cloud и sql. Мои данные содержат 1 таблицу с 3 столбцами: школы, их общая производительность (уровень) и местоположение. Я хочу найти местоположение с наименьшим СРЕДНИМ уровнем, используя подзапрос с помощью avg и min.
У меня есть этот код, который выполняет эту работу:
select location, avg(level) as avglevel
from schools_table
group by location
order by avglvl
limit 1;
Но я ищу что-то более похожее:
select location
from schools_table
where level = (select min(level) from schools_table);
это дает минимум всех значений. Однако меня интересует минимум среднего значения.
пожалуйста, помогите Большое спасибо за любую информацию.
Артуро
Комментарии:
1. Что вам не нравится в вашем коде, который использует
order by
иlimit
?2. Я немного потерялся. У вас есть две таблицы, упомянутые в вопросе. Описание таблицы в тексте не соответствует столбцам, используемым в запросах. Примеры данных и желаемые результаты действительно помогли бы.
3. Привет! Извините, что я перепутал две таблицы, вы правы. Я уже исправил это, и я думаю, что ответ от Фахми — это то, что я искал.
4. @GMB, ты прав, мне особенно не нравится строка limit . Вместо упорядочивания по и ограничения 1 строкой я хотел получить ответ с помощью функции min() .
5. Что, если два местоположения имеют одинаковый средний уровень и оба равны минимальному? Один из них будет потерян, если вы используете
limit
.
Ответ №1:
Вы можете попробовать следующее —
with cte as
(
select location,avg(safety_score) as safety_score from chicago_public_schools group by location
)
select community_area_name
from chicago_public_schools
where safety_score = (select min(safety_score) from cte)
Комментарии:
1. Спасибо! Я думаю, что это все. Я новичок в sql и не знал о операторе with . Просто из любопытства, возможно ли это без него? Как, каким-то образом, сгенерировать эту переменную / новую таблицу cte в подзапросе?
Ответ №2:
Я думаю, вам просто нужно
select community_area_name
from chicago_public_schools
where safety_score = (select avg(safety_score)
from chicago_public_schools
group by location
order by avg(safety_score) asc --sort the result
limit 1); --pick the smallest avg
Теперь .. я не рекомендую это по соображениям производительности, но если вы действительно хотите избежать order by
with limit
, а также не хотите использовать a cte
, вы можете использовать a window function
select community_area_name
from chicago_public_schools
where safety_score = (select distinct min(avg(safety_score)) over()
from chicago_public_schools
group by location)
И если вы хотите избежать window functions
этого, вы могли бы полагаться исключительно на подзапросы, но тогда — это слишком некрасиво
select community_area_name
from chicago_public_schools a
join (select min(safety_score) as min_safety_score
from (select avg(safety_score) as safety_score
from chicago_public_schools
group by location) b) c on a.safety_score = c.min_safety_score
Комментарии:
1. Привет, спасибо за ответ! Я искал код, который получает наименьшее среднее значение с помощью функции min(). Ваш способ очень похож на тот, который у меня есть в вопросе. Однако вам удается сделать это в подзапросе, который я также нахожу интересным. Еще раз спасибо!
2. @arturo451 Нет проблем, я добавил другую альтернативу для обучения