CONNECT_BY_ISCYCLE
のドキュメントから :
CONNECT_BY_ISCYCLE
pseudocolumnは1
を返します 現在の行にその祖先でもある子がある場合
CYCLE
のそれ :
祖先の行の1つがサイクル列に対して同じ値を持っている場合、その行はサイクルを形成していると見なされます。
あなたの例では、行2
祖先でもある子がありますが、そのid
まだ返送されていません。
つまり、CONNECT_BY_ISCYCLE
子供をチェックします (まだ返されていません)、CYCLE
現在の行をチェックします (これはすでに返されています)。
CONNECT BY
行ベースですが、再帰的なCTE
はセットベースです。
CYCLE
に関するOracleのドキュメントに注意してください。 「祖先の行」について言及しています。ただし、一般的に言えば、再帰的なCTE
には「祖先行」の概念はありません。 。これはセットベースの操作であり、ツリーから完全に結果を得ることができます。一般的に、アンカー部分と再帰部分は異なるテーブルを使用することもできます。
再帰的なCTE
以降 は通常 階層ツリーの構築に使用、Oracle
サイクルチェックを追加することにしました。ただし、セットベースの方法により、再帰的なCTE
の動作では、「祖先行」のサイクル条件も明確に定義できないため、次のステップでサイクルが生成されるかどうかを判断することは一般に不可能です。
「次の」ステップを実行するには、「現在の」セット全体が使用可能である必要がありますが、現在のセットの各行(サイクル列を含む)を生成するには、「次の」操作の結果が必要です。
現在のセットが常に単一の行で構成されている場合(CONNECT BY
のように)、問題はありません。 )が、セット全体で再帰演算が定義されている場合は問題になります。
Oracle 11
を調べていません まだですが、SQL Server
再帰的なCTE
を実装します CONNECT BY
を非表示にするだけです その背後には、多数の制限を設ける必要があります(これらはすべて、セットベースのすべての操作を効果的に禁止します)。
PostgreSQL
一方、の実装は真にセットベースです。再帰部分のアンカー部分を使用して任意の操作を実行できます。ただし、サイクルはそもそも定義されていないため、サイクルを検出する手段はありません。
前に述べたように、MySQL
CTE
を実装していません はまったくありません(HASH JOIN
は実装されていません またはMERGE JOIN
■同様に、ネストされたループのみなので、それほど驚かないでください。
皮肉なことに、私は今日、このテーマに関する手紙を受け取りました。これについてはブログで取り上げます。
更新:
再帰的なCTE
SQL Server
の CONNECT BY
にすぎません 変装した。衝撃的な詳細については、私のブログのこの記事を参照してください:
- SQL Server:再帰CTEは本当にセットベースですか?