如何从mysql中的数据库中获取最接近的值
Posted
技术标签:
【中文标题】如何从mysql中的数据库中获取最接近的值【英文标题】:how to get nearest value from database in mysql 【发布时间】:2011-11-08 07:32:27 【问题描述】:我正在使用mysql
和CodeIgniter
。我的数据库中有一些浮点数,例如
我想……
SELECT * FROM table WHERE value = $myvalue
但我不能在我的 SELECT 查询中使用value = $myvalue
,因为$myvalue
不完全等于数据库值。我需要从数据库中获取最接近 $myvalue
的值。
如果$myvalue
是5,我想选择值4.5556
。
如何在 mySQL 中执行此操作?
【问题讨论】:
如果您有几行,那么顶部的答案就足够了 - 但是如果您有数百万行,我不会推荐它们,因为它们会扫描整个表格 - 而是在底部(权衡是可读性,因为查询更长 - 但也更快) 【参考方案1】:select *
from table
order by abs(value - $myvalue)
limit 1
【讨论】:
可能会进行(慢)表扫描。【参考方案2】:假设您有 10% 的容差 (+/-),您可以尝试以下方法:
select * from table
where value >= ($myvalue * .9) and value <= ($myvalue * 1.1)
order by abs(value - $myvalue) limit 1
略微更新了从其他人那里窃取的信息 - 这应该会返回假设容差范围内最接近的结果。 (另外,我刚刚注意到哪里不正确,抱歉 - 现在应该可以了)。
【讨论】:
如果最近的 $myvalue 与任意值的距离大于您的任意 % 怎么办? 原来的要求不是很清楚。当然,如果没有“可接受的范围”,您可以说 10000000000 足够接近“1”,假设您的数据库中没有更好的东西。在这种情况下,您可以删除“where”部分。 注意,如果$Myvalue
为0,这将失败。如果你真的想这样做,你需要添加OR (($myvalue >= (value * .9)) AND ($myvalue <= (value * 1.1)))
例如,如果他输入 6,这将不会显示最接近的值 -> 但是您使用 >= 和 任何看到这个的人请看我的答案底部,这将给出一个快速、正确的结果。【参考方案3】:
(
select *
from table
where value >= $myvalue
order by value asc
limit 1
)
union
(
select *
from table
where value < $myvalue
order by value desc
limit 1
)
order by abs(value - $myvalue)
limit 1
这可能看起来违反直觉,但速度会比目前显示的其他查询更快。
这是因为greater than
和less than
查询更快。
然后在两个值上执行ABS
没什么。
这将在我能想到的单个查询中为您提供最快的返回。
对整个表执行ABS
会很慢,因为它会扫描整个表。
【讨论】:
看起来是迄今为止最好的答案【参考方案4】:获取类似于$val的最大值:
SELECT * FROM tab WHERE val <= $val ORDER BY val DESC LIMIT 1
获取类似于$val的最小值:
SELECT * FROM tab WHERE val >= $val ORDER BY val LIMIT 1
在任一方向上获取类似于 $val 的最接近的值:
SELECT * FROM tab ORDER BY abs(val - $val) LIMIT 1
【讨论】:
【参考方案5】:从以下取第一个值:
select * from table order by abs(value - $myvalue);
【讨论】:
【参考方案6】:就我而言,我使用浏览器的地理位置并尝试根据我在表格中的坐标找到最近的城市/州。
表结构:
id zipcode city_state lat lon
1 12345 Example, GA 85.3 -83.2
建议在使用之前对其进行大力测试——可能需要一些调整,但我想以此作为开始
SELECT city_state,
zipcode,
( Abs( lat - -33.867886 )
+ Abs( lon - -63.987) ) AS distance
FROM zipcodes
ORDER BY distance
LIMIT 1;
对于 laravel 用户:
$city = Zipcodes::selectRaw
('city_state, zipcode, ( ABS( lat - ? ) + ABS( lon - ?) ) AS distance', [$lat, $lon])
->orderBy('distance')
->first();
echo $city->city_state
希望有一天这对某人有所帮助。
【讨论】:
【参考方案7】:SELECT * FROM table1 ORDER BY ABS(value - '$myvalue') LIMIT 1
【讨论】:
【参考方案8】:不幸的是,我认为您的数据库可能会对涉及abs
的解决方案进行全表扫描,因此一旦您的表增长,它们将(非常)慢。可以在此earlier thread 中找到快速运行的解决方案。
【讨论】:
【参考方案9】:SELECT number, ABS( number - 2500 ) AS distance
FROM numbers
ORDER BY distance
LIMIT 6
Selecting closest values in MySQL
【讨论】:
【参考方案10】:试试这个:
SELECT *,abs((columnname -Yourvalue)) as near
FROM table
WHERE order by near limit 0,1
【讨论】:
【参考方案11】:阅读此页http://dev.mysql.com/doc/refman/5.1/en/mathematical-functions.html#function_round
但您的选择看起来像这样
select value from table where ROUND(value) = $myvalue
【讨论】:
如果最近的$myvalue
与任何值的距离大于1怎么办?
@Bohemian - 在某些时候你需要一个截止点来匹配值
@Bohemian,不,这完全取决于您的应用程序,如果您需要一个截止值,它应该始终是原始值的百分比。如果您不处理8.12
,而是处理15,481,254,454,875,544,545.1
,该怎么办?
问题很明确:“选择最接近的值”。它没有说明值的多远......可能是1000。你的答案很简单,“错误”。以上是关于如何从mysql中的数据库中获取最接近的值的主要内容,如果未能解决你的问题,请参考以下文章