我有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 。
我如何修复我的查询以返回最新级别,而不是任何级别,以防更多级别重叠?
答案 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);