Возможно, вы ищете функцию collect()
, которая дает вам вложенную таблицу как часть вашего основного набора результатов.
Вот пример использования данных схемы HR по умолчанию:
select d.department_id,
count(e.employee_id) as cnt,
cast(collect(e.first_name) as sys.odcivarchar2list) as names
from departments d
left join employees e on e.department_id = d.department_id
group by d.department_id;
DEPARTMENT_ID CNT NAMES
------------- ---------- --------------------------------------------------------------------------------
10 1 ODCIVARCHAR2LIST('Jennifer')
20 2 ODCIVARCHAR2LIST('Michael', 'Pat')
30 6 ODCIVARCHAR2LIST('Den', 'Karen', 'Guy', 'Sigal', 'Shelli', 'Alexander')
40 1 ODCIVARCHAR2LIST('Susan')
...
Вы также можете использовать a cursor()
выражение , чтобы включить подзапрос для каждой строки результатов, который ближе к вашему первоначальному предложению:
select d.department_id,
count(e.employee_id) as cnt,
cursor(
select e2.first_name
from employees e2
where e2.department_id = d.department_id
) as names
from departments d
left join employees e on e.department_id = d.department_id
group by d.department_id;
SQL Разработчик представляет результаты этого (при запуске в виде скрипта) как:
DEPARTMENT_ID CNT NAMES
------------- ---------- --------------------------------------------------------------------------------
10 1 CURSOR STATEMENT : 3
CURSOR STATEMENT : 3
FIRST_NAME
--------------------
Jennifer
20 2 CURSOR STATEMENT : 3
CURSOR STATEMENT : 3
FIRST_NAME
--------------------
Michael
Pat
30 6 CURSOR STATEMENT : 3
CURSOR STATEMENT : 3
FIRST_NAME
--------------------
Den
Alexander
Shelli
Sigal
Guy
Karen
6 rows selected.
...
В этом случае, когда вы обращаетесь к тем же таблицам во внешнем запросе и подзапросе, которые могут быть меньше эффективный; с другой стороны, вы тянете те же блоки данных, так что это может не иметь значения. Для вас может быть проще обработать курсор ref, чем для коллекции. Это в некоторой степени зависит от того, как вы обрабатываете результаты.
Ваше первоначальное предложение - это, в основном, запрос без ключевого слова cursor
; но это приведет к ошибке, потому что скалярное выражение подзапроса должно возвращать одно значение:
select d.department_id,
count(e.employee_id) as cnt,
(
select e2.first_name
from employees e2
where e2.department_id = d.department_id
) as names
from departments d
left join employees e on e.department_id = d.department_id
group by d.department_id;
ORA-01427: single-row subquery returns more than one row
... если я (очень искусственно) не ограничу его отделами, которые, как я знаю, будут возвращаться только одна строка в подзапросе:
select d.department_id,
count(e.employee_id) as cnt,
(
select e2.first_name
from employees e2
where e2.department_id = d.department_id
) as names
from departments d
left join employees e on e.department_id = d.department_id
where d.department_id in (10, 40)
group by d.department_id;
DEPARTMENT_ID CNT NAMES
------------- ---------- --------------------------------------------------------------------------------
10 1 Jennifer
40 1 Susan