【问题标题】:How to make sure HAVING happens before GROUP BY如何确保 HAVING 在 GROUP BY 之前发生
【发布时间】:2026-02-10 14:30:01
【问题描述】:

我正在获取距某个点一定距离的银行列表

ICBC                        6805    119.86727673154
Bank of Shanghai            7693    372.999006839511
Bank of Ningbo              7626    379.19406334356
ICBC                        6790    399.580754911156
Minsheng Bank               8102    485.904900718796
Standard Chartered Bank     8205    551.038506011767
Guangdong Development Bank  8048    563.713291030103
Bank of Shanghai            7688    575.327270234431
Bank of Nanjing             7622    622.249663674778

但是我只想抓住每个连锁店的 1 个场地。

到目前为止的查询

SELECT name, id , (
GLength( LineStringFromWKB( LineString( `lnglat` , POINT( 121.437478728836, 31.182877821277 ) ) ) )
) *95000 AS `distance`
FROM `banks` 
WHERE (
lnglat != ""
)
AND (
published =1
)
HAVING (
distance <700
)
ORDER BY `distance` ASC

按名称使用组不起作用,因为它评估然后距离不落入范围内。换句话说,如果有一个 ICBC 超过 700 m 并且具有较低的 id,那么即使两个 ICBC 在 700 m 以内,ICBC 也不会出现在结果中。所以我怀疑发生这种情况是因为group by 发生在having 之前
或者也许有不同的解决方案?

我无法将距离检查移到 where 因为它不是真正的列 #1054 - Unknown column 'distance' in 'where clause'

【问题讨论】:

  • HAVING 是在 GROUP BY 之后执行的。这正是它被发明的目的。如果你需要对结果集应用一些条件之前 GROUP BY你需要使用WHERE
  • 如果你的意思是`抓住每条链的1个场地`,那是指最近的一个吗?
  • @zerkms 但是距离列不存在。我还能如何在给定距离内找到动态的银行?在这种情况下 WHERE 不起作用?
  • @ace 最好,但不如一个重要
  • @Moak:将评估放在where 子句中

标签: mysql group-by having


【解决方案1】:

选择您的整个查询作为一个表格,然后在上面执行 Group By。

例如

Select * FROM 
(SELECT name, id , (
GLength( LineStringFromWKB( LineString( `lnglat` , POINT( 121.437478728836, 31.182877821277 ) ) ) )
) *95000 AS `distance`
FROM `banks` 
WHERE (
lnglat != ""
)
AND (
published =1
)
HAVING (
distance <700
)
ORDER BY `distance` ASC) t
GROUP BY t.name

【讨论】:

  • 是的,有没有 group by 的作品。我的原始查询没有分组依据。
  • @Moak:这没有任何意义 ;-) 你很幸运你使用的是 mysql,而不是另一个 mature dbms ;-)
  • 我不知道没有 group by。我仍然会尝试将距离移动到 where 子句。
  • 是的,我保持主查询不变只是为了确保它对你有用,但我同意 Balam 的观点,把它放在 WHERE 子句中。
  • @BalamBalam #1054 - Unknown column 'distance' in 'where clause' @ 这正是我的问题的答案。然后它会进行正确的检查,按名称分组。有用?为什么这是一件坏事?
【解决方案2】:

由于没有 GROUP BY 条件,您确定您的样本是完整的吗?如果您想要 700 英里内的银行,请将其置于 WHERE 状态。如果您只想报告 1 家银行,请将其放在 GROUP BY 中。您可能需要在 Group By 中重复 Glenght 而不是使用别名 - 取决于您的 SQL 版本。您不是从某个点抓取一定距离的银行列表 - 您是在抓取带有位置的银行并计算与某个点的距离。您只需要计算距离为 700 的银行,如果银行重复,您只希望它列出一次。

    SELECT name, id, (GLength( ...) AS [distance]
    FROM [banks] 
    WHERE [lnglat] != "" ... AND [distance] <700 
    Group By [name], [id], [distance] 
    ORDER BY [distance] ASC 

【讨论】:

  • 因为距离是动态计算的,它不会在 where 子句中注册 (#1054 - Unknown column 'distance' in 'where clause'),这就是为什么有工作,它会检查伪列
  • 对不起,我回答了 TSQL。我没有 MYSQL 来测试这个语法。如果没有 GROUP BY 或无法在 where 条件下放置距离,我只是无法获得 HAVING 工作。
【解决方案3】:

我不确定这是否是您要找的,只是找一家距离最短的银行。

SELECT banks.name, banks.id, banks_with_least_distance.distance
FROM banks JOIN
(
  SELECT name, min(
  GLength( LineStringFromWKB( LineString( `lnglat` , POINT( 121.437478728836, 31.182877821277 ) ) ) )
  *95000) AS `distance`
  FROM `banks` 
  WHERE (lnglat != "") AND (published =1) AND (GLength( LineStringFromWKB( LineString( `lnglat` , POINT( 121.437478728836, 31.182877821277 ) ) ) ) *95000 < 700)
  GROUP BY `name`
) AS banks_with_least_distance ON banks.name = banks_with_least_distance.name
ORDER BY banks_with_least_distance.distance DESC

已编辑:将 where 子句中的 distance 更改为实际公式。

【讨论】:

  • #1054 - Unknown column 'distance' in 'where clause'
最近更新 更多