我有一个包含很多值的数据库表,如:340.13和232.89。
现在我想选择与比较值最匹配的值。
这可能不费吹灰之力吗?
答案 0 :(得分:1)
这将匹配搜索值的+ -10%范围内的值,如果有多个值,则会通过绝对差异找到最接近的匹配。
Oracle 11g R2架构设置:
var die1:uint = Math.floor(Math.random() * 6) + 1;
var die2:uint = Math.floor(Math.random() * 6) + 1;
查询1 :
CREATE TABLE TABLE_NAME ( VALUE ) AS
SELECT 340.13 FROM DUAL UNION ALL
SELECT 232.89 FROM DUAL UNION ALL
SELECT 224.73 FROM DUAL UNION ALL
SELECT 100.00 FROM DUAL;
<强> SQL Fiddle 强>:
WITH search_values ( search_value ) AS (
SELECT 330 FROM DUAL UNION ALL
SELECT 230 FROM DUAL
)
SELECT search_value,
value
FROM (
SELECT search_value,
value,
RANK() OVER ( PARTITION BY Search_value
ORDER BY ABS( value - search_value ) ) AS rnk
FROM table_name t
INNER JOIN
search_values v
ON ( t.value BETWEEN search_value * 0.9 AND search_value * 1.1 )
)
WHERE Rnk = 1
答案 1 :(得分:0)
这是一个非常基本和常见的任务,所以这是一般方法。
首先,你需要决定“最佳匹配标准”。基本上它作为存储在行和输入值中的值的函数。因此,您可以实现此功能并评估它为每行调用类似MATCH_RATING(COLUMN, :value)
的内容。现在您对每一行都有评级,您可以按照自己喜欢的方式对行进行排序并过滤最合适的行(ROWNUM
对此非常有用,因为{{1}等分析函数}或RANK
)。
ROW_NUMBER
然后一个好主意是检查你选择的标准是否用语言实现,因为如果它们是,那么使用SQL功能肯定会在性能方面更好。
例如,如果两个数字之间的距离是唯一与您有关的事情,那么SQL将看起来像这样。
SELECT *
FROM (
SELECT VALUE,
MATCH_RATING(VALUE, :input_value) RATING
FROM YOUR_TABLE
ORDER BY RATING DESC)
WHERE ROWNUM = 1
如果你的函数在某个时间间隔内假设0值,这意味着某些行永远不会进入你的结果集,那么你也应该使用SELECT VALUE
FROM (
SELECT VALUE,
ABS(VALUE - :input_value) DISTANCE
FROM YOUR_TABLE
ORDER BY DISTANCE)
WHERE ROWNUM = 1
子句过滤无用的行(WHERE
)。
回到我们的距离示例:让接受距离不超过输入值的5%。
WHERE MATCH_RATING(COLUMN, :value) > 0
顺便说一句,SELECT VALUE
FROM (
SELECT VALUE,
ABS(VALUE - :input_value) DISTANCE
FROM YOUR_TABLE
WHERE VALUE BETWEEN 0.95 * :input_value AND 1.05 * :input_value
ORDER BY DISTANCE)
WHERE ROWNUM = 1
上的索引肯定会对此示例有所帮助。