在数据库中查找最接近的数值

时间:2009-02-26 20:07:10

标签: sql

我需要找到一个select语句,该语句将返回与我的输入完全匹配的记录,或者如果找不到完全匹配则返回最接近的匹配。

到目前为止,这是我的选择声明。

SELECT * FROM [myTable] 
WHERE Name = 'Test' AND Size = 2 AND PType = 'p' 
ORDER BY Area DESC

我需要做的是找到与'Area'字段最接近的匹配,所以如果我的输入是1.125并且数据库包含2,1.5,1和.5,则查询将返回包含1的记录。

我的SQL技能非常有限,所以任何帮助都会受到赞赏。

8 个答案:

答案 0 :(得分:65)

获取区域和输入之间的差异,取绝对值,使其始终为正,然后按顺序递增并取第一个

SELECT TOP 1 * FROM [myTable] 
WHERE Name = 'Test' and Size = 2 and PType = 'p'
ORDER BY ABS( Area - @input ) 

答案 1 :(得分:9)

可怕的事情,如下:

ORDER BY ABS( Area - 1.125 ) ASC LIMIT 1

也许?

答案 2 :(得分:4)

如果有许多行满足NameSizePType列上的等式谓词,那么您可能希望在Area列中包含范围谓词您的查询。如果对Area列编制索引,则可以实现基于索引的有效访问。

以下查询(使用Oracle语法编写)使用UNION ALL的一个分支查找目标最小Area >=的记录,而另一个分支查找最大Area <的记录你的目标。这两条记录中的一条将是您正在寻找的记录。然后你可以ORDER BY ABS(Area - ?input)从这两位候选人中挑选出胜利者。不幸的是,由于嵌套的SELECTS需要强制执行所需的ROWNUM / ORDER BY优先级,因此查询很复杂。

SELECT *
FROM
  (SELECT * FROM
    (SELECT * FROM
       (SELECT * FROM [myTable]
         WHERE Name = 'Test' AND Size = 2 AND PType = 'p' AND Area >= ?target
         ORDER BY Area)
       WHERE ROWNUM < 2
     UNION ALL
     SELECT * FROM 
       (SELECT * FROM [myTable]
         WHERE Name = 'Test' AND Size = 2 AND PType = 'p' AND Area < ?target
         ORDER BY Area DESC)
       WHERE ROWNUM < 2)
     ORDER BY ABS(Area - ?target))
WHERE rownum < 2

此查询的一个好索引是(Name, Size, PType, Area),在这种情况下,预期的查询执行计划将基于两个索引范围扫描,每个扫描返回一行。

答案 3 :(得分:3)

如何根据您的输入和[区域]之间的差异进行排序,例如:

DECLARE @InputValue DECIMAL(7, 3)

SET @InputValue = 1.125

SELECT TOP 1 * FROM [myTable]
WHERE Name = 'Test' AND Size = 2 AND PType = 'p'
ORDER BY ABS(@InputValue - Area)

答案 4 :(得分:3)

SELECT * 
  FROM [myTable] 
  WHERE Name = 'Test' AND Size = 2 AND PType = 'p' 
  ORDER BY ABS(Area - 1.125)
  LIMIT 1

- MarkusQ

答案 5 :(得分:1)

如果使用MySQL

SELECT * FROM [myTable] ... ORDER BY ABS(Area - SuppliedValue) LIMIT 1

答案 6 :(得分:1)

请注意,尽管几乎所有内容都支持ABS(),但它在技术上并不标准(至少在SQL99中)。如果由于某种原因必须编写ANSI标准SQL,则必须使用CASE运算符解决该问题:

SELECT * FROM myTable
WHERE Name='Test' AND Size=2 AND PType='p'
ORDER BY CASE Area>1.125 WHEN 1 THEN Area-1.125 ELSE 1.125-Area END

答案 7 :(得分:-1)

选择min [field]&gt; your_target_value 选择最大值[field]&lt; your_target_value