Distinct是SQL中一种很常见的操作,能够很方便地筛选掉结果中重复的行。首先来看看Distinct操作的效果:
 mysql> select * from ob;
 +------+------+------+
 | a    | b    | c    |
 +------+------+------+
 |    1 |    2 |    3 |
 |    1 |    2 |    3 |
 |    1 |    2 |    3 |
 |    1 |    2 | 2323 |
 |    1 |  323 |   21 |
 |    9 |    9 |    9 |
 +------+------+------+
 6 rows in set (0.00 sec)
/// 取出所有不同行
mysql> select distinct * from ob;
 
+------+------+------+
 | a    | b    | c    |
 +------+------+------+
 |    1 |    2 |    3 |
 |    1 |    2 | 2323 |
 |    1 |  323 |   21 |
 |    9 |    9 |    9 |
 +------+------+------+
 
4 rows in set (0.00 sec)
/// 取出所有a, b列不相同的行
mysql> select distinct a, b from ob;
 +------+------+
 | a    | b    |
 +------+------+
 |    1 |    2 |
 |    1 |  323 |
 |    9 |    9 |
 +------+------+
 3 rows in set (0.00 sec)
在数据库的设计中,如何实现Distinct操作呢?一般有两种基本思路:排序(Sort)法,哈希(Hash)法。
排序法将表格中的数据全部按照distinct指定的列为key进行排序,然后逐行迭代,每迭代出一行数据都与上一行数据根据key作对比,如果相同,则丢弃当前行继续迭代下一行,如果不同则输出。排序法带来的一个副作用就是数据输出按照key有序。mysql在某些情况下不是使用排序法,通过下面的输出可以观察到行并不是有序的:
mysql> select distinct a, b from ob;
 +------+------+
 | a    | b    |
 +------+------+
 |    1 |    2 |
 |    1 |  323 |
 |    9 |    9 |
 |    0 |    0 |
 +------+------+
 4 rows in set (0.00 sec)
哈希法将表格中的数据全部按照distinct指定的列值为key作为hash key进行分桶,key相同的行自然就被区分出来了。
排序法在具体实现中会遇到这么一些问题:
1. 数据集超出了内存限制,如何排序?
2. 如何实现可以尽可能减少数据拷贝?
3. 如果已经有了Sort运算符,如何实现代码重用。
考虑一种理想实现,sort依次排序出最大,次大,较大,。。。等行,没一行输出后都跟前一行比较,如果key相等则丢弃,这样,sort完毕,distinct也做完了。堆排序可以较好地满足这一要求。但是,堆排序不支持外排,当数据集合超出内存限制时该方法将失效。
最后说个题外话,distinct跟groupby蛮像的,那么他们的区别又在哪里呢? 简单地说,distinct是一种很弱的groupby。详细见网上转载的一篇文章:
SQL語法 : DISTINCT vs GROUP BY
 
  我使用的是SQLyog執行我的測試!! SQL語法的保留字~大小寫我在寫下列例子沒有很在意... 
 
 主要是為了情境所測出的心得~~如測試結果不同,請給我意見(pls leave comment)喔!! 
 
 CC~~ ^^ 
 
 -------------------------------------------------------------------------------------------------------------- 
 
 Table: member 
 
id  | name  | email_address  | 
11  | Mary  | mary@gmail.com  | 
22  | Mary  | mary@hotmail.com  | 
33  | John  | john@gmail.com  | 
44  | Leo  | leo@gmail.com  | 
55  | Jane  | jane@hotmail.com  | 
55  | Janny  | jane@hotmail.com  | 
 -------------------------------------------------------------------------------------------------------------- 
 
 Create Table  
 member_distinct_by_name 
 
 Select  
 Distinct  
 name 
 
 From  
 member 
 
 ------------------------------------------------- 
 
 result: 
 
 Table:  
 member_distinct_by_name 
 
 
 
name  | 
Mary  | 
John  | 
Leo  | 
Jane  | 
 --------------------------------------------------------------------------------------------------------------- 
 
情境: 依據不重覆的 email_address,拉出想要的資料! 
 
 Create Table  
 member_group_by_emailaddress 
 
 Select 
   
 email_address, id 
 
 From 
  member  
 GROUP BY 
  name 
 
 
 
 ------------------------------------------------ 
 
 result: 
 
 Table:  
 member_group_by_ 
 emailaddress 
 
email_address  | id  | 
mary@gmail.com  | 11  | 
mary@hotmail.com  | 22  | 
john@gmail.com  | 33  | 
leo@gmail.com  | 44  | 
Jane@hotmail.com  | 55  | 
 ---------------------------------------------------------------------------------------------------------------- 
 
 Create Table  
 member_distinct 
 
 Select  
 Distinct  
 email_address, name, id  (只要有一欄位的data不一樣就會納入) 
 
 From  
 member 
 
 --------------------------------------------------- 
 
 result: 
 
 Table:   
 member_distinct 
 
ID  | NAME  | GENDER  | 
11  | Mary  | mary@gmail.com  | 
22  | Mary  | mary@hotmail.com  | 
33  | John  | john@gmail.com  | 
44  | Leo  | leo@gmail.com  | 
55  | Jane  | jane@hotmail.com  | 
55  | Janny  | jane@hotmail.com  | 
 
 
/// 取出所有不同行










