sql去重

問題點:存在數據表test_table如下,想只對value字段篩選並去重,結果顯示去重後的value列和對應的id列(id顯示3或4都可以)

id value
1 a
2 b
3 c
4 c
5 e
5 f

可以看到表中的value字段有重複,如果想篩選去重,使用select distinct語句如下:

SELECT DISTINCT value FROM test_table;

得到結果會是
| value
| a
| b
| c
| e
| f

結論1

SELECT DISTINCT + 單字段,可實現對該字段去重


篩選去重是實現了,可是隻有選中的value列顯示了出來,如果我想知道對應的id呢?
嘗試一下把id字段加入sql語句,如下:

SELECT DISTINCT value, id FROM test_table;

得到結果:
| value | id
| a | 1
| b | 2
| c | 3
| c | 4
| e | 5
| f | 5
更換一下sql語句中id和value的順序,如下:

SELECT DISTINCT id, value FROM test_table;

得到結果:
| id |value
| 1 | a
| 2 | b
| 3 | c
| 4 | c
| 5 | e
| 5 | f
好像看明白它的作用結果了,只有id和value兩個字段同時重複時,select distinct語句纔會把它列入“去重”清單
所以能看到id爲3和4的value雖然都是4,但由於select語句中寫了id字段,它也默認會對id字段起效。

結論2

SELECT DISTINCT + 多字段,可實現對輸入字段合併去重(只有多字段完全相同纔會被“去重”的效果)


而且如果sql語句中把DISTINCT放到只想起效的字段前,那也是不行的....比如sql語句改爲:

SELECT id, DISTINCT value FROM test_table;

會提示sql報錯。

結論3

SELECT +字段 + DISTINCT + 字段,sql錯誤,DISTINCT必須放在開頭


那到底怎麼樣能得到我想要的只對value字段內容去重,顯示結果又能保留其他字段內容呢....
找到的解決方法是使用group by函數,sql語句如下:

SELECT min(id), value FROM test_table GROUP BY value

得到結果:
| min(id) |value
| 1 | a
| 2 | b
| 3 | c
| 5 | e
| 5 | f
完成目標了✔!
如果把sql語句中的min()換成max()呢?

SELECT max(id), value FROM test_table GROUP BY value

得到結果:
| min(id) |value
| 1 | a
| 2 | b
| 4 | c
| 5 | e
| 5 | f
也完成目標了✔!
同時比對兩次sql運行結果可以發現,
第一次使用min(id)時,由於重複結果存在兩條而id最小的爲爲3,符合min(id)的篩選條件,所以結果中把id等於4的重複記錄刪除了。
第二次使用max(id)時結果中,也就把id等於3的重複記錄刪除了
可以推論到假如還存在一條id=5,value=c的記錄,使用max(id)時得到的結果裏就會是>5 c這條了。

再來嘗試一下,如果min()和max()用在value字段裏呢:

SELECT id, min(value) FROM test_table GROUP BY id

得到結果:
| id |min(value)
| 1 | a
| 2 | b
| 3 | c
| 4 | c
| 5 | e

SELECT id, max(value) FROM test_table GROUP BY id

得到結果:
| id |min(value)
| 1 | a
| 2 | b
| 3 | c
| 4 | c
| 5 | f

結論4

當DISTINCT無法滿足只對單字段去重,並希望結果中顯示對應的多字段內容的時候,可以用group by函數實現。但要注意希望在結果中顯示的非去重目標字段,需要對它們分別添加篩選條件的函數或方法,否則sql語句會報錯。

再仔細想想,這種需求也只出現在不是那麼care顯示結果中,非去重目標字段的內容時才能使用,如果需要指定這些字段的值,可能篩選條件就不是min()和max()那麼簡單了....

以上。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章