自从v2以来,Oracle SQL可以使用其专有的CONNECT BY语法进行分层查询.在他们最新的11g版本2中,他们添加了递归子查询因子,也称为recursive with子句.这是ANSI标准,如果我理解正确,这个也已由其他RDBMS供应商实现.
将connect-by与递归with进行比较时,我注意到使用循环检测时结果集的差异.结果连接对我来说更直观,所以我想知道Oracle的实现是否包含错误,或者这是否是标准ANSI和预期行为.因此,我的问题是,如果您可以使用其他数据库(如MySQL,DB2,SQL Server等)检查递归查询.如果这些数据库当然支持recursive with子句.
以下是它在Oracle 11.2.0.1.0上的工作原理
SQL> select *
2 from t
3 /
ID PARENT_ID
---------- ----------
1 2
2 1
2 rows selected.
Run Code Online (Sandbox Code Playgroud)
使用CONNECT BY语法的查询:
SQL> select id
2 , parent_id
3 , connect_by_iscycle
4 from t
5 connect by nocycle parent_id = prior id
6 start with id = 1
7 /
ID PARENT_ID CONNECT_BY_ISCYCLE
---------- ---------- ------------------
1 2 0
2 1 1
2 rows selected.
Run Code Online (Sandbox Code Playgroud)
这看起来很直观.但是,使用新的ANSI语法,它会再返回一行:
SQL> with tr (id,parent_id) as
2 …Run Code Online (Sandbox Code Playgroud) 我使用PostgreSQL 9.1来查询分层树结构数据,包括与节点连接的边(或元素).数据实际上是用于流网络,但我已经将问题抽象为简单的数据类型.考虑示例tree表.每条边都有长度和面积属性,用于确定网络中的一些有用指标.
CREATE TEMP TABLE tree (
edge text PRIMARY KEY,
from_node integer UNIQUE NOT NULL, -- can also act as PK
to_node integer REFERENCES tree (from_node),
mode character varying(5), -- redundant, but illustrative
length numeric NOT NULL,
area numeric NOT NULL,
fwd_path text[], -- optional ordered sequence, useful for debugging
fwd_search_depth integer,
fwd_length numeric,
rev_path text[], -- optional unordered set, useful for debugging
rev_search_depth integer,
rev_length numeric,
rev_area numeric
);
CREATE INDEX ON tree (to_node);
INSERT INTO …Run Code Online (Sandbox Code Playgroud) postgresql recursive-query common-table-expression hierarchical-query transitive-closure-table
假设我们有以下表格
create table Employee(
2 EMPNO NUMBER(3),
3 ENAME VARCHAR2(15 BYTE),
4 HIREDATE DATE,
5 ORIG_SALARY NUMBER(6),
6 CURR_SALARY NUMBER(6),
7 REGION VARCHAR2(1 BYTE),
8 MANAGER_ID NUMBER(3)
9 )
Run Code Online (Sandbox Code Playgroud)
和
create table job (
2 EMPNO NUMBER(3),
3 jobtitle VARCHAR2(20 BYTE)
4 )
5 /
Run Code Online (Sandbox Code Playgroud)
我对以下查询的作用感兴趣
SELECT empno, manager_id, ename
2 FROM employee
3 START WITH empno = 1
4 CONNECT BY PRIOR empno = manager_id;
Run Code Online (Sandbox Code Playgroud)
我的理解,这个代码选择empno,manager_id,ename从员工,它开始选择从该行地方empno=1,但不明白这行做了什么:
CONNECT BY PRIOR empno = …Run Code Online (Sandbox Code Playgroud) PostgreSQL在Oracle中是否有像"LEVEL"这样的伪列?
如果没有,那么我们如何创建一个类似于"LEVEL"的列?
oracle postgresql connect-by recursive-cte hierarchical-query
我刚刚在这里讨论了这篇有趣的文章,展示了如何使用分层查询和窗口函数进行模拟wm_concat()或group_concat()在Oracle中:
SELECT deptno,
LTRIM(MAX(SYS_CONNECT_BY_PATH(ename,','))
KEEP (DENSE_RANK LAST ORDER BY curr),',') AS employees
FROM (SELECT deptno,
ename,
ROW_NUMBER() OVER (PARTITION BY deptno ORDER BY ename) AS curr,
ROW_NUMBER() OVER (PARTITION BY deptno ORDER BY ename) -1 AS prev
FROM emp)
GROUP BY deptno
CONNECT BY prev = PRIOR curr AND deptno = PRIOR deptno
START WITH curr = 1;
Run Code Online (Sandbox Code Playgroud)
虽然,我发现这不是一个非常易读的解决方案,但它非常有趣,特别是因为该CONNECT BY .. STARTS WITH条款在该GROUP BY条款之后.根据规范,这是不可能的.我尝试使用一个简单的查询,但它确实有效!以下两个查询返回相同的结果: …
我有一个包含数据的表,可以在这个伪有向图中表示:
我说这是一个伪图,因为我有一些«edge»,只连接在一个节点上.
每个«edge»都被标记,并将被视为一个事件.
每个节点只包含一个ID.
Oracle(12c)表如下所示:http: //sqlfiddle.com/#!4/79cdb5/4/0
在表上我运行了这个查询 ,我期望在其伪列CONNECT_BY_ISLEAF中有1的行之一而不是0.
这是有罪的行:http: //sqlfiddle.com/#!4/79cdb5/3/2
我完全无法理解为什么oracle不认为这行显然是一个叶子.
在表格中,我使用的每一行代表一个事件(或图形边缘)以及它所连接的节点.
VUID列是"上一个"节点,AUID是"步骤",EVENT是事件标签,NEW_VUID是"下一个"节点.
事件D和U的例外情况是只有1个节点连接到它,并且该节点将始终位于VUID列中(即使对于D事件,节点是"下一个"节点).
在这里,我将给出一些关于我正在做的请求的背景信息
我的最终目标是根据表格中的数据重新创建此图表.为此我继续前进:
要使用oracle创建树,我认为最简单的方法是进行正确的分层查询,然后使用伪列SYS_CONNECT_BY_PATH并对CONNECT_BY_ISLEAF = 1进行过滤,这是因为只使用叶子加上每个叶子都有的路径很容易重新创建树.
但是我被困了,因为由于某些原因我不明白Oracle不会像我一样考虑所有的方式.包含节点88888的叶子没有考虑
在 Oracle 分层查询中,WHERE-CLAUSE 应该在 oracle 文档中的 Connect-By 运算符之后进行评估。
但是有一些复杂的情况:如果 WHERE-CLAUSE 包含 JOIN-style 限定,正如 oracle 所说,Join-Style 限定应该在 Connect-By 运算符之前进行评估,而另一个仅引用一个关系的 none-Join-Style 将是在 Connect-By 运算符之后进行评估。
那么问题来了:如何将WHERE-CLAUSE中的限定符分为两部分,一是在Connect-By算子之前求值,另一个是在Connect-By算子之后求值。
example:
SQL> desc bar
Name Null? Type
----------------------------------------- -------- -----------------
B1 NUMBER(38)
B2 NUMBER(38)
SQL> desc foo;
Name Null? Type
----------------------------------------- -------- -----------------
F1 NUMBER(38)
F2 NUMBER(38)
SQL> set pagesize 3000
SQL> set linesize 3000
SQL> explain plan for select * from foo, bar where
2 **f1=b1 and (b2 = 1 or f1=b2 and b1=1 or f2=b1+1) …Run Code Online (Sandbox Code Playgroud) 我开始使用 sql 并面临分层查询。同时我成功地使用connect by prior命令选择行但未能更新。这是我的更新查询:
update HTABLE set status = 'INACTIVE'
WHERE STATUS <> 'CLOSE'
Connect by prior PARENT_ID=ID start with PARENT_ID=12345;
Run Code Online (Sandbox Code Playgroud)
我得到SQL Error: ORA-00933: SQL command not properly ended并将很高兴知道如何使用分层更新表..
谢谢!
编辑
我也试图把where条件放在start with, not help 中:
update HTABLE set status = 'INACTIVE'
Connect by prior PARENT_ID=ID start with PARENT_ID=12345 AND STATUS <> 'CLOSE';
Run Code Online (Sandbox Code Playgroud) 我正在尝试并在Oracle 11g数据库中的一个层次查询中搜索从节点获取所有最后一级子项( leafs)的方法.
我有2个表:"节点"(所有节点的列表及其各自的值),以及指定父子关系的"关系":
ID_NODE - VALUE
1 3
2 6
3 9
4 2
5 4
6 5
7 2
8 7
9 8
10 1
Run Code Online (Sandbox Code Playgroud)
ID_FATHER - ID_CHILD
1 2
1 3
1 4
2 5
2 6
4 7
5 8
5 9
7 10
Run Code Online (Sandbox Code Playgroud)
我已经阅读了CONNECT_BY_ISLEAF,如果它是一个叶子,它返回1,但我不能像Oracle示例一样查询CONNECT_BY_ISLEAF,我也没有得到任何结果.即使我不确切知道如何使用此函数精确地进行查询(例如使用案例条件?)
太谢谢了!
有没有办法在SQL中发送递归查询?
给定结束节点id,我需要所有行到根节点(有parentid = NULL)按级别排序.例如,如果我有类似的东西:
nodeid | parentid
a | NULL
b | a
c | b
Run Code Online (Sandbox Code Playgroud)
在查询之后end_node_id = c,我会得到类似的东西:
nodeid | parentid | depth
a | NULL | 0
b | a | 1
c | b | 2
Run Code Online (Sandbox Code Playgroud)
(而不是深度,我也可以使用到给定端节点的距离)
我能想到的唯一(也是显而易见的)方法是每行执行一次查询,直到到达父节点.
有没有更有效的方法呢?
sql tree recursive-query hierarchical-data hierarchical-query
我想知道是否存在与Oracle的分层语法等效的通用SQL start with...connect by.我需要一些可以在任何数据库上使用的东西.这是我的意思(使用Oracle的示例EMP表):
SELECT empno , ename , job , mgr ,hiredate ,level
FROM emp
START WITH mgr IS NULL
CONNECT BY PRIOR empno = mgr.
Run Code Online (Sandbox Code Playgroud)
递归公用表表达式适用于许多数据库实现,但不适用于MySQL.
我有一个查询来查看父子层次数据列表。在运行下面的查询时,我得到了错误ORA-01436。
SELECT ParentPropertyRSN, CONNECT_BY_ROOT PropertyRSN as PropertyRSN,
LEVEL, SYS_CONNECT_BY_PATH(ParentPropertyRSN, '/') Path
FROM Property
CONNECT BY PRIOR PropertyRSN = ParentPropertyRSN
order by level desc;
Run Code Online (Sandbox Code Playgroud)
所以我NOCYCLE在CONNECT BY子句中添加并获得了完整的数据列表及其分层路径
现在我需要的是一个查询来获取包含不准确数据的行列表ORA-01436。
sql oracle recursive-query hierarchical-data hierarchical-query