目前支援cte的資料庫有teradata, db2, firebird, microsoft sql server, oracle (with recursion since 11g release 2), postgresql (since 8.4), mariadb (since 10.2), sqlite (since 3.8.3), hypersql and h2 (experimental), mysql8.0.
cte的文法如下:
non-recursive ctes
recursive ctes
cte使語句更加簡潔
例如以下兩個語句表達的是同一語義,使用cte比未使用cte的嵌套查詢更簡潔明了。
1) 使用嵌套子查詢
2) 使用cte
cte 可以進行樹形查詢
初始化這顆樹
1) 層序周遊
2) 深度優先周遊
oracle recursive with 語句不需要指定recursive關鍵字,可以自動識别是否recursive.
oracle 還支援cte相關的hint,
“materialize”告訴優化器産生一個全局的臨時表儲存結果,多次引用cte時直接通路臨時表即可。而”inline”則表示每次需要解析查詢cte。
postgresql從8.4開始支援cte,postgresql還擴充了cte的功能, cte的query中支援dml語句,例如
mariadb從10.2開始支援cte。10.2.1 支援non-recursive cte, 10.2.2開始支援recursive cte。 目前的ga的版本是10.1.
mysql從8.0開始支援完整的cte。mysql8.0還在development
階段,rc都沒有,ga還需時日。
alisql基于mariadb10.2, port了no-recursive cte的實作,此功能近期會上線。
以下從源碼主要相關函數簡要介紹其實作,
//解析識别with table引用
find_table_def_in_with_clauses
//檢查依賴關系,比如不能重複定義with table名字
with_clause::check_dependencies
// 為每個引用clone一份定義
with_element::clone_parsed_spec
//替換with table指定的列名
with_element::rename_columns_of_derived_unit
此實作對于多次引用cte,cte會解析多次,是以此版本cte有簡化sql的作用,但效率上沒有效提高。
以下是mysql8.0 隻掃描一次的執行計劃
以下是postgresql9.4 隻掃描一次的執行計劃
alisql還有待改進。