Oracle 10g - сглаживает реляционные данные динамически - PullRequest
1 голос
/ 20 октября 2010

Я использую Oracle 10g.и у меня есть следующая реляционная структура, которую, как мне кажется, мне нужно выровнять, чтобы на стороне клиента представление сетки отображало правильное количество столбцов.

В приведенной ниже таблице A можно настроить включение любой из ее записей илиотключено с помощью поля enable.

В TableB хранятся вычисленные значения, относящиеся к TableA, через поле fk.Для docid 1 есть значения, рассчитанные для «nm1» и «nmn4», но не для «nm2».

Моя проблема заключается в том, что для конкретной конфигурации TableA мне нужно вернуть набор записей, содержащий полный наборВключенные записи в Таблице A независимо от того, имеет ли docid в Таблице B вычисленное значение для него.Результат, который я ищу для динамического создания, показан ниже.

Есть идеи?

TableA
id     nm     enabled
1     'nm1'   1
2     'nm2'   1
3     'nm3'   0
4     'nm4'   1


TableB
id     fk(A.id)     docid     value
1      1            1         .8
2      4            1         .6
3      1            2         .3
4      2            2         .4
5      4            2         .7
6      2            3         .6
7      4            3         .8

Output as records
1     'nm1'     .8       'nm2'     null     'nm4'     .6
2     'nm1'     .3       'nm2'     .4       'nm4'     .7
3     'nm1'     null     'nm2'     .6       'nm4'     .8

Ответы [ 2 ]

1 голос
/ 20 октября 2010

Это похоже на подвид сводного запроса для меня. Вы можете выполнить фильтрацию, соединив таблицу B с таблицей A, а затем включив (что-то вроде select B.* from B, A where B.A_id = A.id and A.enabled = 1). Затем вы можете повернуть это.

0 голосов
/ 20 октября 2010

Я уверен, что есть лучший способ сделать это, но это то, что я придумал.Кроме того, вопрос, который вы разместили, кажется немного расплывчатым, поэтому я не совсем уверен, что правильно отвечаю на вопрос.

Сначала вам нужно получить скудную таблицу всех возможных результатов, а затем снова присоединиться кполучить значения.

Это вывод в виде одного столбца данных.На самом деле невозможно создать произвольное количество столбцов для каждого запроса без создания запроса с использованием динамического SQL или чего-либо еще.

sys_connect_by_path используется для объединения нескольких строк данных в одну строку.

with table_a as (
  select 1 as id, 'nm1' as nm, 1 as enabled from dual union all
  select 2 as id, 'nm2' as nm, 1 as enabled from dual union all
  select 3 as id, 'nm3' as nm, 0 as enabled from dual union all
  select 4 as id, 'nm4' as nm, 1 as enabled from dual
),
table_b as (
  select 1 as id, 1 as a_id, 1 as docid, 0.8 as value from dual union all
  select 2 as id, 4 as a_id, 1 as docid, 0.6 as value from dual union all
  select 3 as id, 1 as a_id, 2 as docid, 0.3 as value from dual union all
  select 4 as id, 2 as a_id, 2 as docid, 0.4 as value from dual union all
  select 5 as id, 4 as a_id, 2 as docid, 0.7 as value from dual union all
  select 6 as id, 2 as a_id, 3 as docid, 0.6 as value from dual union all
  select 7 as id, 4 as a_id, 3 as docid, 0.8 as value from dual 
),
cartesian_prod as (
  select b.docid, a.id, a.nm
  from 
    table_a a
    cross join (select distinct docid from table_b) b
  where a.enabled = 1
)
select 
  docid, 
  ltrim(max(sys_connect_by_path(nm || ' ' || value, ', ')), ', ') as value
from (
  select 
    c.docid, 
    c.nm, 
    nvl(to_char(b.value), 'null') as value, 
    row_number() over (partition by c.docid order by c.id) as rown
  from 
    cartesian_prod c 
    left outer join table_b b on (b.docid = c.docid and c.id = b.a_id)
)
start with rown = 1
connect by docid = prior docid and rown = prior rown + 1
group by docid
...