当前位置:  开发笔记 > 数据库 > 正文

SQLite - 获得最接近的值

如何解决《SQLite-获得最接近的值》经验,为你挑选了2个好方法。

我有SQLite数据库,我在其中有一些类型为"double"的列.我想获得一个在此列值中最接近指定值的行.

例如,在我的表中我有:

id: 1; value: 47
id: 2; value: 56
id: 3; value: 51

我想得到一个其值最接近50的行.所以我想收到id:3(value = 51).

我怎样才能实现这个目标?

谢谢.



1> Alnitak..:

这应该工作:

SELECT * FROM table
ORDER BY ABS(? - value)
LIMIT 1

Where ?代表您要比较的值.


它显然会起作用,但是它实际上是在`log N`时间内优化的吗?

2> Tim Sylveste..:

使用order-by,SQLite将扫描整个表并将所有值加载到临时b树中以对它们进行排序,从而使任何索引无效.这将非常慢并且在大型表上使用大量内存:

explain query plan select * from 'table' order by abs(10 - value) limit 1;
0|0|0|SCAN TABLE table
0|0|0|USE TEMP B-TREE FOR ORDER BY

您可以使用索引获得下一个更低或更高的值,如下所示:

select min(value) from 'table' where x >= N;
select max(value) from 'table' where x <= N;

您可以使用union从单个查询中获取两者:

explain query plan 
        select min(value) from 'table' where value >= 10
  union select max(value) from 'table' where value <= 10;
1|0|0|SEARCH TABLE table USING COVERING INDEX value_index (value>?)
2|0|0|SEARCH TABLE table USING COVERING INDEX value_index (value

即使在大型桌子上,这也会非常快.您可以简单地加载这两个值并在代码中对它们进行评估,或者使用更多的sql以各种方式选择一个:

explain query plan select v from
   (      select min(value) as v from 'table' where value >= 10
    union select max(value) as v from 'table' where value <= 10)
  order by abs(10-v) limit 1;
2|0|0|SEARCH TABLE table USING COVERING INDEX value_index (value>?)
3|0|0|SEARCH TABLE table USING COVERING INDEX value_index (value

要么

explain query plan select 10+v from
   (      select min(value)-10 as v from 'table' where value >= 10
    union select max(value)-10 as v from 'table' where value <= 10)
  group by v having max(abs(v)) limit 1;
2|0|0|SEARCH TABLE table USING COVERING INDEX value_index (value>?)
3|0|0|SEARCH TABLE table USING COVERING INDEX value_index (value

由于您对任意大于和小于目标的值感兴趣,因此您无法避免进行两次索引搜索.但是,如果你知道目标在一个小范围内,你可以使用"between"来只触及一次索引:

explain query plan select * from 'table' where value between 9 and 11 order by abs(10-value) limit 1;
0|0|0|SEARCH TABLE table USING COVERING INDEX value_index (value>? AND value

当它仅评估1-2个值时,这将比上面的联合查询快2倍,但如果您开始加载更多数据,它将很快变慢.

推荐阅读
地之南_816
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有