Oracle - 如何在分层查询中使用连接并避免笛卡尔积
Oracle - How to use join in hierarchical query and avoid cartesian product
我需要来自两个 table 的 select 数据 - 第一个保存层次结构数据 (STR
table) 和另一个,比方说,起点一个层次结构 (REQ
table),我需要 select 层次结构并将其与 REQ
table.
中的另一列合并
这是一个例子:
CREATE TABLE REQ (prop int, ord varchar2(10));
CREATE TABLE STR (par varchar2(10), chld varchar2(10));
INSERT INTO REQ VALUES (100,'A');
INSERT INTO REQ VALUES (101,'A');
INSERT INTO REQ VALUES (102,'B');
INSERT INTO STR VALUES ('A','A1');
INSERT INTO STR VALUES ('A','A2');
INSERT INTO STR VALUES ('A1','A3');
INSERT INTO STR VALUES ('A2','A5');
INSERT INTO STR VALUES ('A3','A6');
INSERT INTO STR VALUES ('B','B1');
INSERT INTO STR VALUES ('B','B2');
来自 STR
table 的基本查询给出,例如,这个层次结构:
SELECT par, chld, level
FROM STR
CONNECT BY PRIOR chld = par
START WITH PAR IN (SELECT ord FROM REQ WHERE prop = 100);
层次结构正常:
PAR CHLD LEVEL
---------- ---------- ----------
A A1 1
A1 A3 2
A3 A6 3
A A2 1
A2 A5 2
我需要从 REQ
table 添加到列 prop
的结果值中。 我希望得到这样的结果:
PAR CHLD LEVEL PROP
---------- ---------- ---------- -----
A A1 1 100
A1 A3 2 100
A3 A6 3 100
A A2 1 100
A2 A5 2 100
当我尝试将 JOIN 和 CONNECT BY 中的 table 组合在一起时,我得到类似笛卡尔积的结果,有些行是重复的:
SELECT STR.par, STR.chld, level, REQ.prop, REQ.ord
FROM STR
, REQ
WHERE REQ.prop = 100
CONNECT BY PRIOR STR.chld = STR.par
START WITH STR.PAR = REQ.ord;
结果不是我想要的:
PAR CHLD LEVEL PROP ORD
---------- ---------- ---------- ---------- ----------
A A1 1 100 A
A1 A3 2 100 A
A3 A6 3 100 A
A3 A6 3 100 A ! extra
A3 A6 3 100 A ! rows !
A1 A3 2 100 A !
A3 A6 3 100 A !
A3 A6 3 100 A !
A3 A6 3 100 A !
A A2 1 100 A
A2 A5 2 100 A
A2 A5 2 100 A !
12 rows selected
我有什么方法可以更正查询以获得预期数据吗?
以下查询应该可以解决问题 - 不知道它是否理想但它会起作用:
SELECT DISTINCT STR.par, STR.chld, level
, connect_by_root req.prop AS prop
, connect_by_root req.ord AS ord
FROM str
LEFT JOIN REQ
ON REQ.ord = str.par
CONNECT BY PRIOR STR.chld = STR.par
START WITH REQ.prop = 100
我找到了另一种方法 - 不知道它是否理想但它似乎有效:
SELECT STR.par, STR.chld, level, REQ.prop, REQ.ord
FROM STR
, REQ
CONNECT BY PRIOR STR.chld = STR.par
AND PRIOR REQ.prop = REQ.prop
START WITH STR.PAR = REQ.ord AND REQ.prop = 100;
我需要来自两个 table 的 select 数据 - 第一个保存层次结构数据 (STR
table) 和另一个,比方说,起点一个层次结构 (REQ
table),我需要 select 层次结构并将其与 REQ
table.
这是一个例子:
CREATE TABLE REQ (prop int, ord varchar2(10));
CREATE TABLE STR (par varchar2(10), chld varchar2(10));
INSERT INTO REQ VALUES (100,'A');
INSERT INTO REQ VALUES (101,'A');
INSERT INTO REQ VALUES (102,'B');
INSERT INTO STR VALUES ('A','A1');
INSERT INTO STR VALUES ('A','A2');
INSERT INTO STR VALUES ('A1','A3');
INSERT INTO STR VALUES ('A2','A5');
INSERT INTO STR VALUES ('A3','A6');
INSERT INTO STR VALUES ('B','B1');
INSERT INTO STR VALUES ('B','B2');
来自 STR
table 的基本查询给出,例如,这个层次结构:
SELECT par, chld, level
FROM STR
CONNECT BY PRIOR chld = par
START WITH PAR IN (SELECT ord FROM REQ WHERE prop = 100);
层次结构正常:
PAR CHLD LEVEL
---------- ---------- ----------
A A1 1
A1 A3 2
A3 A6 3
A A2 1
A2 A5 2
我需要从 REQ
table 添加到列 prop
的结果值中。 我希望得到这样的结果:
PAR CHLD LEVEL PROP
---------- ---------- ---------- -----
A A1 1 100
A1 A3 2 100
A3 A6 3 100
A A2 1 100
A2 A5 2 100
当我尝试将 JOIN 和 CONNECT BY 中的 table 组合在一起时,我得到类似笛卡尔积的结果,有些行是重复的:
SELECT STR.par, STR.chld, level, REQ.prop, REQ.ord
FROM STR
, REQ
WHERE REQ.prop = 100
CONNECT BY PRIOR STR.chld = STR.par
START WITH STR.PAR = REQ.ord;
结果不是我想要的:
PAR CHLD LEVEL PROP ORD
---------- ---------- ---------- ---------- ----------
A A1 1 100 A
A1 A3 2 100 A
A3 A6 3 100 A
A3 A6 3 100 A ! extra
A3 A6 3 100 A ! rows !
A1 A3 2 100 A !
A3 A6 3 100 A !
A3 A6 3 100 A !
A3 A6 3 100 A !
A A2 1 100 A
A2 A5 2 100 A
A2 A5 2 100 A !
12 rows selected
我有什么方法可以更正查询以获得预期数据吗?
以下查询应该可以解决问题 - 不知道它是否理想但它会起作用:
SELECT DISTINCT STR.par, STR.chld, level
, connect_by_root req.prop AS prop
, connect_by_root req.ord AS ord
FROM str
LEFT JOIN REQ
ON REQ.ord = str.par
CONNECT BY PRIOR STR.chld = STR.par
START WITH REQ.prop = 100
我找到了另一种方法 - 不知道它是否理想但它似乎有效:
SELECT STR.par, STR.chld, level, REQ.prop, REQ.ord
FROM STR
, REQ
CONNECT BY PRIOR STR.chld = STR.par
AND PRIOR REQ.prop = REQ.prop
START WITH STR.PAR = REQ.ord AND REQ.prop = 100;