sql连接两个没有键的表

时间:2017-04-14 07:53:15

标签: sql oracle join

我有一个包含'父子行'的平面文件: 通常,每行都有这两列:

  

type_record

     

渐进

父(行)type_record的值为'01' 相反,子(行)的type_record值为 '02'

渐进式它就像一个计数器

这里是文件的一个快照(忽略空格)

https://pastebin.com/raw/tmpWfFiX

01 00001   father-columns................ --new father
02 00001   child columns.................
02 00001   child columns.................
02 00001   child columns.................

01 00002   fathercolumns................. --new father
02 00002   child columns.................
02 00002   child columns.................
02 00002   child columns.................

01 00003   fathercolumns................. --new father
02 00003   child columns.................
02 00003   child columns.................

01 00001   fathercolumns................. --new father (identical as the row before)
02 00001   child columns.................
02 00001   child columns.................

所以我需要在这两个表之间创建一个关系

我怎么能这样做?

由于

编辑:

我创建了两个独立的外部表,一个用于父行,另一个用于子行。

正如您所期望的那样阅读行,我正在使用 LOAD_WHEN ='progressive'。 这是用于读取父行的创建表

CREATE TABLE "EXT_FATHER" 
(
    "type_record"   VARCHAR2(2 BYTE),
    "progressive"   VARCHAR2(5 BYTE),
    "fields_other1" VARCHAR2(7 BYTE),
    "fields_other2" VARCHAR2(6 BYTE)) 
    ORGANIZATION EXTERNAL
    (
      TYPE ORACLE_LOADER DEFAULT DIRECTORY "DIR"
      ACCESS PARAMETERS ( 
        RECORDS DELIMITED BY newline
        BADFILE DIR:'file.bad'
        LOGFILE DIR:'file.log'
        DISCARDFILE DIR:'file.dsc'
        LOAD WHEN type_record = '01'
        FIELDS
        (
         type_record POSITION(1:2)    CHAR(2),
         progressive POSITION(3:5)    CHAR(5),
         fields_other1 POSITION(8:7)  CHAR(7),
         fields_other2 POSITION(15:6) CHAR(6)
        .....
        )
  ) LOCATION ( "DIR":'  file.txt' ) 
);

这是用于读取子行的create table

CREATE TABLE "EXT_CHILD" 
(
        "type_record"   VARCHAR2(2 BYTE),
        "progressive"   VARCHAR2(5 BYTE),
        "fields_other1" VARCHAR2(20 BYTE),
        "fields_other2" VARCHAR2(9 BYTE)) 
        ORGANIZATION EXTERNAL
        (
          TYPE ORACLE_LOADER DEFAULT DIRECTORY "DIR"
          ACCESS PARAMETERS ( 
            RECORDS DELIMITED BY newline
            BADFILE DIR:'file.bad'
            LOGFILE DIR:'file.log'
            DISCARDFILE DIR:'file.dsc'
            LOAD WHEN type_record = '02'
            FIELDS
            (
             type_record POSITION(1:2)    CHAR(2),
             progressive POSITION(3:5)    CHAR(5),
             fields_other1 POSITION(8:20) CHAR(20),
             fields_other2 POSITION(28:9) CHAR(9)
            .....
            )
      ) LOCATION ( "DIR":'  file.txt' ) 
    );

以示例为例,将数据作为样本,(请查看pastebin) 获取父行的查询将是

SELECT * FROM EXT_FATHER WHERE PROGRESSIVE = '00001'

这会产生2行的结果集...... 但我需要'独特'

因为那时我需要得到更好的

第二个查询类似于

SELECT * FROM EXT_CHILD WHERE PROGRESSIVE = '00001'

但是这会产生第一个父亲的结果 5行... 3 ,然后是第二个父亲的最后一个

1 个答案:

答案 0 :(得分:0)

您的代码看起来像Oracle,因此我假设您使用的是Oracle数据库。

如果要加入这两个表,则需要某种键,无论是复合键还是代理键。如果您无法找到包含该文件中字段的复合键,则必须生成一个代理项。

我不是外部表格的专家,但如果尝试做你需要的话我会尝试遵循的步骤

  1. 创建sequence temp_load_seq;

  2. 将整个文件加载到外部表temp_tab中,每行使用temp_load_seq.nextval()来保存排序;这会给我一个看起来像文件的表格,附加一个"人工行号&#34 ;;

  3. 创建另一个序列surrogate_key_seq;

  4. 创建我的最终成绩表fathers_tabchildren_tab;第一个列会有一个额外的id列,第二个列会有一个额外的father_id列;

  5. 编写一个循环遍历temp_tab的过程,并根据fathers_tab值将其行插入children_tabtype_record;

    1. 在插入fathers_tab时,我会使用id填充其surrogate_key_seq.nextval()字段;
    2. 在插入children_tab时,我会使用father_id填充其surrogate_key_seq.currval()字段。
  6. 通过这种方式,最终表格可以轻松过滤并加入idfather_id

    我并非100%确定第2步是可行的,因为在外部表中使用了一个序列,但从this article来看似乎应该没问题。