需要帮助理解与COUNT相关的HAVING子句

时间:2011-03-18 00:41:12

标签: mysql sql aggregate-functions

我开始学习sql,当我和COUNT一起使用时,我现在正忙于'having'子句。我做了很多研究,我的一般理解是,与查询中的任何函数运行之前等待应用的地方不同。

这让我找到了一个相当简洁的小功能,它允许我通过纬度和经度找到给定邮政编码的最近位置。我开始玩这个并用它把三张桌子绑在一起。一个包含邮政编码列表及其纬度经度,另一个包含事件列表及其邮政编码,最后一个列表包含每个事件的任何特殊要求。这三个事件表通过索引相互关联。纬度/经度表通过邮政编码绑定。

例如:

  SELECT `EVENT_CAT`,
         `NAME`,
         (3959 * acos(cos(radians(44.643418)) * cos(radians(`Latitude`)) * cos(radians(`Longitude`) - radians(-73.121685) ) + sin( radians(44.643418)) * sin(radians( `Latitude`)))) AS distance 
    FROM DATA_ZipCodes 
    JOIN `EVENT_POST_General` ON ZIP_CODE = ZipCode 
    JOIN `DATA_EVENTCategories` ON EVENT_CAT = DATA_EVENTCategories.ID 
    JOIN `EVENT_POST_Filtering` ON EVENT_POST_General.EVENT_ID = EVENT_POST_Filtering.EVENT_ID 
   WHERE `REQUIRE_TICKET` = '0' 
  HAVING distance < 10
ORDER BY distance

这很好用并且返回:

EVENT_CAT     NAME     DISTANCE
-------------------------------
1           CONCERT        1
1           CONCERT        1
1           CONCERT        1
2            GAMES         1
2            GAMES         2
3            DANCE         4
4           DINNER         4
5           MOVIES         4

问题是,我还希望能够只查询我所拥有的每类事件的数量。

为此,我尝试了加载COUNT和GROUP BY

  SELECT COUNT(`EVENT_CAT`),
         `NAME`,
         (3959 * acos(cos(radians(44.643418)) * cos(radians(`Latitude`)) * cos(radians(`Longitude`) - radians(-73.121685) ) + sin( radians(44.643418)) * sin(radians( `Latitude`)))) AS distance 
    FROM DATA_ZipCodes 
    JOIN `EVENT_POST_General` ON ZIP_CODE = ZipCode 
    JOIN `DATA_EVENTCategories` ON EVENT_CAT = DATA_EVENTCategories.ID 
    JOIN `EVENT_POST_Filtering` ON EVENT_POST_General.EVENT_ID = EVENT_POST_Filtering.EVENT_ID 
   WHERE `REQUIRE_TICKET` = '0'
GROUP BY `EVENT_CAT` 
  HAVING distance < 10
ORDER BY distance

当我这样做时,响应不会出错但它也不会返回任何内容。我对如何做到这一点感到非常困惑。我尝试移动组,但这只是导致错误。

*编辑以修正GROUP_BY到GROUP BY,因为当我在这里粘贴它并且不在原始代码中时它是一种类型:)

2 个答案:

答案 0 :(得分:1)

您的查询有点短路:

SELECT COUNT(`EVENT_CAT`),`NAME`, ... as `distance`
FROM ...
WHERE `REQUIRE_TICKET` = '0'
GROUP_BY `EVENT_CAT` 
HAVING distance < 10
ORDER BY distance

group by子句(我认为它也不应该有_)通过不同的event_cat结果对结果进行分组,统一其余的结果。但是:

  • 您的查询结果甚至不包含此类列。
  • 在每个组中,您尝试计算event_cat的不同值。只有一个,如果你愿意这样做。
  • 另外,结果的其他列不仅仅依赖于分组列...这不起作用。

having子句用于在分组后过滤生成的组。由于您的距离在每个组中都不是唯一的,因此这不是一个好方法 - 如果您想要计算每个类别中10公里距离内有多少事件,请将其改为WHERE子句。问题是您不能在WHERE子句中引用仅在SELECT子句中定义的字段,因此我们需要将公式放入WHERE子句中。

然后计算不同的name值(或其他唯一值),而不是event_cat

SELECT `EVENT_CAT`, COUNT(`NAME`)
FROM ...
WHERE `REQUIRE_TICKET` = '0' AND ... < 10
GROUP_BY `EVENT_CAT` 

按距离排序也是不可能的,因为距离并非按类别唯一。也许按计数或最小距离排序,或者这样?

答案 1 :(得分:0)

使用:

  SELECT dzc.name,
         COUNT(dzc.name),         
         (3959 * acos(cos(radians(44.643418)) * cos(radians(`Latitude`)) * cos(radians(`Longitude`) - radians(-73.121685) ) + sin( radians(44.643418)) * sin(radians( `Latitude`)))) AS distance 
    FROM DATA_ZipCodes dzc
    JOIN EVENT_POST_General epg ON epg.zip_code = dzc.zipcode
    JOIN DATA_EVENTCategories dec ON dec.id = dzc.event_cat
    JOIN EVENT_POST_Filtering epf ON epf.event_id = epg.event_id
   WHERE REQUIRE_TICKET = '0'
GROUP BY dzc.name
  HAVING distance < 10
ORDER BY distance