SQL99 中取代子查詢表格的功能 - CTE (Common Table Expression)
隨著 IBM DB2 v8,v9; Oracle9i release 2; 以及 Microsoft SQL Server 2005 相關文件出現,我注意到它們都有提供一個由 SQL:1999 (簡稱 SQL-99 或 SQL3) 所規範的 CTE (Common Table Expression) 查詢語法。 CTE 查詢語法簡化了以往「子查詢表格」的複雜語法與難讀敘述。不妨試著解讀《一個較複雜的表格聯結 (join) 範例》一文的範例,想看出裡面有四個子查詢表格確實不是件容易的事。
簡潔易讀的語法
CTE 是以 WITH 為查詢關鍵字,在主查詢進行前先以 WITH 宣告暫時性表格的內容,緊接著進行主查詢。這點與傳統的子查詢表格被夾雜在主查詢中的語法相比,在語法上顯得更為簡潔易讀。
查詢效能的改善
從 CTE 的語義上看,理論上對查詢效能也有所助益。當主查詢中重覆使用同一個暫時性表格時, CTE 的語義將明確指示查詢引擎只需為暫時性表格進行一次 SELECT 動作。雖然就我個人的實務經驗來看,多數資料庫系統查詢引擎已經針對這種情形進行了最佳化處理,當查詢引擎發現查詢句中有重覆的子查詢時,它實際上只會對重覆的子查詢進行一次 SELECT 動作而已。所以對查詢效能的幫助可能不會很顯著。
Recursive query
我在 PostgreSQL 的 mailing-list 中,找到了一個 CTE 做得到而子查詢表格做不到的功能,即暫時性表格的遞迴查詢 (SQL-99 Recursive query) [SQL3 recursive unions,請留意並非支援 CTE 的資料庫系統就支援遞迴查詢]。 遞迴查詢是指 CTE 在宣告暫時性表格的敘述中,又參照了自己的情形。範例如下,請注意第 8 行, rpl 參照了自己。
上述範例的語法,我無法測試。 OpenSource Software 中支援 SQL 標準最好的 PostgreSQL ,一直到目前釋出的 PostgreSQL v8.2 beta 2 為止,仍未支援 CTE 。
Reference
- Recursion in DB2 V8, V8, V8…
- Oracle SQL-99 WITH clause
- SQL Server 2005 Recursive Functions
- SQL3 recursive unions