如何在 MySQL 中使用 GROUP By 和 HAVING
How to use GROUP By and HAVING in MySQL
前两个查询工作正常,第三个查询运行但在应该有结果时没有返回任何结果。我怎样才能得到第三个带回结果。在我看来 GROUP BY
和 HAVING
不能一起工作。
第二个查询 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
前两个查询工作正常,第三个查询运行但在应该有结果时没有返回任何结果。我怎样才能得到第三个带回结果。在我看来 GROUP BY
和 HAVING
不能一起工作。
第二个查询 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