如何在 MySQL 中使用 GROUP By 和 HAVING

How to use GROUP By and HAVING in MySQL

前两个查询工作正常,第三个查询运行但在应该有结果时没有返回任何结果。我怎样才能得到第三个带回结果。在我看来 GROUP BYHAVING 不能一起工作。

第二个查询 returns 32 Active Status 和 7 Pending Status,所以第三个查询应该 return 第二个查询的摘要,但它不是。

SELECT COUNT(DISTINCT MLSNumber) AS TOTAL, `Status`
FROM Residential 
WHERE PropertyType='Single Family' AND Status IN ("Active", "Pending")  
GROUP BY `Status`;

SELECT MLSNumber, `Status`, 
( 3959 * acos( cos( radians(21.380936) ) * cos( radians( Latitude ) ) 
 * cos( radians( Longitude ) - radians(-157.757438) ) + sin( radians(21.380936) ) 
 * sin(radians(Latitude)) ) ) AS distance 
FROM Residential 
WHERE PropertyType='Single Family' AND Status IN ("Active", "Pending")  
HAVING distance < 2;

SELECT COUNT(DISTINCT MLSNumber) AS TOTAL, `Status`, 
( 3959 * acos( cos( radians(21.380936) ) * cos( radians( Latitude ) ) 
 * cos( radians( Longitude ) - radians(-157.757438) ) + sin( radians(21.380936) ) 
 * sin(radians(Latitude)) ) ) AS distance 
FROM Residential 
WHERE PropertyType='Single Family' AND Status IN ("Active", "Pending")  
GROUP BY `Status`
HAVING distance < 2;

您不能在此示例中使用 HAVING,因为该子句用于 specifying conditions on aggregate columns

在您的示例中,距离不是聚合列,而是针对每一行计算的列,因此如果您想查找距离小于两行的行,您应该使用 WHERE 子句。但是,我不确定您是否希望在这种情况下进行分组,因为距离看起来适用于单独的行,而不适用于组。

这些示例中唯一属于 HAVING 的列是您的计数函数。

我假设 #3 的目标是找到 2 英里内 MLS 条目的总数。

您遇到的问题是,通过在最终查询中按 Status 分组,您首先应用了它,然后才对纬度和经度进行计算。因此,每个 Status 分组只计算一个记录的纬度和经度。

尝试将查询 #2 包装在另一个按状态分组的 select 中:

  SELECT COUNT(DISTINCT i.MLSNumber) AS TOTAL, i.Status FROM 
    ( SELECT MLSNumber, `Status`, 
         ( 3959 * acos( cos( radians(21.380936) ) * cos( radians( Latitude ) ) *    cos( radians( Longitude ) - radians(-157.757438) ) + sin( radians(21.380936) ) * sin(radians(Latitude)) ) ) AS distance 
     FROM Residential 
     WHERE PropertyType='Single Family' AND Status IN ("Active", "Pending")  
     HAVING distance < 2) as i  Group by Status

您可能需要稍微调整一下查询,但这就是要点——我没有您要试验的架构。

此外,正如您之前对 post 的评论所指出的,您可以放弃 HAVING 并只使用 where 因为您没有分组。

当您使用 GROUP BY 时,您需要对 GROUP BY 子句中未包含的所有字段使用聚合函数。

我认为您想要的是将计算出的距离作为 where 子句的一部分并去掉 HAVING 子句。

WHERE PropertyType='Single Family' AND Status IN ("Active", "Pending")  
    AND ( 3959 * acos( cos( radians(21.380936) ) * cos( radians( Latitude ) ) * cos( radians( Longitude ) - radians(-157.757438) ) + sin( radians(21.380936) ) * sin(radians(Latitude)) ) ) < 2