我的数据库中有两个不同的表,名称为:rank,settings。
以下是每个表的外观如下:
id points userid
-- ----- ------
1 500 1
2 300 2
3 900 3
4 1500 4
5 100 5
6 700 6
7 230 7
8 350 8
9 850 9
10 150 10
userid active
------ ------
1 0
2 1
3 1
4 1
5 1
6 0
7 1
8 1
9 0
10 1
我基本上想要实现的是从ID中选择#rank中的特定行,按点排序并选择特定ID上方3行和特定ID下方3行但仅适用于活动列的行(来自#settings)用户等于1。
例如: 我想从#rank中选择ID为8,它应该返回以下内容:
rank points userid
---- ----- ------
2 150 10
3 230 7
4 300 2
5 350 8
6 900 3
7 1500 4
我已经为此创建了相当广泛的查询,但问题是,它在确定用户是否处于活动状态之前对列进行排名。但是,在确定用户是否处于活动状态后,我需要对列进行排名。
SELECT sub2.sort, sub2.points, sub2.userid
FROM
(
SELECT @sort1 := @sort1 + 1 AS sort, puu.points, puu.userid
FROM rank as puu,
(SELECT @sort1 := 0) s
LEFT JOIN
(
settings as p11
)
ON puu.userid = p11.userid,
WHERE p11.active = 1
ORDER BY puu.points DESC
) sub1
INNER JOIN
(
SELECT @sort2:=@sort2+1 AS sort, p2.points, p2.userid
FROM rank as p2,
(SELECT @sort2 := 0) s
LEFT JOIN
(
settings as p12
)
ON p2.userid = p12.userid,
WHERE p12.active = 1
ORDER BY points DESC
) sub2
ON sub1.userid = :userid
AND sub2.sort BETWEEN (sub1.sort - 5) AND (sub1.sort + 5)
你们能找到解决问题的方法吗?如果你能提供一个SQLfiddle演示,那真是太棒了!
答案 0 :(得分:1)
SELECT sort, points, user_id, active FROM (
SELECT @pos := @pos + 1 AS sort, id, points, r.user_id, s.active,
IF(user_id = :userid, @userpos := @pos, 0)
FROM rank r
JOIN settings s USING(user_id)
JOIN (SELECT @pos := 0, @userpos := 0) p
WHERE s.active = 1
ORDER BY points DESC
) list
WHERE sort BETWEEN @userpos - 3 AND @userpos + 3
我在这里做了一个小提琴:sqlfiddle
答案 1 :(得分:0)
可能使用2个联合查询来获取排名前的值: -
SELECT @rank:=@rank+1 AS rank, points, userid
FROM
(
SELECT id, points, userid
FROM
(
SELECT rank.id, rank.points, rank.userid
FROM rank
INNER JOIN
(
SELECT points
FROM rank
WHERE id = 8
) sub0
ON rank.points >= sub0.points
INNER JOIN settings
ON rank.userid = settings.userid
WHERE settings.active = 1
ORDER BY rank.points LIMIT 3
) sub1
UNION ALL
SELECT id, points, userid
FROM
(
SELECT rank.id, rank.points, rank.userid
FROM rank
INNER JOIN
(
SELECT points
FROM rank
WHERE id = 8
) sub0
ON rank.points < sub0.points
INNER JOIN settings
ON rank.userid = settings.userid
WHERE settings.active = 1
ORDER BY rank.points DESC LIMIT 3
) sub1
) sub2
CROSS JOIN (SELECT @rank:=0) sub3
ORDER BY points