web-dev-qa-db-ja.com

CTEとSubQueryの違いは?

この投稿から 次の手順でROW_NUMBERを使用するには?

回答には2つのバージョンがあり、1つはSubQueryを使用し、もう1つはCTEを使用して同じ問題を解決します。

Sub-query(したがって、readable)よりもCTE (Common Table Expression)を使用する利点は何ですかクエリは実際に行っています)

サブセレクトに対してCTEを使用する唯一の利点は、サブクエリを実際にnameできることです。 CTEが単純な(非再帰的)CTEとして使用されている場合、これら2つの間に他の違いはありますか?

134
Sung M. Kim

サブクエリvs シンプル(非再帰)CTEバージョンでは、おそらく非常によく似ています。プロファイラーと実際の実行計画を使用して違いを見つける必要がありますが、これはセットアップに固有のものです(したがって、完全な答えをお伝えすることはできません)。

In 一般; CTEは再帰的に使用できます。サブクエリはできません。これにより、ツリー構造に特に適しています。

90
Marc Gravell

共通テーブル式再帰クエリ に使用しない場合)の主な利点は、使用するすべての場所でサブクエリを宣言する代わりにカプセル化することです一度定義することはできますが、複数の参照があります。

ただし、これはnotを1回だけ実行することを意味します( この非常に答えの以前の繰り返し 、ありがとうございますコメントしたすべての人)。クエリは、複数回参照されると複数回実行される可能性があります。クエリオプティマイザーは最終的に、CTEの解釈howについて決定します。

78
casperOne

CTEは再帰に最も役立ちます。

WITH hier(cnt) AS (
        SELECT  1
        UNION ALL
        SELECT  cnt + 1
        FROM    hier
        WHERE   cnt < @n
        )
SELECT  cnt
FROM    hier

@n行(101まで)を返します。カレンダー、ダミー行セットなどに役立ちます。

また、(私の意見では)読みやすくなっています。

これとは別に、CTEsubqueriesは同じです。

15
Quassnoi

言及されていない違いの1つは、単一のCTEがユニオンの複数の部分で参照できることです。

10
user340140

何かが足りない場合を除き、CTEとサブクエリに同じ名前を付けることができます。

主な違いは読みやすさだと思います(サブクエリを途中ではなく前もって定義しているため、CTEの方が読みやすいと思います)。

そして、再帰で何かをする必要がある場合、サブクエリでそれを行うのに少し苦労するでしょう;)

8
AlexCuse

誰も言及していない1つの重要な事実は、(少なくともpostgresでは)CTEは最適化フェンスであるということです:

https://blog.2ndquadrant.com/postgresql-ctes-are-optimization-fences/

つまり、それらはクエリプラン全体に組み込まれるのではなく、独自のアトミッククエリとして扱われます。より良い説明をする専門知識はありませんが、使用しているsqlのバージョンのセマンティクスを確認する必要があります。上級ユーザーの場合、最適化フェンスを作成できると、クエリプランナーを制御する専門家レベルのパフォーマンスが向上します。ただし、99%のケースでは、クエリプランナーに何をすべきかを指示しようとするのを避ける必要があります。 :-)

7
Ajax

他の回答に追加すると、同じサブクエリが何度も使用されている場合は、これらすべてのサブクエリを1つのCTEに置き換えることができます。これにより、コードをより再利用できます。

6
A-K

理解する必要があることの1つは、古いバージョンのSQL Server(多くの人がSQL Server 2000データベースをサポートする必要がある場合)では、CTEが許可されておらず、派生テーブルが最適なソリューションであるということです。

4
HLGEM

ヒント:(MAXRECURSION n)

MAXRECURSIONヒントとOPTION

たとえば、次を試すことができます。

OPTION 
      (MAXRECURSION 150)

GO
2
Basic_