2010-01-20 66 views
2

我試圖運行的SQLite 3以下查詢:故障使用SQLite SQL查詢

SELECT *, 
    DISTANCE(latitude, longitude, ?, ?) AS "distance" 
FROM "country" 
WHERE "id" NOT LIKE ? 
HAVING "distance" <= ? 
ORDER BY "distance" ASC; 

,但我得到了以下錯誤:

SQLSTATE[HY000]: General error: 1 a GROUP BY clause is required before HAVING

我不明白爲什麼要的SQLite我組的結果,但我仍然嘗試了以下內容:

SELECT *, 
    DISTANCE(latitude, longitude, ?, ?) AS "distance" 
FROM "country" 
WHERE "id" NOT LIKE ? 
GROUP BY "id" 
HAVING "distance" <= ? 
ORDER BY "distance" ASC; 

而且我也試過這樣:

SELECT *, 
    DISTANCE(latitude, longitude, ?, ?) AS "distance" 
FROM "country" 
WHERE "id" NOT LIKE ? 
GROUP BY "distance" 
HAVING "distance" <= ? 
ORDER BY "distance" ASC; 

沒有錯誤,但所有記錄都被返回(即使是那些有"distance" > ?)。我也試過:

SELECT *, 
    DISTANCE(latitude, longitude, ?, ?) AS "distance" 
FROM "country" 
WHERE "id" NOT LIKE ? 
    AND "distance" <= ? 
ORDER BY "distance" ASC; 

同樣的輸出,所有的記錄都被返回。我已經加倍檢查 - 距離正確計算...我不知道這個查詢有什麼問題,有人可以幫我嗎?

回答

2

,而不必指定GROUP BY子句您不能指定HAVING條款。用途:

SELECT *, 
     DISTANCE(latitude, longitude, ?, ?) AS dist 
    FROM COUNTRY c 
    WHERE c.id NOT LIKE ? 
    AND DISTANCE(c.latitude, c.longitude, ?, ?) <= ? 
ORDER BY dist; 

如果您不想打電話距離超過一次,你可以使用子查詢:

SELECT x.* 
    FROM (SELECT c.*, 
       DISTANCE(latitude, longitude, ?, ?) AS dist 
      FROM COUNTRY c 
      WHERE c.id NOT LIKE ?) x 
    WHERE x.dist <= ? 
ORDER BY dist; 
+0

但我曾嘗試指定一個「GROUP BY」子句......有沒有什麼辦法可以運行查詢,而無需調用兩次'DISTANCE'函數?這會使查詢運行速度更快。 – 2010-01-20 05:03:27

+0

Hummm ...我不是嵌套查詢的忠實粉絲,http://www.arubin.org/files/geo_search.pdf的第8頁更直截了當。 MySQL手冊(http://dev.mysql.com/doc/refman/5.0/en/group-by-hidden-columns.html)說:「SQL標準不允許HAVING子句命名任何未找到的列在GROUP BY子句中,如果它不包含在聚合函數中「。這是SQLite的特定?對不起,成爲一個PITA,但有任何其他方式來解決這個問題? – 2010-01-20 05:14:00

+0

@Alix:沒有任何其他選項可以最大限度地減少使用「DISTANCE」的次數。 DISTANCE不是一個聚合函數,所以比較屬於'WHERE'子句。使用'HAVING'的唯一原因是因爲你實際上是將記錄分組 - 這對於一個國家的表來說不太可能。 – 2010-01-20 05:23:34

0

是語法錯誤,你必須有「按組」,當你使用具有事業使用,

您與組查詢的是獲取有記錄(「距離」>),因爲,有數據庫規則首先它需要具有匹配記錄的數據,然後在它通過有原因過濾記錄之後它將執行分組。所以你永遠不會有數據(「距離」 <)

請糾正,如果我錯

+0

謝謝,我不知道。有什麼方法可以重寫查詢,以便它只返回具有'distance <=?'的記錄,而不必調用兩次'DISTANCE'函數? – 2010-01-20 05:07:30

1

一個更好的(和更快)的方式可能是減少停機選定的一組在應用ORDER BY之前。我用這樣的方法:

SELECT * FROM位置WHERE ABS(緯度 - 51.123)< 0.12和ABS(經度 - 0.123)< 0.34 ORDER BY DISTANCE(緯度,經度51.123,0.123)

。 ..其中(51.123,0.123)是您正在搜索的中心緯度/經度點,0.12和0.34的值用於將搜索範圍縮小爲一個經緯度的經緯度適當的大小(即在地球球面上的那個點上的n公里乘以n的平方,其大小取決於你的位置的平均地理分佈)。我使用http://en.wikipedia.org/wiki/Longitude的度數長度公式來計算出這些值應該賦予搜索點在地球球面上的位置。

+0

謝謝。我這樣做,我只是沒有發佈,以避免添加太多混亂。 =) – 2010-01-20 22:06:37

-2

而且正確的標記回答上面的,如果你不想調用距離函數兩次,請參閱別名WHERE子句中,即:

SELECT *, 
     DISTANCE(latitude, longitude, ?, ?) AS dist 
    FROM COUNTRY c 
    WHERE c.id NOT LIKE ? 
    AND dist <= ? 
ORDER BY dist; 
+0

看看我的問題的最後一個代碼片段... – 2010-02-22 19:49:22