WITH CTE公用表達式查詢
- https://www.postgresql.org/docs/10/queries-with.html
- https://www.postgresql.org/docs/10/sql-select.html
WITH提供了一種編寫輔助語句以便在更大的查詢中使用的方法。這些語句(通常稱爲公用表表達式或CTE)可以被視爲定義僅針對一個查詢存在的臨時表。一個在每個輔助語句WITH子句可以是SELECT,INSERT,UPDATE,或DELETE; 和WITH本身所在的主語句也可以是SELECT,INSERT,UPDATE,或DELETE
- WITH子句可以將在SQL中多次出現的SQL語句提取出來,簡化SQL編寫
- WITH子句無論使用多少次,都只會計算一次
- 優點:性能比計算多次更好
- 缺點:如果主句中有其他限制條件可以大幅加快表查找數據,使用WITH子句,在子句將無法使用該限制
WITH invoice_by_type AS ( SELECT cl_invoice_type, COUNT ( 1 ) COUNT FROM inv_t_invoice GROUP BY cl_invoice_type ),
invoice_max_type AS ( SELECT cl_invoice_type FROM invoice_by_type ORDER BY COUNT DESC LIMIT 2 )
SELECT
i.cl_id,i.cl_invoice_type,T.count
FROM
inv_t_invoice i
LEFT JOIN invoice_by_type T ON i.cl_invoice_type = T.cl_invoice_type
WHERE
i.cl_invoice_type IN (
SELECT
cl_invoice_type
FROM
invoice_max_type)
- 有兩個With子句invoice_by_type和invoice_max_type ,其中invoice_max_type用到了子句invoice_by_type
RECURSIVE
遞歸語法
非遞歸語句 UNION [ ALL | DISTINCT ] 遞歸語句
- 遞歸自引用必須出現在右側UNION
- 每個查詢只允許一次遞歸自引用
- 不支持遞歸數據修改語句
例如
WITH RECURSIVE t(n) AS (
VALUES (1)
UNION ALL
SELECT n+1 FROM t WHERE n < 100
)
SELECT sum(n) FROM t;
遞歸計算執行過程
- 計算非遞歸語句,如果是UNION則先去重,將數據放入最終結果表和臨時表中
- 執行遞歸語句訪問臨時表進行查詢,如果是UNION則和最終結果表去重,將數據追加到最終結果表,覆蓋臨時表
- 如果臨時表爲空,則中斷遞歸,否則返回第2步
需要注意防止遞歸出現無限循環,可以在主語句加入limit防止死循環
刪除並轉移數據
刪除products數據並移到products_log
WITH moved_rows AS(
DELETE FROM products
WHERE
“date”> ='2010-10-01'and
“date”<'2010-11-01'RETURNING
*
)
INSERT INTO products_log
SELECT * FROM moved_rows;
同時刪除兩張表數據,返回的影響行數是bar錶行數
WITH t AS(
DELETE FROM foo
)
DELETE FROM bar;
強制主句在WITH子句後執行
如果主句沒有使用WITH子句,主句和子句的執行順序無法確定
WITH t AS (
UPDATE products SET price = price * 1.05
RETURNING *
)
SELECT * FROM products;
可通過RETURNING *強制在主句中使用WITH子句,實現先執行用WITH子句,再執行主句
WITH t AS (
UPDATE products SET price = price * 1.05
RETURNING *
)
SELECT * FROM t;
CLUSTER聚類表
https://www.postgresql.org/docs/10/sql-cluster.html
將當前錶轉爲索引聚類表,索引聚類表將數據和索引存儲在一起,可以加快通過索引訪問數據的速度
使用指定索引聚類表
CLUSTER [VERBOSE] table_name [ USING index_name ]
聚類所有表
CLUSTER [VERBOSE]
索引聚類表不能在事物中執行
- 如果有新增行,新行不會按索引排序
- 如果原連續存儲空間不足,更新行可能也不會按索引排序
可以通過命令重建索引聚類表,保障所有行按索引順序
Window Functions
https://www.postgresql.org/docs/10/tutorial-window.html
取得員工部門,員工編號,本部門平均工資
SELECT depname, empno, salary, avg(salary) OVER (PARTITION BY depname) FROM empsalary;
#Result
depname | empno | salary | avg
-----------+-------+--------+-----------------------
develop | 11 | 5200 | 5020.0000000000000000
develop | 7 | 4200 | 5020.0000000000000000
develop | 9 | 4500 | 5020.0000000000000000
develop | 8 | 6000 | 5020.0000000000000000
develop | 10 | 5200 | 5020.0000000000000000
personnel | 5 | 3500 | 3700.0000000000000000
personnel | 2 | 3900 | 3700.0000000000000000
sales | 3 | 4800 | 4866.6666666666666667
sales | 1 | 5000 | 4866.6666666666666667
sales | 4 | 4800 | 4866.6666666666666667
(10 rows)
取得員工部門,員工編號,薪資,部門內薪資排名
SELECT depname, empno, salary,
rank() OVER (PARTITION BY depname ORDER BY salary DESC)
FROM empsalary;
並行查詢
並行查詢允許一個SQL同時使用多個CPU加快查詢速度,主要用於OLAP場景