2017-07-19 18 views
0

私は、リクエストしたユーザのために半径内のすべてのユーザを取得しようとしていました。緯度と経度を格納するgps(ジオメトリタイプ)を作成しました。PostgreSQLは特定の半径でユーザを取得します

私はこのコードを使用しました:

SELECT * From UserAddresses 
WHERE ST_DWithin(
    (Select gps 
    from useraddresses 
    where ID=(Select UserAddressID 
       FROM Users WHERE ID=1)), 
    (Select gps 
    from useraddresses 
    WHERE ID IN (SELECT UserAddressID 
       FROM Users 
       WHERE ID!=1)), 
    1609*(Select DiscoveryDistance 
      From Users 
      WHERE ID=1),true) 

を、それはこのエラーを返します。

ERROR: more than one row returned by a subquery used as an expression

は、私はこのエラーがSELECT UserAddressID FROM Users WHERE ID!=1部分から来ることを知っているが、私はそれを固定されていませんでした。

私がしたいことは、GPSID=1をすべてのユーザーと比較し、半径内にいる場合はそのデータを取得することです。

誰でも私の構文を助けることができますか?

答えて

0

条件をサブクエリの外に移動することができます。 ST_DWithinは一度に(各ジオメトリに対して)1行で動作するため、サブクエリを使用する場合は1行だけを返す必要があり、おそらく1つ以上のID!=1行が返されます。

SELECT targetAdr.* 
From UserAddresses srcAdr, 
    UserAddresses targetAdr 
WHERE srcAdr.ID=(Select UserAddressID 
       FROM Users 
       WHERE ID=1) 
AND targetAdr.ID IN (SELECT UserAddressID 
        FROM Users 
        WHERE ID!=1) 
AND ST_DWithin(srcAdr.gps, 
       targetAdr.gps, 
       1609*srcAdr.DiscoveryDistance, 
       true); 

あなたがあるAddressIdを割り当てる方法に応じて、それは単に代わりに、おそらく巨大なIN句を行うと、targetAdr.ID != srcAdr.IDするはるかに効率的であるかもしれないことに注意してください。

0

私はあなたがメトリックSRIDでジオメトリタイプとしてあなたの「GPS」の列を持っているか、あなたは4326を使用している場合、あなたは地理タイプ

SELECT * 
    FROM UserAddresses ua1 
WHERE EXISTS (SELECT FROM users u1, UserAddresses ua2, users u2 
       WHERE u2.id=1 
        AND u1.id<>u2.id 
        AND u1.useraddressid=ua1.id 
        AND u2.useraddressid=ua2.id 
        AND st_DWithin(ua2.gps, ua1.gps, u2.DiscoveryDistance*1609)) 

は、GiSTインデックスとインデックスのGPS欄に覚えていていることを前提としています。

関連する問題