1

現在、場所の表から選択しようとしています。結果は、最も近い場所であり、さらに少なくとも 30 km 離れた場所である必要があります。

だから私はやろうとしています

SELECT * FROM locations WHERE (distance = minimumdistance OR distance > 30) AND some other parameters LIMIT 2

しかし、ステートメントを非常に長くする他のすべてのパラメーターも含む2番目の選択なしでは、最小距離を取得できません。

MIN(距離) にはグループ化が必要ですが、その結果、2 つではなく 1 つの結果しか得られません...

これをもっと簡単に行う方法はありますか?ステートメント内で完全な WHERE 句を 2 回使用せずにステートメントを作成します。

現在は

SELECT * FROM locations WHERE (distance = (SELECT MIN(distance) FROM locations WHERE some other parameters ) OR distance > 30) AND some other parameters LIMIT 2

ここで、他のいくつかのパラメーターがかなり長い文字列であり、距離が静的なテーブル列ではなく計算であると想像してみてください。これはかなり厄介になります。

4

4 に答える 4

2

1つのクエリでそれを行うことを主張する場合、これは必要に応じて行われます(より標準的に更新されます)

SELECT

        -- this will have 2 records, 1 nearest and 1 with l.distance > 30
        d.*
FROM (
    SELECT 
        loc.*,
        -- this assumes locationID == the PK field, update as needed
        IF(loc.distance>30,@farLoc := loc.locationID,@nearLoc := loc.locationID) AS ignoreMe
    FROM locations AS loc,
    (
        SELECT @nearLoc := 0,@farLoc := 0
    ) AS v
    WHERE some other parameters
    ORDER BY loc.distance DESC 
) AS d
WHERE d.locationID IN (@nearLoc,@farLoc)

しかし、本当に単純なユニオンは、このインスタンスで使用する必要があることを行います

(
    SELECT * FROM locations 
    WHERE some other parameters
    ORDER BY distance ASC 
    LIMIT 1
) UNION (
    SELECT * FROM locations 
    WHERE some other parameters
    AND distance > 30 
    ORDER BY distance ASC 
    LIMIT 1
)

効率的である限り、ステートメントが「非常に長い」かどうかは問題ではありません。他のパラメーターがスクリプト内で生成される場合、維持する余分なオーバーヘッドはなく、これが最も効率的な方法になります。

于 2013-03-28T13:09:15.487 に答える
1

あなたはこれを試すことができます

    SELECT * FROM locations WHERE  some other parameters 
    HAVING  distance > 30
    OR distance = minimumdistance 
    LIMIT 2
于 2013-03-28T13:04:43.633 に答える
0

私はこの方法に興奮していませんが、MySQL で動作するはずです:

select l.*
from (SELECT l.*, (@rn = @rn+1) as rn
      FROM locations l cross join
           (select @rn = 0)
      WHERE some other parameters
      order by distance
     ) l
where rn = 1 or distance > 30
limit 2

@rn は、行番号を追跡する変数です。他のほとんどのデータベースでは を使用しますがrow_number()、MySQL ではサポートされていません。次に、最初の行 (最小距離) または 30 より大きい行を選択します。最小距離が 30 より大きい場合は、2 つの行が得られます。

実際には、30 未満で最も近いものを返します。

于 2013-03-28T13:40:04.403 に答える
0

The result should be the closest location and additionally a location that is at least 30km distance away

これはmySQLで機能しますか? SQLite で動作します。

     select min(distance) from foo
     where distance > (select min(distance) from foo) and distance > 30
     union 
     select min(distance) from foo 

それが機能する場合は、それを使用してインライン ビューを作成し、これを行うことができます。

     select name, min(dist) from
     (

     select name, dist
     from   foo
     join
     (
     select min(distance) as dist from foo 
     where distance > (select min(distance) from foo) and distance > 30
     union 
     select min(distance) as dist from foo  
     ) as X         
     on foo.distance = X.dist   

   )

   union

    select name, max(dist) from

    (

     select name, dist
     from   foo
     join
     (
     select min(distance) as dist from foo 
     where distance > (select min(distance) from foo) and distance > 30
     union 
     select min(distance) as dist from foo  
     ) as X         
     on foo.distance = X.dist   

   )

列 [距離] のインデックスを使用すると、これは非常に高速になります。

于 2013-03-28T13:42:57.240 に答える