我的记忆很糟糕.每当我在Oracle中执行CONNECT BY查询时 - 我的意思是每一次 - 我都要努力思考,通常通过试错来解决PRIOR应该去哪个参数.
我不知道为什么我不记得 - 但我没有.
有没有人有一个方便的记忆助记符,所以我永远记得?
例如:
走下来,从一个节点的树-很明显,我不得不看这件事:) -你做这样的事情:
select * from node connect by prior node_id = parent_node_id start with node_id = 1
所以 - 我从node_id
1 开始(分支的顶部),查询查找parent_node_id
= 1的所有节点,然后迭代到树的底部.
要向上移动树,先前对父进行:
select * from node connect by node_id = prior parent_node_id start with node_id = 10
因此,从某个分支开始(node_id = 10
在本例中)Oracle首先获取所有节点,其中所有节点parent_node_id
与node_id
10的节点相同.
编辑:我仍然错了,所以我想添加一个澄清的编辑来扩展已接受的答案 - 这是我现在记得的方式:
select * from node connect by prior node_id = parent_node_id start with node_id = 1
这个SQL的'英语'版本我现在读作......
在NODE中,从其中的行开始,
node_id = 1
所选的下一行与前一行(前一行)parent_node_id
相等node_id
.
编辑:Quassnoi提出了一个很好的观点 - 您编写SQL的顺序使事情变得更加容易.
select * from node start with node_id = 1 connect by parent_node_id = prior node_id
这让我感觉更清楚 - "start with"给出第一行选择,"connect by"给出下一行 - 在这种情况下node_id = 1的子节点.
我总是尝试JOIN
按以下顺序放置表达式:
joined.column = leading.column
这个查询:
SELECT t.value, d.name FROM transactions t JOIN dimensions d ON d.id = t.dimension
可以被视为"对于每个事务,找到相应的维度名称"或"对于每个维度,找到所有相应的事务值".
因此,如果我搜索给定的事务,我按以下顺序放置表达式:
SELECT t.value, d.name FROM transactions t JOIN dimensions d ON d.id = t.dimension WHERE t.id = :myid
,如果我搜索维度,那么:
SELECT t.value, d.name FROM dimensions d JOIN transactions t ON t.dimension = d.id WHERE d.id = :otherid
以前的查询很可能首先使用索引扫描(t.id)
,然后使用on(d.id
),而后者将首先使用索引扫描(d.id)
,然后再使用(t.dimension)
,您可以在查询本身中轻松查看:搜索的字段位于左侧.
驱动表和驱动表在a中可能不那么明显JOIN
,但它与CONNECT BY
查询的铃声一样清晰:PRIOR
行正在驱动,非行驶PRIOR
.
这就是为什么这个查询:
SELECT * FROM hierarchy START WITH id = :root CONNECT BY parent = PRIOR id
表示"查找parent
给定的所有行id
".此查询构建层次结构.
这可以这样对待:
connect_by(row) { add_to_rowset(row); /* parent = PRIOR id */ /* PRIOR id is an rvalue */ index_on_parent.searchKey = row->id; foreach child_row in index_on_parent.search { connect_by(child_row); } }
而这个查询:
SELECT * FROM hierarchy START WITH id = :leaf CONNECT BY id = PRIOR parent
表示"找到id
给定的行parent
".此查询构建了一个祖先链.
始终放在PRIOR
表达式的正确部分.
可以想象PRIOR column
所有行都将被搜索到的常数.