SQLite SQL查询的麻烦

时间:2010-01-20 04:42:40

标签: sql sqlite pdo having

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

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

但是我收到以下错误:

  

SQLSTATE [HY000]:常规错误:1 a   之前需要GROUP BY子句   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;

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

4 个答案:

答案 0 :(得分: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;

答案 1 :(得分:1)

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

SELECT * FROM Locations WHERE abs(Latitude - 51.123)&lt; 0.12 AND abs(经度-0.123)&lt; 0.34按距离排序(纬度,经度,51.123,0.123)

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

答案 2 :(得分:-1)

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

你的group by查询是获取具有(“距离”&gt;)的记录,因为,有数据库规则首先它采用匹配记录的数据然后它将在它过滤记录之后执行group by有原因。所以你永远不会得到数据(“距离”&lt;)

如果我错了请更正

答案 3 :(得分:-3)

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

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