1

バックグラウンド:

私はワイヤー映像を追跡するために使用される大規模なデータベースに取り組んでいます。現在、データベース(Oracle)は、次の3つの主要なテーブルを中心に構成されています。

1)マップ詳細テーブル。郡/地区/市などの特定のマップのトップレベルの詳細をすべて定義します。各マップは、次の表で使用されているシリアル番号によって一意に識別されます。

2)廊下の長さの表。基本的に、カラスが飛ぶときの配線の長さ、およびその廊下が公有地または私有地にあるかどうか。したがって、ここで定義されるフッテージは、単にAからBまでの距離です。

3)線長表。このテーブルには、特定のコリドーで配線できるさまざまなワイヤに関する情報が格納されています。動作電圧ごとに1つの行があります。したがって、廊下には、たとえば、いくつかの長さのワイヤがあります。12KV、33KV、および66KV。

(1)には常に単一のマップレコードがありますが、(2)と(3)には任意の数の行があり、(2)と(3)の行数は通常一致しません。

質問:

各フッテージが1回だけ報告されるように、これら3つのテーブルを結合する方法を探しています。これは例によって最もよく示されています。以下は、サンプルレコードセットです。

Map Details:
-------------------------------------------
| SERIAL_NO | CNTY | DIST | MAP_NO (Name) |
|-----------------------------------------|
|         1 |   33 |   88 | 123-4567-8    |
-------------------------------------------

Corridor Details:
------------------------------------
| SERIAL_NO | PROPRTY_CD | CORR_FT |
|----------------------------------|
|         1 |     PUBLIC |     100 |
|         1 |    PRIVATE |     200 |
------------------------------------

Wire Details
---------------------------------
| SERIAL_NO | OPER_KV | WIRE_FT |
|-------------------------------|
|         1 |      12 |     300 |
|         1 |      33 |     200 |
|         1 |      66 |     200 |
---------------------------------

私が求めている最終的な出力は、次のようになります。

--------------------------------------------------------------------------------------
| SERIAL_NO | CNTY | DIST | MAP_NO (Name) | PROPRTY_CD | CORR_FT | OPER_KV | WIRE_FT |
|------------------------------------------------------------------------------------|
|         1 |   33 |   88 | 123-4567-8    |     PUBLIC |     100 |      12 |     300 |
|         1 |   33 |   88 | 123-4567-8    |    PRIVATE |     200 |      33 |     200 |
|         1 |   33 |   88 | 123-4567-8    |       NULL |    NULL |      66 |     200 |
--------------------------------------------------------------------------------------

注: ワイヤーと廊下の映像は、ほとんどの場合一致しません(簡潔にするために、ワイヤーマルチプライヤーなどはここには示されていません)。また、コリドーテーブルには、ワイヤテーブル(ワイヤが含まれていないコリドー)よりも多くの行がある場合や、その逆(複数のワイヤが配線されているコリドー)がある場合があります。

この問題に対してさまざまなアプローチを試しましたが、希望する出力が得られないようです。私が試したすべての結合の結果、次の値と同様の値が複製されました。

BAD:
--------------------------------------------------------------------------------------
| SERIAL_NO | CNTY | DIST | MAP_NO (Name) | PROPRTY_CD | CORR_FT | OPER_KV | WIRE_FT |
|------------------------------------------------------------------------------------|
|         1 |   33 |   88 | 123-4567-8    |     PUBLIC |     100 |      12 |     300 |
|         1 |   33 |   88 | 123-4567-8    |     PUBLIC |     100 |      33 |     200 |
|         1 |   33 |   88 | 123-4567-8    |     PUBLIC |     100 |      66 |     200 |
|         1 |   33 |   88 | 123-4567-8    |    PRIVATE |     200 |      12 |     300 |
|         1 |   33 |   88 | 123-4567-8    |    PRIVATE |     200 |      33 |     200 |
|         1 |   33 |   88 | 123-4567-8    |    PRIVATE |     200 |      66 |     200 |
--------------------------------------------------------------------------------------

概要:

長い質問をお詫びしますが、私が何を求めているのかを説明するのはやや複雑です。簡単に言うと、2つのテーブル間の行の違いの列にNULLを入力しながら、両方の子テーブルのすべての行を並べて(順不同で)リストしたいと思います。前もって感謝します。

4

1 に答える 1

2

設定方法でのタスクは、次の方法でブルートフォースすることができます

--pseudo-tables with sample data
with t_map  as (select 1 serial_no, 33 cnty,  88 dist, '12345678' map_no from dual),
 t_corr as (select 1 serial_no, 'PUBLIC' property_cd, 100 corr_ft from dual union all
            select 1, 'PRIVATE', 200 from dual),
 t_wire as (select 1 serial_no, 12 oper_kv, 300 wire_ft from dual union all 
            select 1, 33, 200 from dual union all
            select 1, 66, 200 from dual)
--query itself
select m.serial_no, m.cnty, m.dist, m.map_no, r.*
  from  t_map m join 
        (select nvl(c.serial_no, w.serial_no)  serial_no, c.property_cd, c.corr_ft, w.oper_kv, w.wire_Ft from (
                        (select t_corr.*, row_number() over(partition by serial_no order by serial_no) rn from t_corr) c 
              full join (select t_wire.*, row_number() over(partition by serial_no order by serial_no) rn from t_wire) w 
                     on c.serial_no = w.serial_no and (c.rn = w.rn)
                       )
        ) r on r.serial_no = m.serial_no;

しかし、私があなたなら、あなたの最初の投稿へのコメントで尋ねられる質問について心配するでしょう;)

于 2012-05-18T19:02:15.380 に答える