在使用mysql时,有时需要查询出某个字段不重复的记录,虽然mysql提供 有distinct这个关键字来过滤掉多余的重复记录只保留一条,但往往只用它来返回不重复记录的条数,而不是用它来返回不重记录的所有值。其原因是 distinct只能返回它的目标字段.
而无法返回其它字段,这个问题让我困扰了很久,用distinct不能解决的话,我只有用二重循环查询来解决,而 这样对于一个数据量非常大的站来说,无疑是会直接影响到效率的。所以我花了很多时间来研究这个问题
mysql的DISTINCT的关键字有很多你想不到的用处
1.在count 不重复的记录的时候能用到,比如SELECT COUNT( DISTINCT id ) FROM tablename;就是计算talbebname表中id不同的记录有多少条
2,在需要返回记录不同的id的具体值的时候可以用,比如SELECT DISTINCT id FROM tablename;返回talbebname表中不同的id的具体的值
3.上面的情况2对于需要返回mysql表中2列以上的结果时会有歧义,比如SELECT DISTINCT id, type FROM tablename;
实际上返回的是 id与type同时不相同的结果,也就是DISTINCT同时作用了两个字段,必须得id与tyoe都相同的才被排除了,与我们期望的结果不一样.
例,代码如下:
- CREATE TABLE `student` (
- `name` varchar(20) NOT NULL DEFAULT '',
- `age` int(10) DEFAULT '0'
- ) ENGINE=InnoDB DEFAULT CHARSET=latin1
-
-
-
- select * from student;
- a 5
- a 5
- c 0
用distinct过滤掉两列都相同的记录,代码如下:
- select distinct name,age from student;
-
-
-
- a 5
-
- c 0
2.测试二
将表student的数据改为如下,代码如下:
- select * from student;
- c 2
- c 5
-
- select distinct name,age from student;
返回如下,说明distinct后面有多于一列的字段时,只有每列的值完全相同才过滤.
c 2
c 5
3.测试三,代码如下:
- select * from student;
- name age height
-
- c 2 123
- c 2 456
- b 20 222
group by按两列同时分组,代码如下:
- select name,age,sum(height) from student group by name,age;
- b 20 222
- c 2 579
group by按两列同时分组,同时在后面加上having的条件,代码如下:
select name,age,sum(height) as n from student group by name,age having n > 500;
返回:c 2 579
4.测试四
关于group by后面limit的测试,代码如下:
- select songname,sengerid,count(sengerid) as n from t_song group by songname,sengerid having n > 1 ORDER BY n DESC,songid ASC limit 10;
-
- 未知 8738 40
- 共同渡过 1432 24
- 风继续吹 1432 23
- 倩女幽魂 1432 23
- 无心睡眠 1432 23
- 罗百吉超嗨派对连续组曲 780 19
- 拒绝再玩 1432 19
- 风再起时 1432 18
- 每天爱你多一些 1480 18
- 千言万语 1794 18
-
- select songname,sengerid,count(sengerid) as n from t_song group by songname,sengerid having n > 1 ORDER BY n DESC,songid ASC limit 5;
-
- 未知 8738 40
- 共同渡过 1432 24
- 风继续吹 1432 23
- 倩女幽魂 1432 23
- 无心睡眠 1432 23
经过以上两个测试可以看出,如果sql语句中含有limit,limit是对用group by进行分组,并进行相关计算以后的limit操作,而不是对limit后面的指定记录数进行分组,从n那一列的数据每一行的值都大于10就可以看出来.
5.测试五
用以下的两种形式的distinct均可以得到相同的记录数,写法不一样,结果是一样的,代码如下:
select count(distinct(songid)) from feedback;
select count(distinct songid) from feedback;
6.测试六
field singername is string,max(singername),如果singername有些列为空,有些列不为空,则max(singername)取非空的值,如果一列为zxx,一列为lady,则取zxx,按字母顺利取的,代码如下:
select feedback_id,songid,songname,max(singername),max(time) as new_time from feedback group by songid order by new_time desc;
7.Sql语句中where,group by,order by及limit的顺序
where xxx,group by xxx,order by xxx,limit xxx
8.关于group by与count的问题
如果sql语句中含有group by,则最好不要将count sql转换为select count(*) from xxx,否则select与from之间的字段很有可能是后面要使用的,代码如下:
- select feedback_id,songid,songname,max(singername),max(time) as new_time from feedback group by songid order by new_time desc;
-
- MySQL Query Error: SELECT COUNT(*) FROM feedback GROUP BY songid ORDER BY new_time DESC Error Info:Unknown column 'new_time' in 'order clause'
|