Oracle按级别复杂连接

时间:2015-08-01 16:39:05

标签: sql oracle stored-procedures plsql

我对查询有困难,其目的是将一行拆分为两行。

我的示例数据:

       ID OLD                      NEW                    
---------- ------------------------ ------------------------
        12 L-D / T-E                L-E / T-E               
        13 L-D / T-E                L-D / T-D               
        14 L-D / T-E                L-E / T-D 

新旧价值不同的地方,我想拆分它们,所以我的输出应该是:

id | OLD | NEW
12 | L-D | L-E  //in this instance T hasn't changed so I will ignore it.
13 | T-E | T-D  //similar to the above but this time only add T
14 | L-D | L-E  //both values have changed, two rows required
14 | T-E | T-D

我已经组织了一个“工作”的工作。例如,但结果是重复的。我认为问题在于逐级连接,我对Oracle来说很新,所以调试很难。

非常感谢任何帮助。

这是我用来删除,创建和运行查询的查询:

它在sqldeveloper中运行良好,但不确定sqlplus是否会被它打动。

    drop table t;
CREATE TABLE T
    (id int, 
     old varchar2(24), 
     new varchar2(24))
;

INSERT ALL

      INTO T (id, old, new)
         VALUES (12, 'L-D / T-E', 'L-E / T-E')
      INTO T (id, old, new)
         VALUES (13, 'L-D / T-E', 'L-D / T-D')
      INTO T (id, old, new)
         VALUES (14, 'L-D / T-E', 'L-E / T-D')

SELECT * FROM dual
;


SELECT * FROM T;

--insert into t (id, old, new) values (1,'dasdsad', 'asdasd');

BEGIN
INSERT INTO t (id,old, new) 

  WITH DATA AS
      (SELECT id,OLD, new
      FROM t
      WHERE 
      --multiple changes
      (
        (SUBSTR(OLD,3,1) <> SUBSTR(NEW, 3,1)
        AND SUBSTR(OLD, 9)    <> SUBSTR(NEW, 9)
        )
      OR
        --row 2 old/new L are same, old/new T are not
        (SUBSTR(OLD,3,1) = SUBSTR(NEW, 3,1)
        AND SUBSTR(OLD, 9)    <> SUBSTR(NEW, 9)
        )

      OR
        --row 1
        (SUBSTR(OLD,3,1) <> SUBSTR(NEW, 3,1)
        AND SUBSTR(OLD, 9) = SUBSTR(NEW, 9)
        )

      )
      )

    SELECT id, trim(regexp_substr(OLD, '[^/]+', 1, LEVEL)) OLD,  
               trim(regexp_substr(NEW, '[^/]+', 1, LEVEL)) NEW
    FROM DATA
      CONNECT BY (LEVEL <= regexp_count(new, '/')+1);

END;
 /

1 个答案:

答案 0 :(得分:3)

我个人不会使用递归语法。

首先,我将创建虚拟列(或视图)以从查询中消除繁琐的substring函数,这样:

ALTER TABLE t ADD ( OLD_LEFT AS ( Substr( OLD, 1, 3 )));
ALTER TABLE t ADD ( OLD_RIGHT AS ( Substr( OLD, 7, 3 )));
ALTER TABLE t ADD ( NEW_LEFT AS ( Substr( NEW, 1, 3 )));
ALTER TABLE t ADD ( NEW_RIGHT AS ( Substr( NEW, 7, 3 )));

或:

CREATE VIEW tt AS
SELECT ID, OLD, NEW,
       Substr( OLD, 1, 3 ) As OLD_LEFT,
       Substr( OLD, 7, 3 ) As OLD_RIGHT,
       Substr( NEW, 1, 3 ) As NEW_LEFT,
       Substr( NEW, 7, 3 ) As NEW_RIGHT
FROM t;

经过上述简化后,查询非常简单,只需:

SELECT id, OLD_LEFT , NEW_LEFT 
FROM T
WHERE OLD_LEFT <> NEW_LEFT
UNION ALL
SELECT id, OLD_RIGHT , NEW_RIGHT 
FROM T
WHERE OLD_RIGHT <> NEW_RIGHT
ORDER BY ID

演示:http://sqlfiddle.com/#!4/2fdc4/2