2012-05-18 96 views
1

背景:加入独特的SQL行时表具有不等的行数

我用来跟踪线影像资料的大型数据库上运行。目前,数据库(Oracle)围绕三个主表构成:

1)地图详细信息表。定义特定地图的所有顶级详细信息,如县/区/城市。每张地图由下表中使用的序列号唯一标识。

2)走廊长度表。基本上,乌鸦飞行多久,以及走廊是在公共还是私人土地上。因此,此处定义的素材只是从A到B的距离。

3)线长表。该表存储有关可以在给定走廊中运行的不同电线的信息。每个工作电压都有一行。因此,例如,走廊可能有几段长度的线; 12KV,33KV和66KV。

(1)中总是会有一个地图记录,但是在(2)和(3)中存在任意数量的行,并且(2)和(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 | 
-------------------------------------------------------------------------------------- 

摘要:

我对长的问题道歉,但它是有点复杂的解释我是什么后。长话短说,我想列出两个子表中的所有行并排(没有特定的顺序),同时为两个表之间的行差的列填充NULL。先谢谢你。

+0

您是否在寻找['FULL JOIN'](http://www.w3schools.com/sql/sql_join_full.asp)?这将为您提供表格的结果,并排显示不匹配记录的空白/空值。 – swasheck

+3

电线与哪条走廊相匹配是否重要? – Gabe

+1

感觉像这个数据库没有正确规范化。这3张桌子的钥匙是什么? –

回答

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; 

但是,如果我是你,我会关注有关在评论中问道,您的初始后的问题;)