sql >> データベース >  >> RDS >> PostgreSQL

sql with-recursiveステートメントはどのように解釈されますか?

    ここでは「再帰」は発生しておらず、混乱するところだと思います。

    PostgreSQLのドキュメントから:http://www.postgresql.org/docs/9.4/static/queries-with.html

    Note: Strictly speaking, this process is iteration not recursion, 
    but RECURSIVE is the terminology chosen by the SQL standards committee.
    

    この文を言い換えると、WITH RECURSIVE 単純なWHILEと見なすことができます ループ。

    WITH RECURSIVE t(n) AS (
      VALUES (1)
      UNION ALL
      SELECT n+1 FROM t WHERE n < 100
    )
    SELECT * FROM t;
    

    このプロセスを詳細に説明するためのカスタムメイドの擬似コードを次に示します

    # Step 1: initialisation
    LET cte_result = EMPTY
    LET working_table = VALUES (1)
    LET intermediate_table = EMPTY
    
    # Step 2: result initialisation, merge initialisation into cte_result
    cte_result = cte_result UNION working_table
    
    # Step 3: iteration test
    WHILE (working_table is not empty) DO
        # Step 4: iteration select, we substitute the self-reference with working_table
        intermediate_table = SELECT n+1 FROM working_table WHERE n < 100
    
        # Step 5: iteration merge, merge the iteration result into cte_result
        cte_result = cte_result UNION intermediate_table
    
        # Step 6: iteration end, prepare for next iteration
        working_table = intermediate_table
        intermediate_table = EMPTY
    END WHILE
    
    # Step 7: return
    RETURN cte_result
    

    そして例を使って

    # Step 1: initialisation
    cte_result: EMPTY    | working_table: 1        | intermediate_table: EMPTY
    
    # Step 2: result initialisation
    cte_result: 1        | working_table: 1        | intermediate_table: EMPTY
    
    # Step 3: iteration test
    count(working_table) = 1 # OK
    # Step 4: iteration select
    cte_result: 1             | working_table: 1        | intermediate_table: 2
    # Step 5: iteration merge
    cte_result: 1, 2          | working_table: 1        | intermediate_table: 2
    # Step 6: iteration end
    cte_result: 1, 2          | working_table: 2        | intermediate_table: EMPTY
    
    # Step 3: iteration test
    count(working_table) = 1 # OK
    # Step 4: iteration select
    cte_result: 1, 2         | working_table: 2        | intermediate_table: 3
    # Step 5: iteration merge
    cte_result: 1, 2, 3      | working_table: 2        | intermediate_table: 3
    # Step 6: iteration end
    cte_result: 1, 2, 3      | working_table: 3        | intermediate_table: EMPTY
    
    # … 97 more iterations and you get this state
    cte_result: 1, 2, …, 100  | working_table: 100       | intermediate_table: EMPTY
    
    # Step 3: iteration test
    count(working_table) = 1 # OK
    # Step 4: iteration select, the iteration query does not return any rows due to the WHERE clause
    cte_result: 1, 2, …, 100  | working_table: 100       | intermediate_table: EMPTY
    # Step 5: iteration merge, nothing is merged into the cte_result
    cte_result: 1, 2, …, 100  | working_table: 100       | intermediate_table: EMPTY
    # Step 6: iteration end
    cte_result: 1, 2, …, 100  | working_table: EMPTY | intermediate_table: EMPTY
    
    # Step 3: iteration test
    count(working_table) = 0 # STOP
    
    # Step 7: return
    cte_result: 1, 2, …, 100
    

    したがって、CTEの結果は1から100までのすべての数値になります。




    1. ssisフラットファイルソースの不正な行をスキップする方法

    2. SQL Azure:サーバー上のデータベースXXXYYYは現在利用できません

    3. MySQLを使用した基本的なSQLクエリについて学ぶ

    4. 意見を求める:すべてのテーブルに対して1つのシーケンス