我有一个名为users的简单表,其中包含以下数据:
id | hops
1 | 3
2 | 1
3 | 5
4 | 2
5 | 4
6 | 5
我想选择我指定的任何给定id的跳数,并根据从最高到最低排序的跳数选择下一个和前一个id。
为了解释更多,我使用以下查询:
SELECT * FROM test WHERE id = 1
OR (id > 1 AND hops >= (SELECT hops FROM test WHERE id= 1) )
OR (id < 1 AND hops <= (SELECT hops FROM test WHERE id= 1) )
LIMIT 3
因此,在上面的查询中,我尝试获取id=1
,下一个具有相同或更高跳数的id,以及之前具有相同或更低跳数的id。
这是我得到的结果:
id | hops
1 | 3
3 | 5
5 | 4
正如你所看到的,它选择了id = 1和两个更高的id,尽管我只想要一个更高的id和一个更低的id。因此,在这种情况下,结果应该是这样的:
id | hops
1 | 3
3 | 5
由于没有低于1的id,所以没有任何低于符合标准并仅选择1个更高的id。错误的结果是因为使用LIMIT 3但我不能为每个条件使用LIMIT。所以根本不知道如何处理这个问题。
有另一个问题,会使用子查询
"SELECT hops FROM test WHERE id= 1"
大规模减慢服务器?我听说使用子查询不是优选的,但除了使用单独的查询之外没有其他方法可以获得此数字。
由于
答案 0 :(得分:3)
在这里,你可以根据自己的喜好按ID更改订单...你没有说你是想要最接近的跳数还是最接近的ID,只有一个更大或更低
SELECT * FROM test
WHERE id IN (1,(
SELECT id FROM test WHERE id > 1 AND hops >= (
SELECT hops FROM test WHERE id = 1
) ORDER BY id LIMIT 1
), (
SELECT id FROM test WHERE id < 1 AND hops <= (
SELECT hops FROM test WHERE id = 1
) ORDER BY id DESC LIMIT 1
))
答案 1 :(得分:1)
如果我理解你的问题,我相信以下内容会有效。
-- Previous Rec
SELECT t2.*
FROM test as t1
JOIN test as t2 ON t2.hop <= t1.id
WHERE t1.id = 1
ORDER BY t2.id DESC
LIMIT 1
UNION ALL
-- Current Rec
SELECT *
FROM test as t
WHERE id = 1
UNION ALL
-- Following Rec
SELECT t2.*
FROM test as t1
JOIN test as t2 ON t2.id >= t1.hop
WHERE t1.id = 1
ORDER BY t2.id ASC
LIMIT 1