powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Можно ли сделать выборку одним запросом с аналитическими функциями?
6 сообщений из 6, страница 1 из 1
Можно ли сделать выборку одним запросом с аналитическими функциями?
    #39626395
Фотография samatom
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Даны расходы клиентов
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
with t as
(
select 'Витек' name, 100 amount from dual union all
select 'Витек' name, 200 amount from dual union all
select 'Витек' name, 300 amount from dual union all
select 'Егор' name, 500 amount from dual union all
select 'Егор' name, 100 amount from dual union all
select 'Егор' name, 200 amount from dual union all
select 'Женя' name, 800 amount from dual union all
select 'Женя' name, 200 amount from dual union all
select 'Женя' name, 500 amount from dual
)
select * from t


Необходимо одним запросом вывести имена клиентов с максимальными и минимальными суммарными расходами.
Т.е. на выходе должна быть одна строка с двумя столбцами - "Женя" и "Витек".

Интересует именно вариант одним запросом, без подзапросов. Версия не важна.
Возможно ли вообще? Это не реальная задача, а просто из любви к искусству так сказать.
...
Рейтинг: 0 / 0
Можно ли сделать выборку одним запросом с аналитическими функциями?
    #39626402
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
samatom,

first / last
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
with t as
(
select 'Витек' name, 100 amount from dual union all
select 'Витек' name, 200 amount from dual union all
select 'Витек' name, 300 amount from dual union all
select 'Егор' name, 500 amount from dual union all
select 'Егор' name, 100 amount from dual union all
select 'Егор' name, 200 amount from dual union all
select 'Женя' name, 800 amount from dual union all
select 'Женя' name, 200 amount from dual union all
select 'Женя' name, 500 amount from dual
)
select 
  max(name)keep(dense_rank first order by sum(amount)) first
 ,max(name)keep(dense_rank last  order by sum(amount)) last
from t
group by name
...
Рейтинг: 0 / 0
Можно ли сделать выборку одним запросом с аналитическими функциями?
    #39626407
Фотография samatom
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xtender,
благодарю, а то у самого никак не клеилось, к сожалению. Конечная цель такая - одним запросом вывести клиентов с самыми большими и маленькими тратами, а также города с самыми большими и маленькими тратами (т.е. это также 1 строка, но уже 4 столбца). Как я понимаю, это уже не выбрать одним запросом из-за разных условий группировки?

Добавил в выборку города:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
with t as
(
select 'Витек' name, 100 amount, 'Дефолт-сити' city from dual union all
select 'Витек' name, 200 amount, 'Дефолт-сити' city from dual union all
select 'Витек' name, 300 amount, 'Дефолт-сити' city from dual union all
select 'Егор' name, 500 amount, 'Дефолт-сити' city from dual union all
select 'Егор' name, 100 amount, 'Дефолт-сити' city from dual union all
select 'Егор' name, 200 amount, 'Дефолт-сити' city from dual union all
select 'Женя' name, 800 amount, 'Поребрик-сити' city from dual union all
select 'Женя' name, 200 amount, 'Поребрик-сити' city from dual union all
select 'Женя' name, 500 amount, 'Поребрик-сити' city from dual
)
select * from t
...
Рейтинг: 0 / 0
Можно ли сделать выборку одним запросом с аналитическими функциями?
    #39626453
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
samatomКонечная цель такаяхотелка странная, конечно - зачем запрещать подзапросы, если по факту это все равно два уровня агрегации и читаться без подзапросов будет хуже?

чисто just4fun. крайне не рекомендую такое использовать
если name и city not null:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
with t as
(
select 'Витек' name, 100 amount, 'Дефолт-сити' city from dual union all
select 'Витек' name, 200 amount, 'Дефолт-сити' city from dual union all
select 'Витек' name, 300 amount, 'Дефолт-сити' city from dual union all
select 'Егор' name, 500 amount, 'Дефолт-сити' city from dual union all
select 'Егор' name, 100 amount, 'Дефолт-сити' city from dual union all
select 'Егор' name, 200 amount, 'Дефолт-сити' city from dual union all
select 'Женя' name, 800 amount, 'Поребрик-сити' city from dual union all
select 'Женя' name, 200 amount, 'Поребрик-сити' city from dual union all
select 'Женя' name, 500 amount, 'Поребрик-сити' city from dual
)
select 
  max(name)keep(dense_rank first order by decode(city,null,sum(amount)) nulls last )  name_first
 ,max(name)keep(dense_rank last  order by decode(city,null,sum(amount)) nulls first)  name_last
 ,max(city)keep(dense_rank first order by decode(name,null,sum(amount)) nulls last )  city_first
 ,max(city)keep(dense_rank last  order by decode(name,null,sum(amount)) nulls first)  city_last
from t
group by grouping sets((name),(city))


по-хорошему тут вместо извращения с decode(city,null...) надо было бы использовать grouping_id(name,city) или grouping(name)/grouping(city) - тогда было бы все просто и не было бы ограничения на not null, но оракл не переваривает их - ругается ORA-00934: group function is not allowed here...

Еще более извращенный подход/воркэраунд - использование аналитики с дистинктом:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
with t as
(
select 'Витек' name, 100 amount, 'Дефолт-сити' city from dual union all
select 'Витек' name, 200 amount, 'Дефолт-сити' city from dual union all
select 'Витек' name, 300 amount, 'Дефолт-сити' city from dual union all
select 'Егор' name, 500 amount, 'Дефолт-сити' city from dual union all
select 'Егор' name, 100 amount, 'Дефолт-сити' city from dual union all
select 'Егор' name, 200 amount, 'Дефолт-сити' city from dual union all
select 'Женя' name, 800 amount, 'Поребрик-сити' city from dual union all
select 'Женя' name, 200 amount, 'Поребрик-сити' city from dual union all
select 'Женя' name, 500 amount, 'Поребрик-сити' city from dual
)
select 
 distinct
  max(decode(grouping(name),0,name)) keep(dense_rank first order by decode(grouping(name),0,sum(amount)) nulls last ) over() name_first
 ,max(decode(grouping(name),0,name)) keep(dense_rank last  order by decode(grouping(name),0,sum(amount)) nulls first) over() name_last
 ,max(decode(grouping(city),0,city)) keep(dense_rank first order by decode(grouping(city),0,sum(amount)) nulls last ) over() city_first
 ,max(decode(grouping(city),0,city)) keep(dense_rank last  order by decode(grouping(city),0,sum(amount)) nulls first) over() city_last
from t
group by grouping sets((name),(city))



...
Рейтинг: 0 / 0
Можно ли сделать выборку одним запросом с аналитическими функциями?
    #39626672
Фотография samatom
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xtender,

Спасибо за наводку. Если например, необходимо будет сделать не 2 уровня аггрегации, а, скажем, 10, то, полагаю, будет профит в производительности. Пускай даже в ущерб удобочитаемости кода. Или я заблуждаюсь?
...
Рейтинг: 0 / 0
Можно ли сделать выборку одним запросом с аналитическими функциями?
    #39626693
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
samatomxtender,

Спасибо за наводку. Если например, необходимо будет сделать не 2 уровня аггрегации, а, скажем, 10, то, полагаю, будет профит в производительности. Пускай даже в ущерб удобочитаемости кода. Или я заблуждаюсь?
Мне кажется это зависит от данных, структуры БД, запросов.

Если "full table scan & hash join - наше все", то да, быстрее. А если индексы, мат. view, что-то еще.... то не факт.
...
Рейтинг: 0 / 0
6 сообщений из 6, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Можно ли сделать выборку одним запросом с аналитическими функциями?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]