1

我已经阅读了有关操作的Oracle 文档CONNECT,但我似乎无法理解现有应用程序中的数据库查询。以下是查询的简化版本。

SELECT LEVEL,
       CONNECT_BY_ROOT MY_MONTH MY_LABEL,
       b.*
FROM (
    SELECT ROWNUM AS ORDERING, 
           MY_AREA,
           TRUNC (THE_MONTH, 'MONTH') AS MY_MONTH
    FROM MY_TABLE
    ORDER BY MY_AREA, MY_MONTH DESC
) b
WHERE LEVEL <= 3
START WITH 1 = 1
CONNECT BY PRIOR MY_AREA = MY_AREA
       AND PRIOR ORDERING = ORDERING - 1
       AND PRIOR MY_MONTH <= ADD_MONTHS(MY_MONTH, 6);

虽然我对CONNECT功能有基本的了解,但这种组合让我迷失了方向。谁能解释这个查询中发生了什么?

我认为最后说要获取所有具有相同区域且行号比当前行号小 1 的行以及从当前日期起 6 个月之前的日期。我猜这只会返回 1 行(由于行号标准)或如果不满足其他标准则返回 0 行。然后也许第一个CONNECT_BY_ROOT说要获得该行的MY_MONTH价值?

4

1 回答 1

3

以 开头b,它是一个包含MY_AREA(数字?)的表MY_MONTH, 是一个截断月份的日期(即天都设置为01),以及一个别名ROWNUM,它由ORDER BY子句确定,即ORDER BY MY_AREA, MY_MONTH DESC,例如:

+----------+---------+-----------+
| ORDERING | MY_AREA | MY_MONTH  |
+----------+---------+-----------+
| 1        | 10      | 01-SEP-12 |
| 2        | 10      | 01-JAN-12 |
| 3        | 12      | 01-AUG-12 |
| 4        | 12      | 01-JUN-12 |
| 5        | 12      | 01-MAY-12 |
| 6        | 12      | 01-JAN-12 |
| 7        | 12      | 01-JAN-10 |
+----------+---------+-----------+

WHERE子句直到稍后才会发挥作用,因此请继续使用START WITH,它仅表示1 = 1。这意味着b查询中将使用每一行;如果您在这里有其他条件,例如my_area < 5或其他情况,则只会使用特定的一组行。

现在,CONNECT BY,它决定了应该如何构建层次结构。这就像一个WHERE子句,除了PRIOR告诉数据库查看层次结构中的上一层的特殊关键字。所以:

  • PRIOR MY_AREA = MY_AREA只是意味着子节点必须具有相同的“MY_AREA”值
  • PRIOR ORDERING = ORDERING - 1表示子节点应该在的排序中的当前节点之后排一排。b
  • PRIOR MY_MONTH <= ADD_MONTHS(MY_MONTH, 6)意味着为了加入层次结构,前一个MY_MONTH应该在当前节点日期之后的 6 个月或更短的时间内。

然后创建整个层次结构。LEVEL(special for CONNECT BY...) 设置为层次结构中的级别,CONNECT_BY_ROOT给出该层次结构MY_MONTH的根的值并将其别名为MY_LABEL. 在此之后,该表将类似于下表。为了清楚起见,我为每个层次结构添加了分隔符。

+-------+-----------+----------+---------+-----------+
| LEVEL | MY_LABEL  | ORDERING | MY_AREA | MY_MONTH  |
+-------+-----------+----------+---------+-----------+
| 1     | 01-SEP-12 | 1        | 10      | 01-SEP-12 |
+-------+-----------+----------+---------+-----------+
| 1     | 01-JAN-12 | 2        | 10      | 01-JAN-12 |
+-------+-----------+----------+---------+-----------+
| 1     | 01-AUG-12 | 3        | 12      | 01-AUG-12 |
| 2     | 01-AUG-12 | 4        | 12      | 01-JUN-12 |
| 3     | 01-AUG-12 | 5        | 12      | 01-MAY-12 |
| 4     | 01-AUG-12 | 6        | 12      | 01-JAN-12 |
+-------+-----------+----------+---------+-----------+
| 1     | 01-JUN-12 | 4        | 12      | 01-JUN-12 |
| 2     | 01-JUN-12 | 5        | 12      | 01-MAY-12 |
| 3     | 01-JUN-12 | 6        | 12      | 01-JAN-12 |
+-------+-----------+----------+---------+-----------+
| 1     | 01-MAY-12 | 5        | 12      | 01-MAY-12 |
| 2     | 01-MAY-12 | 6        | 12      | 01-JAN-12 |
+-------+-----------+----------+---------+-----------+
| 1     | 01-JAN-12 | 6        | 12      | 01-JAN-12 |
+-------+-----------+----------+---------+-----------+
| 1     | 01-JAN-10 | 7        | 12      | 01-JAN-10 |
+-------+-----------+----------+---------+-----------+

因此,如您所见,每一行都出现在其自身层次结构的顶部,所有节点都满足其下的CONNECT BY条件。

最后,WHERE应用该子句;这会切断> 3每个层次结构中的所有级别,因此您最多只剩下 3 个级别。这仅影响中间层次结构中的一行,即LEVEL= 4 的行。

于 2012-05-30T18:13:20.043 回答