基于连接上的最高时间戳仅选择不同的行

时间:2015-12-10 03:19:32

标签: 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 
 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

2 个答案:

答案 0 :(得分:0)

您应该将查询编写为:

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;

除非必要,否则请勿使用select distinct。然后你可以通过各种方式做你想做的事。因为你有join和其他条件,我认为变量可能是最简单的方法:

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;

答案 1 :(得分:0)

我找出了一个有效的查询,不确定它是否是万无一失或最有效的方法

这是你的

      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')