Mysql 根据联接上的最高时间戳仅选择不同的行

Mysql 根据联接上的最高时间戳仅选择不同的行,mysql,Mysql,我在mysql中对这两个表执行连接 挑战表 challenge_ID(int) |to_user(int)|from_user(int)|timestamp 用户表 iduser(int)|email(string) 我的加入查询如下: Select distinct u.email,c.challenge_id,c.status,c.timestamp from test.challenges c join test.users u on c.to_user=u.iduser

我在mysql中对这两个表执行连接

挑战表

challenge_ID(int) |to_user(int)|from_user(int)|timestamp
用户表

iduser(int)|email(string)
我的加入查询如下:

 Select distinct u.email,c.challenge_id,c.status,c.timestamp from 
 test.challenges c join test.users u
 on 
  c.to_user=u.iduser 
 where 
  c.from_user=9 and (c.status='open' || c.status='rejected') 
 Order by 
  c.timestamp DESC
我从这个查询中得到的结果是

email           |challenge_id| status    |timestamp (Descending)
Dan21@rab.edu       5           open      2015-12-09 21:20:26
tommy52@gump.com    4           open      2015-12-09 21:10:22
Dan21@rab.edu       1           rejected  2015-12-08 12:27:00
注意如何Dan21@rab.edu重复两次,我希望它只显示一次,并且显示的一个应该具有最新的时间戳,即

email           |challenge_id| status    |timestamp (Descending)
    Dan21@rab.edu       5           open      2015-12-09 21:20:26
    tommy52@gump.com    4           open      2015-12-09 21:10:22

您应该将查询编写为:

Select u.email, c.challenge_id, c.status, c.timestamp
from test.challenges c join
     test.users u
     on c.to_user = u.iduser 
 where c.from_user = 9 and c.status in ('open', 'rejected') 
 Order by c.timestamp DESC;
除非必要,否则不要使用
选择distinct
。然后你可以用各种方式做你想做的事。因为您有一个
连接
和其他条件,我认为变量可能是最简单的方法:

select cu.*
from (Select u.email, c.challenge_id, c.status, c.timestamp,
             (@rn := if(@e = u.email, @rn + 1,
                        if(@e := u.email, 1, 1)
                       )
             ) as rn
      from test.challenges c join
           test.users u
           on c.to_user = u.iduser cross join
           (select @e := '', @rn := 0) params
       where c.from_user = 9 and c.status in ('open', 'rejected') 
       order by u.email, c.timestamp DESC
      ) cu
where rn = 1;
编辑:

我认为上述方法可以在单个查询中使用
join
和变量。但是,有时MySQL会混淆,您需要使用带有变量的子查询:

select cu.*
from (select cu.*,
             (@rn := if(@e = u.email, @rn + 1,
                        if(@e := u.email, 1, 1)
                       )
             ) as rn
      from (Select u.email, c.challenge_id, c.status, c.timestamp,
            from test.challenges c join
                 test.users u
                 on c.to_user = u.iduser 
            where c.from_user = 9 and c.status in ('open', 'rejected') 
            order by u.email, c.timestamp DESC
           ) cu cross join
           (select @e := '', @rn := 0) params
      ) cu
where rn = 1;

我找到了一个对此有效的查询,不确定这是最简单的方法还是最有效的方法

给你

      Select distinct u.email,c.challenge_id,c.status,c.timestamp
            from
                (select ch.challenge_id,ch.status,ch.from_user,ch.to_user,timestamp,
                    (select Max(timestamp) from challenges 
                        where to_user=ch.to_user
                        and from_user=9
                    ) as latest 
               from test.challenges ch 
                )c
            join test.users u
            on
                c.to_user=u.iduser
            and
            c.latest=c.timestamp
    where (c.status='open' || c.status='rejected')

我以前从未使用过variable,我试图理解你给出的查询,我在我的数据库上运行了它,它似乎返回相同的结果(将电子邮件id tho分组),但对于所有行,rn仍然是1,它返回所有3行。我发现这很难理解,因为我没有使用mysql(或RDs)很多其他基本查询。我把它复制粘贴到我的phpadmin中,它在第一个连接附近给了我一个语法错误。我用一个子查询找到了一个查询连接,我已经在答案上发布了它。我没有做过太多的测试,但是很明显,如果这不是最有效的方法,请让我知道它的用途