1

Oracle10gを使用しています。そして、私は次のリレーショナル構造を持っています。これは、クライアント側でグリッドビューに正しい列数が表示されるようにフラット化する必要があると思います。

以下のTableAは、enabledフィールドを使用して、そのレコードのいずれかを有効または無効にするように構成できます。

TableBは、フィールドfkを介してTableAに関連する計算値を格納します。docid 1の場合、「nm1」と「nmn4」に対して計算された値がありますが、「nm2」に対しては計算されません。

私の問題は、TableAの特定の構成について、TableBのdocidに計算値があるかどうかに関係なく、TableAで有効なレコードの完全な補完を持つレコードセットを返す必要があることです。私が動的に作成しようとしている出力を以下に示します。

何か案は?

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
4

2 に答える 2

1

これは、私にはピボットクエリの亜種のように見えます。テーブルBをテーブルAに対して結合し、有効化を制限することでフィルタリングを実行できます(のようなものselect B.* from B, A where B.A_id = A.id and A.enabled = 1)。次に、それをピボットできます。

于 2010-10-20T17:03:03.987 に答える
0

これを行うためのより良い方法があると確信していますが、これは私が思いついたものです。また、あなたが投稿した質問は少し曖昧に見えるので、私が質問に正しく答えているかどうかは完全にはわかりません。

まず、考えられるすべての結果のスパーステーブルを取得する必要があります。次に、再度結合して値を取得します。

これは、単一列のデータとして出力されます。動的SQLなどを使用してクエリを作成せずに、クエリごとにカスタムの列数を設定することは実際には不可能です。

sys_connect_by_pathは、データの複数の行を1つの行に連結するために使用されます。

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
于 2010-10-20T15:25:34.673 に答える