3

我正在尝试在 SQLite 3 中运行以下查询:

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

但我收到以下错误:

SQLSTATE[HY000]: 一般错误: 1 在 HAVING 之前需要一个 GROUP BY 子句

我不明白为什么 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;

相同的输出,返回所有记录。我已经仔细检查过 - 距离正在正确计算......我不知道这个查询有什么问题,有人可以帮我吗?

4

4 回答 4

2

HAVING没有指定子句就不能指定GROUP BY子句。采用:

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

如果您不想多次调用 DISTANCE,可以使用子查询:

  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;
于 2010-01-20T04:59:42.843 回答
1

更好(更快)的方法可能是在应用 ORDER BY 之前减少 SELECTed 集。我使用这种方法:

SELECT * 
FROM Locations 
WHERE abs(Latitude - 51.123) < 0.12 
AND abs(Longitude - 0.123) < 0.34 
ORDER BY DISTANCE(Latitude, Longitude, 51.123, 0.123)

...其中 (51.123, 0.123) 是您搜索的相对中心纬度/经度点,0.12 和 0.34 的值用于将您的搜索范围缩小到 lat/long square-on-a-a-sphere适当的大小(即地球球体上该点的 n 公里乘 n 公里的正方形,其大小取决于您所在位置的平均地理分布)。我使用来自http://en.wikipedia.org/wiki/Longitude的度数长度公式来计算这些值应该被赋予搜索点在地球球体上的位置。

于 2010-01-20T22:03:50.340 回答
-1

这是语法错误,当你使用有原因时,你必须使用'group by',

您使用 group by 的查询正在获取具有 ("distance" >) 的记录,因为有一个数据库规则,首先它获取具有匹配记录的数据,然后它会在它通过有原因过滤记录之后对其执行 group by。所以你永远不会得到具有 ("distance" <) 的数据

如果我错了,请纠正

于 2010-01-20T04:49:12.370 回答
-3

除了上面的正确标记答案之外,如果您不想调用 DISTANCE 函数两次,请参阅 WHERE 子句中的别名,即:

 SELECT *, 
         DISTANCE(latitude, longitude, ?, ?) AS dist
    FROM COUNTRY c
   WHERE c.id NOT LIKE ?
     AND dist <= ?
ORDER BY dist;
于 2010-02-22T15:00:47.650 回答