我对查询有困难,其目的是将一行拆分为两行。
我的示例数据:
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;
/
答案 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