SQL查询一个表中类别字段中Max()最大值对应的记录

问题是:

数据库有一个表 code,里面有个点击量字段click_num和一个类别字段kind以及其它信息字段,

现在要搜出每个类别中点击量最大的那条记录,如果是10个类别,那么结果应该是10条记录,

如果最大点击量有两个相同的只要一条。

经过N次搜索,N次检测网上的解决SQL语句,终于找到个优雅的而且结果正确的SQL,这个是一个博客作者在Mysql的官方文档里面发现的。

禁不住收藏了,以备后用。



  1. select id,kind,click_num from code as a
  2. where  click_num=(select max(b.click_num)
  3. from code as b
  4. where a.kind = b.kind
  5. );

特别注意:

这个语句在SQLite上测试正常,速度很快。但是在我机器上的MySql5.0上执行后就死机了,其他版本的Mysql不知道什么情况。

上面的语句还不能满足我的第二个要求就是:如果某类别中最大点击量有两个相同的记录,只要一条。

下面是我附加的解决办法:

筛选,保证每个类别只有一条,(kind,id改为所有列,结果就是对应的记录了)



  1. select  *
  2. from (select id,kind,click_num from code as a
  3. where  click_num=(select max(b.click_num)
  4. from code as b
  5. where a.kind = b.kind
  6. )
  7. ) as a
  8. group by kind

后续:

结合以往的Mysql使用经验发现Mysql的一个最大问题就是在一个查询的where子句中如果包含对前面select的表的查询那么CPU占用就会飙升Mysql服务停止。可以说是自连接查询问题,不知道这是不是个bug,5.0,5.1版本都有这个问题,回头看看上面的SQL语句正好符合了这个问题,解决办法就是把子查询的表弄成一个临时表或者视图总之不能和前面的select的表是同一个表,那么问题就解决了,于是乎,对上面的SQL稍作修改就可以在Mysql上跑了。

修改过程:

1.建立一个视图max_click,存储的是每个类别最大的点击量



  1. create view max_click as select max(click_num) as click_num,kind
  2. from code
  3. group by kind;

2.筛选,保证每个类别只有一条记录



  1. select  *
  2. from (select id,kind,click_num
  3. from  code
  4. where click_num = ( select b.click_num
  5. from max_click as b
  6. where code.kind = b.kind
  7. )
  8. ) as a
  9. group by kind;

运行正常,速度0.78秒。(表中一共23000条数据) Okay! 大功告成!

最前面第一个SQL在MSSQL上运行不知道行不行,我想在SQLite能正常在MSSQL上应该没问题,看来Mysql需要改进的地方很多啊,同样是开源的SQLite就可以做到的,而且SQLite那么轻量级就几百KB,Mysql更应该能做到。

时间: 2024-10-02 16:14:51

SQL查询一个表中类别字段中Max()最大值对应的记录的相关文章

SQL 查询所有表名、字段名、类型、长度、存储过程、视图

-- 获得存储过程创建语句 select o.xtype,o.name,cm.text from syscomments cm inner join sysobjects o on o.id=cm.id where xtype ='p' order by o.xtype,o.name,cm.text -- 获得视图程创建语句 select o.xtype,o.name,cm.text from syscomments cm inner join sysobjects o on o.id=cm.i

SQL查询一个表的总记录数的方法

一.简单查询语句 1. 查看表结构 SQL>DESC emp; 2. 查询所有列 SQL>SELECT * FROM emp; 3. 查询指定列 SQL>SELECT empmo, ename, mgr FROM emp; SQL>SELECT DISTINCT mgr FROM emp; 只显示结果不同的项 4. 查询指定行 SQL>SELECT * FROM emp WHERE job='CLERK'; 5. 使用算术表达式 SQL>SELECT ename, sa

SQL查询一个表中另外一个表不存在的数据-转

#方法一:使用 not in ,容易理解,效率低  ~执行时间为:1.395秒~SELECT COUNT(1) FROM ecs_goods WHERE ecs_goods.goods_id NOT IN (SELECT ecs_member_price.goods_id FROM ecs_member_price);#方法二:使用 left join...on... , "B.ID isnull" 表示左连接之后在B.ID 字段为 null的记录  ~执行时间:0.739秒~SELE

sql语句查询同一表内多字段同时重复的记录 sql数据库重复记录删除

分享下用sql语句删除数据库中重复记录的方法.比如现在有一人员表 (表名:peosons) 若想将姓名.身份证号.住址这三个字段完全相同的记录查询出来select p1.* from persons p1,persons p2 where p1.id<>p2.id and p1.cardid = p2.cardid and p1.pname = p2.pname and p1.address = p2.address可以实现上述效果.几个删除重复记录的SQL语句 1.用rowid方法2.用gr

向数据库中插入一个DateTime类型的数据到一个Date类型的字段中,需要转换类型。TO_DATE(&#39;{0}&#39;,&#39;YYYY-MM-DD&#39;))

需要指出的是,C#中有datetime类型,但是这个类型是包括小时,分钟,秒的.这个格式与数据库中的Date类型不符,如果将now设为datetime类型插入数据会失败. 需要通过TO_DATE('字段','YYYY-MM-DD'))转换.如下: string.Format("insert into tablename (TIME) values(TO_DATE('{0}','YYYY-MM-DD'))",now) 错误写法: string.Format("insert in

Hibernate原生SQL查询多表关联,SQL语句要注意的问题

Hibernate原生SQL查询多表关联,SQL语句要注意的问题 @for&ever 2009-9-4 系统环境: MySQL5.1 Hibernate3.3 有如下的假定: 实体类 Question 和 Answer分别对应数据表 question 和answer. 并且表 question 和answer 的字段大部分都一样,字段数目也一样. 执行如下的操作: 1> 使用hibernate 使用原生SQL查询, Query q = session.createSQLQuery(sql).

sql:查询创建表的结构

? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86

SQL查询某表是否存在及返回新增数据的ID

下面简单介绍了SQL查询某表是否存在以及返回新增数据的ID值. 1.查询表是否存在: 表名:"t_Demo", type = 'u'  查看是不是用户表 select * from sysobjects where id = object_id('t_Demo') and type = 'u' select * from sys.tables where name='t_Demo' and type = 'u' 2.查询字段是否存在: 表名:"t_Demo", 字段

1.sql 查询和删除多条字段的重复语句

查询 select a.* from Base_UserDeptRole a inner join( select DeptRoleId,UserId from Base_UserDeptRole(表) group by DeptRoleId,UserId having count(*)>1) tem on tem.UserId=a.UserId and tem.DeptRoleId=a.DeptRoleId 删除 select distinct DeptRoleId,UserId into #