背景
我正在开发一个用于跟踪线路片段的大型数据库。目前,数据库(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 :(得分: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;
但是,如果我是你,我会关注你的评论中提到的问题;)