不知道这个问题的标题是否合适,但我的问题很简单
我有一个结果列表,为简单起见,它只包含id
和price
:
+----+-------+
| id | price |
+----+-------+
| 11 | 10 |
| 52 | 17 |
| 23 | 45 |
| 24 | 50 |
| 55 | 60 |
| 96 | 70 |
| 7 | 75 |
| 78 | 80 |
| 99 | 100 |
+----+-------+
对于给定的ID /价格,我需要找到价格较低的前2条记录,然后是价格较高的2条记录。
例如,对于id = 55和price = 60,结果将为:
+----+-------+
| id | price |
+----+-------+
| 23 | 45 |
| 24 | 50 |
| 96 | 70 |
| 7 | 75 |
+----+-------+
在粗略的实现中,这可以通过UNION获得,如下所示:
SELECT id, price
FROM MyTable
WHERE price <= 60 AND id != 55
ORDER BY price DESC
LIMIT 0,2
UNION ALL
SELECT id, price
FROM MyTable
WHERE price >= 60 AND id != 55
ORDER BY price ASC
LIMIT 0,2
但鉴于MyTable实际上是一个使用后面的复杂查询获得的视图,还有另一种方法可以实现吗?
我甚至认为不是运行查询两次(使用UNION),而是在一个查询中获取所有结果,然后使用PHP查找4个结果。
答案 0 :(得分:2)
你必须检查一下: 您的查询
SELECT id, price FROM (
SELECT @rank:=@rank+1 AS rank, @selectedRank := IF(id = 55, @rank,
@selectedRank), id, price
FROM ( SELECT id, price FROM MyTable ORDER BY price
) t1, (SELECT @rank:=0) t2, (SELECT @selectedRank:=0) t3
) results
WHERE rank != @selectedRank AND rank BETWEEN @selectedRank - 2 AND @selectedRank + 2;
SELECT * FROM test.mytable
WHERE
price >= (SELECT price FROM MyTable
WHERE price <= 60
ORDER BY price DESC
LIMIT 2,1)
and id != 55
ORDER BY price
LIMIT 4;
答案 1 :(得分:0)
感谢@David Packer的提示和这个answers,我找到了只迭代表一次的解决方案:
SELECT id, price
FROM (
SELECT @rank:=@rank+1 AS rank, @selectedRank := IF(id = 55, @rank, @selectedRank), id, price
FROM (
SELECT id, price
FROM MyTable
ORDER BY price
) t1, (SELECT @rank:=0) t2, (SELECT @selectedRank:=0) t3
) results
WHERE rank != @selectedRank
AND rank BETWEEN @selectedRank - 2 AND @selectedRank + 2;