mysql的group by用法在5.7和5.6中存在区别

http://stackoverflow.com/questions/39909261/order-by-before-group-by-in-subquery-working-in-mysql-5-5-but-not-in-mysql-5-7

http://stackoverflow.com/questions/34115174/i-am-getting-an-error-in-mysql-related-to-only-full-group-by-when-executing-a-qu

http://stackoverflow.com/questions/12113699/get-top-n-records-for-each-group-of-grouped-results,文章中写的参考例子都是获取到分组中的前两条记录,我们只要一条记录,把<=2改为<2即可

原来在5.6及其以下可以使用select * from(select * from table order by 排序字段) group by 字段,这种写法来得到分组需要的第一条记录,然而在5.7中子查询的排序条件会被忽略掉,暂时没有通过修改配置就可以解决的方案,只能参考demo自己改写sql语句,按照大神Drew的原句是我们原来的这种写法It is just sloppy programming.

第一种改写的办法:直接就是查出需要的ID再联查

第二种改写的办法就是添加变量

SELECT
    person,
    groupname,
    age
FROM
(
    SELECT
        person,
        groupname,
        age,
        @rn := IF(@prev = groupname, @rn + 1, 1) AS rn,
        @prev := groupname
    FROM mytable
    JOIN (SELECT @prev := NULL, @rn := 0) AS vars
    ORDER BY groupname, age DESC, person
) AS T1
WHERE rn <= 2

参照这个写法即

select * from(select *,@rn := IF(@prev = groupname, @rn + 1, 1) AS rn, @prev := groupname from table  join(select @prev:=NULL,@rn:=0) AS vars order by groupname,其它排序字段) group by groupname where rn<2

第三种改写的方法就是在where条件中联查自己过滤

SELECT a.person, a.group, a.age FROM person AS a WHERE 
(SELECT COUNT(*) FROM person AS b 
WHERE b.group = a.group AND b.age >= a.age) <= 2 
ORDER BY a.group ASC, a.age DESC
select * from table AS a WHERE (select (count(*) from table AS b where a.groupname=b.groupname AND 满足特定的条件(b.updatetime>=a.updatetime)))<2 order by 排序条件

第四种改写的方法和第三种的原理类似,也是自己联查自己,只是不需要子查询,通过having条件来过滤

SELECT a.* FROM mytable AS a
  LEFT JOIN mytable AS a2 
    ON a.groupname = a2.groupname AND a.age <= a2.age
GROUP BY a.person
HAVING COUNT(*) <= 2
ORDER BY a.groupname, a.age DESC;



评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值