我怎么记住PRIOR应该在CONNECT BY查询中走哪条路

时间:2008-11-06 15:24:03

标签: sql oracle

我的记忆很糟糕。每当我在Oracle中执行CONNECT BY查询时 - 我的意思是每个时间 - 我必须努力思考,并且通常通过试错来解决PRIOR应该去哪个参数。

我不知道为什么我不记得了 - 但我不知道。

有没有人有一个方便的记忆助记符,所以我永远记得?

例如:

从一个节点向下一棵树 - 很明显我不得不这样看:) - 你做的事情如下:

select
    *
from
    node
connect by
    prior node_id = parent_node_id
start with
    node_id = 1

所以 - 我从一个node_id开始(分支的顶部),查询查找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_idnode_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。

3 个答案:

答案 0 :(得分:5)

我总是尝试按以下顺序将表达式放在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)上使用索引扫描,然后在(d.id)上使用索引扫描,而后者将首先在(d.id)上使用索引扫描,然后在{{(t.dimension)上使用索引扫描。 1}},您可以在查询中轻松查看它:搜索的字段位于左侧。

驱动表和驱动表在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视为常量,搜索所有行。

答案 1 :(得分:1)

考虑将要选择记录的顺序:每条记录上的链接回列必须与所选PRIOR记录上的链接转发列匹配。

答案 2 :(得分:0)

每次都很难看到它的部分原因是因为有时数据建模为id + child_id,有时数据建模为id + {{ 1}}。根据数据建模的方式,您必须将parent_id关键字放在另一侧。

我发现的诀窍始终是通过您要构建的树的叶子节点的眼睛看世界。

因此,当我查找时(称为叶节点),我看到了我的父节点,我也可以将其称为PRIOR节点。 go,我的PRIOR与他的ID相同。因此,在这种情况下,CHILD_ID

以另一种方式对数据建模时(即当我持有父母的ID而不是他的父母持有我的ID时),我的PRIOR child_id = id与他的parent_id的值相同。在这种情况下id,请按此操作。