2010-10-20 80 views
1

我正在使用Oracle 10g。並且我有以下關係結構,我認爲我需要在客戶端平坦化,網格視圖顯示正確的列數。下面Oracle 10g - 動態拼合關係數據

表A可以被配置爲擁有它的記錄啓用或使用能字段禁用任何一個。計算經由現場FK相關表A值

表B存儲。對於docid 1,存在針對「nm1」和「nmn4」而不是「nm2」的值。

我的問題是,對於表A的特定配置我需要返回記錄集具有啓用記錄TableA中充分補充表B中的一個文檔ID是否有它的計算值。下面顯示了我期望動態創建的輸出。

任何想法?

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 
+0

你可以提供一些關於輸出的更多細節嗎?我無法理解它是如何形成的... – Nivas 2010-10-20 14:07:34

+0

我剛剛重新格式化了輸出。我認爲它會更清楚。 – user481779 2010-10-20 14:10:37

回答

1

這看起來像一個亞種pivot query給我。您可以通過將表B連接到表A,然後限制啓用(如select B.* from B, A where B.A_id = A.id and A.enabled = 1)來進行篩選。然後你可以轉動它。

+0

我從上面給出的鏈接中使用了您的示例,它完全符合我需要的內容。感謝所有迴應的人。 – user481779 2010-10-21 19:16:05

0

我敢肯定有一個更好的辦法來做到這一點,但是這是我想出來的。另外,你發佈的問題似乎有點模糊,所以我不完全確定我正確回答了這個問題。

首先,你需要獲得所有可能結果的疏表,然後再加入得到的值。

這具有這樣的輸出作爲數據的單個列。如果沒有使用動態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 
+0

非常感謝。你給了我一些想法。 – user481779 2010-10-20 16:39:35