Oracle从两个表创建视图

时间:2012-02-10 07:26:41

标签: oracle view

我在Oracle 11g中有以下表格:

表A

SITE_ID       SITE_NAME        VECTOR       .........MANY OTHER FIELDS

BN9032U850    REY DEL MAR      ENSENADA
BS2362U850    COSTA BAJA       LA PAZ
BS2601U850    LA PAZ           LA PAZ
BS2606U850    CONQUISTADORES   LA PAZ
BN2679U850    COAST CAST       TIJUANA
BN7116U850    PALACIO AZTECA   TIJUANA

表B

SITE_ID       SITE_NAME             VECTOR       .........MANY OTHER FIELDS

BN9032        REY DEL MAR           (null)
BN9033        BRISAS DEL MAR        (null)
BS2601        CUMBRES DE LA PRESA   (null)
BN9038G850    REAL DEL CASTILLO     (null)
BS0014G850    SAN BRUNO             (null)

正如你在两个表中看到的还有很多其他字段,但我只对我写的那些字段感兴趣(SITE_ID,SITE_NAME,VECTOR)。

我想要实现的是创建一个包含这三列的视图,但是包含来自两个表的信息。

但这种观点必须符合这一条件:

  • 请记住两个表中SITE_ID字段中的前6个字符。

例如,表A中的第一条记录具有此SITE_ID“BN9032U850”,因此如果我们对前6个字符进行子字符串处理,则生成的SITE_ID将为“BN9032”。但正如您所看到的,表B中的第一条记录具有相同的SITE_ID,因此会有重复的记录。

如果发生这种情况,要添加到视图中的记录必须是表A中的记录,而不是表B中的记录。最后我想实现此输出:

查看输出

SITE_ID   SITE_NAME           VECTOR

BN9032    REY DEL MAR         ENSENADA    --->Table A
BS2362    COSTA BAJA          LA PAZ      --->Table A
BS2601    LA PAZ              LA PAZ      --->Table A
BS2606    CONQUISTADORES      LA PAZ      --->Table A
BN2679    COAST CAST          TIJUANA     --->Table A
BN7116    PALACIO AZTECA      TIJUANA     --->Table A
BN9033    BRISAS DEL MAR      (null)      --->Table B
BN9038    REAL DEL CASTILLO   (null)      --->Table B
BS0014    SAN BRUNO           (null)      --->Table B

我一直用这句话来处理它,但似乎有些不对劲。

SELECT SUBSTR(SITE_ID,1,6) SITE_ID,SITE_NAME, VECTOR FROM TABLE_A
WHERE(SUBSTR(SITE_ID,1,6)) NOT IN
(SELECT SUBSTR(SITE_ID,1,6) FROM TABLE_B)
UNION
SELECT SUBSTR(SITE_ID,1,6) SITE_ID,SITE_NAME, VECTOR FROM TABLE_B
WHERE(SUBSTR(SITE_ID,1,6)) NOT IN
(SELECT SUBSTR(SITE_ID,1,6) FROM TABLE_A);

我希望你可以帮助我使用一些示例代码来开始。

2 个答案:

答案 0 :(得分:2)

UNION的前半部分不需要NOT IN子句:

SELECT SUBSTR(SITE_ID,1,6) SITE_ID,SITE_NAME, VECTOR
  FROM TABLE_A
UNION
SELECT SUBSTR(SITE_ID,1,6) SITE_ID,SITE_NAME, VECTOR
  FROM TABLE_B
 WHERE(SUBSTR(SITE_ID,1,6)) NOT IN (SELECT SUBSTR(SITE_ID,1,6) FROM TABLE_A);

Table_A中的所有内容以及表_A中都找不到Table_B中的那些行。

答案 1 :(得分:0)

如果您希望table_A中的所有内容都不在table_B中,我会在第二个条件中使用联接。您应该在两个表上的substr(site_id,1,6)上都有一个功能索引,如果可能的话,它是唯一的,以加快速度。

这在功能上与Jonathan Leffler's answer类似,但它更清楚地表明,如果您从此视图中选择所有内容,那么您将完全扫描并完全索引扫描table_A - 假设建议的索引是到位。它还使得更明确的是,如果你进入索引,那么你只会在两个表上进行索引范围/唯一扫描。

select substr(site_id,1,6), as site_id ,site_name, vector
  from table_a
 union
select substr(site_id,1,6), as site_id ,site_name, vector
  from table_b b
  left outer join table_a a
    on substr(b.site_id,1,6) = substr(a.site_id,1,6)
 where a.site_id is null