我尝试从我的数据库中返回一个地图项目列表,仅在群组数量大于4的情况下对这些项目进行分组,否则我不希望将这些项目分组。
我的项目是为了返回设定区域内的所有条目而构建的,我将使用分组将该区域分解为网格。如果网格中的每个单元格都有太多结果,那么我将显示一个组标记,其中包含组计数而不是单个条目标记。
我当前的查询用于确定COUNT(*)
是否存在分组项目SELECT *, COUNT(*) as groupCount, floor(longitude/0.0007) AS groupLong, floor(latitude/0.0007) AS groupLat
FROM items
WHERE longitude>=151.1
AND longitude<=151.2
AND latitude>=-33.9
AND latitude<=-33.8
GROUP BY floor(longitude/0.0007), floor(latitude/0.0007)
我想要做的只是如果小组计数&gt;对项目进行分组4,组&lt; = 4中的项目将作为未组合项目返回。
我知道我可以使用HAVING COUNT(*)>4
仅返回5及以上的组,但是我该怎么做才能返回4组及以下组中的未组合项目?
我很乐意做两个查询来获得结果,但如果有一种方法可以在一个方法中完成,那就太棒了!
答案 0 :(得分:2)
这是我解决方案的SQL小提琴:http://sqlfiddle.com/#!8/e40ba/1
这个想法首先要弄清楚组是什么,这是在子查询grouping
中完成的。然后我们将这些组连接到原始表,但是我们使用左外连接,因此组中的任何值都不会为分组列提供空值。最后,我们使用AVG
为该组提供代表性坐标。对于未分组的值,这将是坐标本身,这很好。
我建议不要在没有做一些测试和基准测试的情况下实际使用它。如果items
很大,那么加入可能会很糟糕。我真的只是想在一个查询中找到一种方法。正如我在评论中所说,正确的方法是使用窗口函数,但MySQL没有这些。
SELECT AVG(longitude) AS longitude
, AVG(latitude) AS latitude
, COUNT(*) AS count
FROM items
LEFT OUTER JOIN
( SELECT COUNT(*) AS group_count
, FLOOR(longitude/0.0007) AS group_longitude
, FLOOR(latitude/0.0007) AS group_latitude
FROM items
-- Repeat the filter to avoid computing unnecessary groups
WHERE longitude >= 151.1
AND longitude <= 151.2
AND latitude >= -33.9
AND latitude <= -33.8
GROUP BY group_longitude, group_latitude
HAVING group_count > 4
) AS grouping
-- Match each row up with its group
ON FLOOR(longitude/0.0007) = group_longitude
AND FLOOR(latitude/0.0007) = group_latitude
WHERE longitude >= 151.1
AND longitude <= 151.2
AND latitude >= -33.9
AND latitude <= -33.8
GROUP BY COALESCE(group_longitude, id)
, COALESCE(group_latitude, id)
答案 1 :(得分:1)
我认为你可以使用union两个子查询结果来解决这个问题。也许你可以通过划分两部分来使用subselect,第一部分得到COUNT(*)&gt; 4条件结果,第二部分得到其他items.id然后检索所有其他项目。