【发布时间】:2017-02-04 10:06:39
【问题描述】:
我想模糊搜索十进制数字而不是字符串。所以这个想法是搜索 100 应该从数据库中的行中带来 100、90、95、105、108、120 的数值范围。
我也尝试过 like 关键字,但它没有按我的意愿工作。如何对小数进行模糊搜索。谢谢
【问题讨论】:
-
您如何认为 100 和 90 之间的模糊匹配正确?为什么不指定下限和上限?
标签: sql postgresql fuzzy-search
我想模糊搜索十进制数字而不是字符串。所以这个想法是搜索 100 应该从数据库中的行中带来 100、90、95、105、108、120 的数值范围。
我也尝试过 like 关键字,但它没有按我的意愿工作。如何对小数进行模糊搜索。谢谢
【问题讨论】:
标签: sql postgresql fuzzy-search
使用between。函数是一个例子:
create or replace function fuzzy_match_numeric
(number numeric, value numeric, deviation numeric)
returns boolean language sql as $$
select number between value- value* deviation and value+ value* deviation
$$;
检查是否匹配值 100 与 5% 的偏差:
select
fuzzy_match_numeric(94, 100, .05) r1,
fuzzy_match_numeric(95, 100, .05) r2,
fuzzy_match_numeric(105, 100, .05) r3,
fuzzy_match_numeric(106, 100, .05) r4
r1 | r2 | r3 | r4
----+----+----+----
f | t | t | f
(1 row)
【讨论】:
我建议为您的查找值集计算偏差并选择最佳候选者。下面是一个基于整数的示例,但数值类型的工作方式类似。
示例数据集:search_table
postgres=# select * from search_table order by 1;
value
-------
90
95
100
101
103
105
108
120
示例查找值集:search_condition
postgres=# select * from search_condition order by 1;
value
-------
100
103
105
寻找最佳人选:
select
distinct on (value)
value,
lookup_value as best_candidate
from (
select
st.value,
sc.value as lookup_value,
abs(1 - st.value*1.0/sc.value) as deviation
from search_table st
cross join search_condition sc
) t
order by value, deviation, best_candidate;
结果:
value | best_candidate
-------+----------------
90 | 100
95 | 100
100 | 100
101 | 100
103 | 103
105 | 105
108 | 105
120 | 105
如果出现平局,将选择较低的候选人。这可以通过在ORDER BY 子句中的best_candidate 列中添加DESC 来修改,以获取最高候选。
【讨论】: