MySQL - 加入用户最新级别,不是任何级别?

时间:2013-10-28 12:20:01

标签: mysql

我有users的表格:

id | name
1  | Mike

我有一个rights表,它为我的用户提供了一些权利,例如:

id | user | elevation | starts     | ends
1    1      2           1382950736   1383555536

在这里,我将迈克提升到2级,从1382950736开始,到1383555536结束。在此时间范围内,用户为2级。在其他时间,用户为1级。

我有一个查询来找出用户的级别:

SELECT IF(`z`.`elevation` IS NULL, 1, `z`.`elevation`) as `elevation`, `users`.`id`
FROM `users`
LEFT JOIN (
   SELECT `user`, `elevation`
   FROM `rights`
   WHERE (`starts` <= $time) AND (`ends` > $time)
   GROUP BY `user`
) as `z` ON `z`.`user` = `users`.`id`

这一切都很棒,而且效果很好。但是,如果某个用户的高程重叠,我会遇到问题。

例如:让我们想象一下,仅仅为了一个简单的例子,时间现在是10

我们创建此条目:

id | user | elevation | starts     | ends
1    1      2           1            15
2    1      3           5            20

在这种情况下,两个条目都满足(`starts` <= $time) AND (`ends` > $time)条件(当前时间为10)。我的SELECT查询在这些情况下所做的是它为我的用户返回级别2 ,尽管他的最新条目是级别3

我如何修复我的查询以返回最新级别,而不是任何级别,以防更多级别重叠

3 个答案:

答案 0 :(得分:2)

SELECT COALESCE(z.elevation,1) elevation
     , u.id
  FROM users u
  LEFT 
  JOIN 
     ( SELECT user
            , elevation
         FROM rights x
         JOIN 
            ( SELECT user,MAX(starts) max_starts FROM rights GROUP BY user ) y
           ON y.user = x.user
          AND y.max_starts = x.starts
        WHERE '$time' BETWEEN starts AND ends
     ) z
    ON z.user =  u.id

得到它?

答案 1 :(得分:0)

我无法理解用例背后的逻辑,但为什么不使用

order by elevation desc
limit 1;

答案 2 :(得分:0)

这个怎么样:

select if(rs.user is null, 1, r.elevation) as elevation, u.id
from users u
left outer join rights r on u.id = r.user
left outer join (
   select user, max(starts) as starts
   from rights
   where (starts <= $time) AND (ends > $time)
   group by user
) rs on r.user = rs.user and r.starts = rs.starts
where r.user is null or (r.user is not null and rs.user is not null);