以問題推動學習之——Postgresql(1)
以問題推動學習之——Postgresql(1)
1、 理解group by與聚合函式
需求
將資料合成一組,根據每一組的最大數取出這一行的其它欄位。
新增連結描述
如上圖所示,我需要根據時間大小,取每一組(藍色圈)最大時間這一行中的資料,即紅色的兩行中的某些資料。
解決
首先需要使用group by將圖中藍色圈中的欄位聚合,然後使用max(時間欄位)判斷選出最大時間的那一行,最後根據時間將表中的其它資料取出來。
根據描述程式碼如下(以下程式碼瞭解大約意思就行了)
select 表的第二列, 表的第三列, 表的第四列 from (select max(第五列) as time, 第二列 from 表名 group by 第二列) as 新生成表的別名tb1 INNER JOIN 表名 ON tb1的第二列 = 表的第二列 and 表的第五列 = tb1.time;
深入理解
最開始時,我希望直接使用group by將需要資料的行找到就好了,確實很容易找到,但是select資料時,只能選擇group by的資料或者使用聚合函式如max等取值,這對於需要取一些無規律的值時造成很大的麻煩。因此你需要對選擇好的表再進行選擇,因此使用了inner join … on … (內聯)。
我們一步一步來理解我們怎麼才能實現需求。
-
使用group by
select 第二列 from 表 group by 第二列;
哈哈當然只有上表的第一列出現哈,沒有後面兩列。 -
使用聚合函式max
首先我們必須要說說為什麼需要聚合函式。
如上表所示,當我們使用了group by後生成了一個虛擬表(就是上表),如果你僅僅想要取後面兩列的某行,那麼資料庫不知道你需要哪個行,因此你需要呼叫函式從這一列中選出一個出來。因為我們的需求是時間最大,那麼正好使用max聚合函式選出第三列的最大數。
同時我們應該明白資料庫輸出是一行對應一個欄位,不會一對多(除非陣列),因此不可能輸出上表的樣子。
select 第二列,max(第五列) from 表 group by 第二列;
-
再次使用select
當我們找到我們需要的那一行的唯一條件後(第二列與時間列),我們可以根據這些條件再次從表中選擇符合條件的行。
select 表的第二列, 表的第三列, 表的第四列 from (select max(第五列) as time, 第二列 from 表名 group by 第二列) as 新生成表的別名tb1 INNER JOIN 表名 ON tb1的第二列 = 表的第二列 and 表的第五列 = tb1.time; -
理解級聯表
inner join:理解為“有效連線”,兩張表中都有的資料才會顯示
left join:理解為“有左顯示”,比如on a.field=b.field,則顯示a表中存在的全部資料及a\b中都有的資料,A中有、B沒有的資料以null顯示
right join:理解為“有右顯示”,比如on a.field=b.field,則顯示B表中存在的全部資料及a\b中都有的資料,B中有、A沒有的資料以null顯示
full join:理解為“全連線”,兩張表中所有資料都顯示,實際就是inner+(left-inner)+(right-inner)