2009-02-26 31 views
33

私の入力に正確に一致するレコードか、完全一致が見つからない場合に最も近いものを返すselect文を見つける必要があります。データベースに最も近い数値を見つける

これまでの選択文です。私は「エリア」欄に最も近いものを探してくださいされて行う必要があるので、私の入力は1.125で、データベースは2、1.5、1、0.5が含まれている場合、クエリは1を含むレコードを返します。何

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

私のSQLスキルは非常に限られていますので、どんな助力にも感謝します。

答えて

56

ので、常にポジティブ、そして注文昇順に絶対値を取り、あなたの入力し、[エリア]との差で注文についての最初の1

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

を取り、地域とご入力間の差を取得するには、以下のような:

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) 
0

MySQLの

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

恐ろしい何か使用している場合は、たぶん

ORDER BY ABS(Area - 1.125) ASC LIMIT 1 

:の線に沿って?

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

は - ABS()はほとんどすべてでサポートされていますが、それは(少なくともSQL99には)技術的には標準ではないということMarkusQ

1

注意。あなたは多くのNameに等価述語を満たす行、Size、およびPType列を持っている場合は

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 
2

:あなたには、いくつかの理由のためのANSI標準のSQLを記述する必要がある場合は、CASE演算子で問題を回避する必要があると思いますクエリ内のArea列に範囲述部を含めることができます。 Area列が索引付けされている場合、効率的な索引ベースのアクセスが可能になります。他の枝が最大Area <あなたのターゲットを持つレコードを見つけながら

(Oracle構文を使用して書かれた)次のクエリは、最小限のArea >=ターゲットでレコードを検索するUNION ALLの一方の枝を使用しています。これら2つのレコードのうちの1つが、探しているレコードになります。その後、ORDER BY ABS(Area - ?input)で2人の候補者の中から勝者を選ぶことができます。残念なことに、クエリは、ROWNUM/ORDER BY優先順位を強制するために必要なネストされたSELECTSのために複雑です。このクエリの

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 

良い指標は、予想クエリ実行プランは、それぞれ単一の行を返した2回の索引レンジ・スキャンに基づくものであろう場合に(Name, Size, PType, Area)、あろう。

-2

分を選択します。ここで、[フィールド]> your_target_value貢献しようとしているため、最大[フィールド] < your_target_value

+1

へようこそSOと感謝を選択 !しかし、あなたの答えを改善して役に立つものがいくつかあります。まず、マークアップが壊れています。コードブロックは4つのスペースでインデントする必要があります。[編集ヘルプ](http://stackoverflow.com/editing-help)を参照してください。これとは別に、コードのみの回答は一般的に理解しにくいので、説明は便利です。あなたの答えはSQL擬似コードであると言いますか、それを通常のSQLに書き直すのもいいでしょう。それでも、あなたの答えは有用であり、問​​題を編集した後、それは上向きになるかもしれません。 – Palec

関連する問題