PostgreSQL:with recursive使用


先從 with 關鍵字開始,with 提供了一種編寫子查詢的方法,這種子查詢用於 select 查詢語句中。可以將這些子查詢(通常被稱為 Common Table Expressions 簡稱 CTE )視為定義了僅用於此查詢的臨時表。with 的一種用途是將復雜的查詢分解成簡單的查詢語句。例如下面的示例

WITH regional_sales AS (
    SELECT region, SUM(amount) AS total_sales
    FROM orders
    GROUP BY region
  ), top_regions AS (
    SELECT region
    FROM regional_sales
    WHERE total_sales > (SELECT SUM(total_sales)/10 FROM regional_sales)
)
SELECT region,
    product,
    SUM(quantity) AS product_units,
    SUM(amount) AS product_sales
FROM orders
WHERE region IN (SELECT region FROM top_regions)
GROUP BY region, product;

重點是上面的臨時表,基於 orders 表建了兩個臨時表,整個查詢語句都用到了這兩個臨時表。這點和視圖有點類似。with 后面接的就是臨時表的名字,可以在后面的 select 語句中用的到。

 with 加入 recursive 關鍵字后可以實現普通復雜查詢。示例如下:

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

執行上面的 sql 會發生什么步驟呢?

# 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

上面查詢過程中會建立三張表,三張表不斷並集,累加,循環,獲取最終結果。

簡而言之, 以 working_table 為基礎表,執行 select 查詢語句,將結果賦給 intermediate_table,然后將 intermediate_table 賦給 working_table;以 working_table 為基礎表,執行 select 查詢語句,如此循環往復,直到 working_table 為 empty,循環停止。在上述循環過程中,每次 intermediate_table 被重新賦值時,就將 intermediate_table 值累加到 cte_result 中,最終的結果集就是 cte_result

 

參考:

https://www.postgresql.org/docs/8.4/queries-with.html

https://stackoverflow.com/questions/30015842/how-sql-with-recursive-statement-interpreted


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM