我在mysql数据库中有一个名为student的表,如下所示。
name value
sdf -3
abc 3
ddf 4
sdf 7
给定一个值,我应该能够找到最接近它的值,但是一个值较小而另一个值较大。
例如:给定3,输出应为-3和4
我有一个类似的解决方案:
(select value from student where value>3 order by value desc limit 1)
union
(select value from student where value<3 order by value desc limit 1)
但是我想要一个能够有效地遍历表并产生结果的查询。你能帮我找到吗?
答案 0 :(得分:0)
以下内容应该有效,但确定只扫描
SELECT max(if(value < 3, value, NULL)) AS predecessor,
min(if(value > 3, value, NULL)) AS successor
FROM TABLE;
根据wikipedia,十万行是~10 ^ 5行。在现代硬件上,你应该没问题。在MacBook Pro上测试:
mysql> SELECT max(if(value < 3, value, NULL)) AS predecessor, min(if(value > 3, value, NULL)) AS successor FROM toto;
+-------------+-----------+
| predecessor | successor |
+-------------+-----------+
| 2 | 4 |
+-------------+-----------+
1 row in set (0.35 sec)
mysql> select count(*) from toto;
+----------+
| count(*) |
+----------+
| 1000004 |
+----------+
1 row in set (0.23 sec)
答案 1 :(得分:0)
如果您使用的是Postgressql,Oracle或sql-server,那么如果值重复,这应该可以工作并忽略
WITH cte AS (
SELECT
*
,DENSE_RANK() OVER (ORDER BY value ASC) AS Rank
FROM
Tbl
)
SELECT
c.name
,c.value
,p.value AS Predesessor
,s.value AS Successor
FROM
cte c
LEFT JOIN cte s
ON (c.Rank + 1) = s.Rank
LEFT JOIN cte p
ON (c.Rank - 1) = p.Rank