2017-07-19 60 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一部分,但我不能固定它。

我想要做的就是將ID=1GPS與所有用戶進行比較,如果他們在半徑中獲取他們的數據。

任何人都可以幫助我的語法?

回答

0

您可以將您的條件移到子查詢之外。 ST_DWithin一次對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,它可能是更有效簡單地做,targetAdr.ID != srcAdr.ID而不是可能出現巨大的IN條款。

0

我假設你有你的「GPS」列,幾何類型公制SRID或者如果你使用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)) 

記住索引列GPS的GIST指數。