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_AREAMY_MONTH01ROWNUMORDER BYORDER 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階層を構築する方法を決定する。これは、階層内の前のレベルを参照するようにDBに指示するWHERE特別なキーワードを除いて、句のように機能します。PRIORそれで:

  • PRIOR MY_AREA = MY_AREA子ノードが`MY_AREA'に対して同じ値を持っている必要があることを意味します
  • PRIOR ORDERING = ORDERING - 1子は、の順序で現在のノードの1行後に来る必要があることを意味します。b
  • PRIOR MY_MONTH <= ADD_MONTHS(MY_MONTH, 6)つまり、階層に参加するにMY_MONTHは、現在のノードの日付から6か月以内である必要があります。

次に、階層全体が作成されます。LEVEL(特別なCONNECT BY...)は階層内のレベルに設定され、その階層のルートの値をCONNECT_BY_ROOT与え、それをにエイリアスします。この後、テーブルは次のテーブルのようになります。わかりやすくするために、階層ごとに区切り文字を追加しました。MY_MONTHMY_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つのレベルが残ります。これは、中間階層の1つの行(LEVEL= 4の行)にのみ影響します。

于 2012-05-30T18:13:20.043 に答える