MySQL每週進步一點點——group by去重,與自聯結梳理

好久沒發表sql學習總結了,今天總結本週新總結的兩點:group by去重理解,和自聯結的理解。

1、group by去重

從一個例題開始:

已知表格:Product(maker, type, model)

Get the makers who produce only one product type and more than one model. Output: maker, type.

即找出:1個type,>1個model的maker,輸出: maker, type

答案:

select distinct maker, type

from Product

where maker in

(select maker from Product

group by maker

having count(distinct type)=1 and count(distinct model)>1);

分析:

① SQL中distinct和group by去重區別:

distinct必須放在開頭,將所有查詢的字段進行對比,所有字段都完全相同才會去重;

group by 根據字段進行去重,字段相同就會去重。

② 當group by 字段1,字段2,(注意整個表中不止這兩個字段),表示數據集中,字段1相等,字段2也相等的數據歸為一組,只顯示一條數據。那麼你可以對字段3進行統計(求和,求平均值等);

對應的,group by 單個字段:這個字段相等的數據將歸為一組,只顯示一條記錄。

③ 理解:group by maker後,type和model都是多個值形成一格,每個不同的maker形成一列,然後用having來進行聚合和篩選。

④ group by 哪個字段,可以select這個字段,不會報錯!理解:group by 字段1,查詢結果中,字段1會形成單獨一列,具有列名!所以,可以被select提取出來。

舉例理解:

對於某原表表1,表名為test,想要執行:

select name from test

group by name

MySQL每週進步一點點——group by去重,與自聯結梳理

這裡是原表test--表一

可是為了能夠更好的理解“group by”,建議在思考的過程中,增加一個虛構的中間表:虛擬表3。

MySQL每週進步一點點——group by去重,與自聯結梳理

由表一到表三,自己過渡下

1)如果執行select * 的話,那麼返回的結果應該是虛擬表3,可是id和number中有的單元格里面的內容是多個值的,而關係數據庫就是基於關係的,單元格中是不允許有多個值的,所以你看,執行select * 語句就報錯了。

2)再看name列,每個單元格只有一個數據,所以我們select name的話,就沒有問題了。

3)那麼對於id和number裡面的單元格有多個數據的情況怎麼辦呢?答案就是用聚合函數,聚合函數就用來輸入多個數據,輸出一個數據的。如cout(id),sum(number),而每個聚合函數的輸入就是每一個多數據的單元格。

4)例如我們執行select name,sum(number) from test group by name,那麼sum就對虛擬表3的number列的每個單元格進行sum操作,例如對name為aa的那一行的number列執行sum操作,即2+3,返回5,最後執行結果如下:

MySQL每週進步一點點——group by去重,與自聯結梳理

5)group by 多個字段該怎麼理解呢:如group by name, number

---我們可以把name和number看成一個整體字段,以他們整體來進行分組的。

MySQL每週進步一點點——group by去重,與自聯結梳理

如執行

select name,sum(id)

from test

group by name,number

接下來就可以配合select和聚合函數進行操作了,結果如下圖:

MySQL每週進步一點點——group by去重,與自聯結梳理

2、自聯結

不用想什麼自聯結,自己心裡就是兩張普通表,就這麼簡單;

自聯結僅僅是個名詞,數據庫能支持,在語法上沒任何區別

舉例:原表s,左聯結自己(命名為p),採用不同方式聯結後,得到的聯結表如下,注意,s是主表,p作為副表,只是用於與s匹配;故一對多或者多對一的情況下,p中的每一條,都要與主表s中每一行檢索、儘量與主表中每一條匹配。

MySQL每週進步一點點——group by去重,與自聯結梳理

這裡是原表--表s,也是表p

MySQL每週進步一點點——group by去重,與自聯結梳理

MySQL每週進步一點點——group by去重,與自聯結梳理

舉例說明:

select s.id, s.cate_name, p.cate_name

from tdb_cates s left join tdb_cates p

on s.parent_id=p.id;

select之後,呈現輸出的結果:

MySQL每週進步一點點——group by去重,與自聯結梳理

輸出的結果

好了,祝大家SQL學習愉快!


分享到:


相關文章: