如何在MySQL中从分组数据中删除行

如何在MySQL中从分组数据中删除行,mysql,sql,Mysql,Sql,我有一张桌子: 我希望每个live\u登录最多留下两个条目,这些条目按上次登录排序 因此,您应该获得: !!如果可能的话,不要只使用SQL,而不使用php和其他工具 对我的英语很抱歉: 答复: 谢谢你,草莓 Edit:显然,这个符合ANSI/ISO SQL的答案不适用于MySQL。可以与大多数其他dbms产品一起使用,所以我不删除答案 如果有两个或更多具有相同live_登录名的较新行,则删除一行: delete from tablename t1 where 2 <= (select co

我有一张桌子:

我希望每个live\u登录最多留下两个条目,这些条目按上次登录排序

因此,您应该获得:

!!如果可能的话,不要只使用SQL,而不使用php和其他工具

对我的英语很抱歉:

答复:

谢谢你,草莓

Edit:显然,这个符合ANSI/ISO SQL的答案不适用于MySQL。可以与大多数其他dbms产品一起使用,所以我不删除答案

如果有两个或更多具有相同live_登录名的较新行,则删除一行:

delete from tablename t1
where 2 <= (select count(*)
            from tablename t2
            where t2.live_login = t1.live_login
              and t2.last_login_ts > t1.last_login_ts)
编辑:显然,这个符合ANSI/ISO SQL的答案不适用于MySQL。可以与大多数其他dbms产品一起使用,所以我不删除答案

如果有两个或更多具有相同live_登录名的较新行,则删除一行:

delete from tablename t1
where 2 <= (select count(*)
            from tablename t2
            where t2.live_login = t1.live_login
              and t2.last_login_ts > t1.last_login_ts)
或者类似的


或者类似的东西

这是可行的,但很难看,而且可能是次优的:

delete logins from logins
inner join (
  select l1.live_login, l1.last_login_ts second, q1.last_login_ts min 
    from logins l1
    left join
      (select live_login, min(last_login_ts) last_login_ts 
        from logins 
        group by live_login) q1
    on q1.last_login_ts < l1.last_login_ts 
      and l1.live_login = q1.live_login
    where not exists 
     (select 1 
       from logins 
       where live_login = q1.live_login 
         and logins.last_login_ts > q1.last_login_ts 
         and logins.last_login_ts < l1.last_login_ts) 
     and q1.last_login_ts is not null) q
on q.live_login = logins.live_login and logins.last_login_ts > q.second;

这里演示小提琴:

这很管用,但很难看,可能不太理想:

delete logins from logins
inner join (
  select l1.live_login, l1.last_login_ts second, q1.last_login_ts min 
    from logins l1
    left join
      (select live_login, min(last_login_ts) last_login_ts 
        from logins 
        group by live_login) q1
    on q1.last_login_ts < l1.last_login_ts 
      and l1.live_login = q1.live_login
    where not exists 
     (select 1 
       from logins 
       where live_login = q1.live_login 
         and logins.last_login_ts > q1.last_login_ts 
         and logins.last_login_ts < l1.last_login_ts) 
     and q1.last_login_ts is not null) q
on q.live_login = logins.live_login and logins.last_login_ts > q.second;


这里演示小提琴:

这张表也可能有一个id列吗?@pala_uu否。这张表只有三列。@pala为什么?似乎不需要。@pala_u此表有PK live_u登录,dead_login@Strawberry我又有了一个思路。这个表可能也有一个id列吗?@pala_uuuo。这个表只有三列。@pala为什么?似乎不需要。@pala_u此表有PK live_u登录,dead_login@Strawberry我又有了一个思路。此SQL返回错误:错误代码:1064。您的SQL语法有错误;检查与您的MySQL服务器版本对应的手册,以了解使用“t1”附近的正确语法,其中2个3个向上投票,但它不起作用-您不能从子查询中引用的表中删除。除了它显然不起作用之外,您真的不想全部计数吗?此SQL返回错误:错误代码:1064。您的SQL语法有错误;查看与您的MySQL服务器版本对应的手册,以了解在t1附近使用的正确语法,其中2个3个向上投票,但它不起作用-您不能从子查询中引用的表中删除。除了它显然不起作用之外,您真的不想全部计数,是吗?有时,人们有时不知道他们想要什么,人们也不知道他们想要什么谢谢,但这是一个很长的查询,重要的不是查询的大小。这就是你如何使用它!谢谢,但这是一个很长的查询。重要的不是查询的大小。这就是你如何使用它!