PostgreSQL使用with一例

常常在SQL中會遇到比較複雜的SQL,不少老手也不知道怎麼入手。在Postgres數據庫中有一種強大的with用法,能夠分拆複雜的SQL並從新組裝,也能夠當作臨時表來使用,以前也曾用with語法來實現SQL層面的遞歸。如下介紹開發中遇到的另外一個例子。

環境: Postgres 9.1.2
評論表T1(user_id reference T2(user_id))
用戶表T2(user_id)

場景:
須要對T1表中數據按評論數分組排序,選擇前5條記錄與表T2進行關聯,返回知足條件的T2用戶數據,但要根據T1的排序結果來展現,也就是要顯示評論最多的5個用戶的詳細信息,並按評論數把用戶從高到低排列。

開發的SQL:
1.查看錶T1,並排序
select user_id,count(1) from t1 group by user_id order by  count(1) desc limit 5;
 

2.與表T2關聯
select * from t2 where user_id in(
select user_id from t1 group by user_id order by  count(1) desc limit 5);
可是展現的T2結果雖然取出來了,但並無排序,沒有達到效果


解決辦法:
1.使用兩個表的join來實現
select t2.user_id,t2.user_name,count(1) as num from t1,t2 
where t1.user_id = t2.user_id 
group by t2.user_id,t2.user_name
order by num desc limit 5; 
2.用with來構造:
with tmp as(
select user_id,count(1) as num from t1 group by user_id order by  num desc limit 5
)
select t2.*,tmp.num from t2 inner join tmp
on t2.user_id = tmp.user_id order by tmp.num desc 

分析:
第一種辦法須要兩張表關聯再分組取前5條,執行計劃以下:


若是數據量比較大,尤爲是T2表很大的時候,會消耗比較多的資源,另外若是想取用戶表裏有其餘的字段,也須要進行分組
第二種辦法是採用with來構造臨時表,而後再去與T2表關聯取數,執行計劃以下:


能夠看到消耗的資源相對少一點,測試中發現T二、T1表很大的時候,這種差距尤爲明顯。 數據庫

相關文章
相關標籤/搜索