Если максимальное количество подробных записей фиксировано и известно, тогда это можно сделать. Чем больше число, тем более утомительным является запрос для кода. Вот почему Природа дала нам вырезку.
В следующем запросе используется несколько трюков. Предложение Common Table Expression (aka Sub-Query Factoring) инкапсулирует запрос в RegistrationDetail, поэтому мы можем легко ссылаться на него в нескольких местах. В подзапросе используется аналитическая функция ROW_NUMBER(), которая позволяет нам идентифицировать каждую детальную запись в группе RegistrationID. Обе эти функции были введены в Oracle 9i, поэтому они не новы, но многие люди до сих пор не знают о них.
В основном запросе используются внешние соединения для одновременного подключения таблицы регистрации к строкам в подзапросе. Он присоединяется к RegistrationID и полученному DetNo.
SQL> with dets as
2 (select
3 registrationid
4 , owner
5 , type
6 , distance
7 , detailid
8 , row_number() over (partition by registrationid
9 order by detailid) as detno
10 from registrationdetail)
11 select
12 reg.registrationid
13 , reg.somedate
14 , reg.totlength
15 , det1.detailid as detId1
16 , det1.owner as owner1
17 , det1.type as type1
18 , det1.distance as distance1
19 , det2.detailid as detId2
20 , det2.owner as owner2
21 , det2.type as type2
22 , det2.distance as distance2
23 , det3.detailid as detId3
24 , det3.owner as owner3
25 , det3.type as type3
26 , det3.distance as distance3
27 from registration reg
28 left join dets det1 on (reg.registrationid = det1.registrationid
29 and det1.detno = 1)
30 left join dets det2 on (reg.registrationid = det2.registrationid
31 and det2.detno = 2)
32 left join dets det3 on (reg.registrationid = det3.registrationid
33 and det3.detno = 3)
34 order by reg.registrationid
35/
REGISTRATIONID SOMEDATE TOTLENGTH DETID1 OW TY DISTANCE1 DETID2 OW TY DISTANCE2 DETID3 OW TY DISTANCE3
-------------- --------- ---------- ---------- -- -- ---------- ---------- -- -- ---------- ---------- -- -- ----------
1 01-JAN-10 5 1 TD UB 1.5 2 AB US 2 3 TD UQ 4
2 01-FEB-10 15 4 AB UQ 13 5 AB UR 13.1
3 05-FEB-09 10 6 TD US 5
SQL>
Очевидно, что если у вас есть четыре Detail записей в RegistrationID вам потребуется четыре из них внешних соединений (и четыре набора столбцов в проекции).
редактировать
Я только перечитывал свой вопрос и заметил трепещут слов «Нет Максимальное число». Извините, в этом случае вам не повезло. Единственный способ решить эту проблему с переменным числом наборов - это динамический SQL, который вы фактически исключили (потому что вам нужно будет создавать дополнительные объекты схемы).
редактировать 2
Существует еще одно решение, которое только об извлечении данных и забыть макет. Oracle позволяет нам объявлять встроенные курсоры, то есть вложенные операторы select
в проекции параллельно скалярам. Это передает проблему отображения вывода на клиентский инструмент.
В этой версии я использую встроенные функциональные возможности Oracle для создания вывода (на основе того, что многие инструменты могут отображать XML в эти дни). Записи RegistrationDetails представляют собой группу в XMLElement под названием REG_DETAILS, которая вложена в каждую регистрационную запись.
with dets as
(select
registrationid
, owner
, type
, distance
, detailid
, row_number() over (partition by registrationid
order by detailid) as detno
from registrationdetail)
select
xmlelement("AllRegistrations"
, xmlagg(
xmlelement("Registration"
, xmlforest(reg.registrationid
, reg.somedate
, reg.totlength
, (select xmlagg(
xmlelement("RegDetail"
, xmlforest(dets.detailid
, dets.owner
, dets.type
, dets.distance
, dets.detno
)
)
)
from dets
where reg.registrationid = dets.registrationid
) as "RegDetails"
)
)
)
)
from registration reg
order by reg.registrationid
/
Это, как правило, плохая идея. Возможно, некоторые подробности о том, как вы собираетесь использовать этот выход, могут помочь кому-то предложить альтернативное решение. –
Причина, по которой это не отличная идея, заключается в том, что SQL - это язык, предназначенный для реляционных баз данных, который всегда связан с отношениями и приводит к отношениям. Ваш желаемый результат не является отношением. см. http://en.wikipedia.org/wiki/Relational_model –