2015-01-14 17 views
3

我試圖從我的數據庫分組項目只返回一個地圖項列表,如果組數大於4,否則我不想要分組的項目。組如果COUNT(*)> X,否則不分組項目

我的項目是爲返回設置區域內的所有條目而構建的,我將使用分組將該區域分解爲網格。如果網格中的每個單元格的結果太多,那麼我將使用組計數顯示組標記,而不是單個輸入標記。

我目前的查詢工作,以確定是否存在由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) 

我想這樣做的唯一一組分組的項目中的項目,如果組數> 4個項目的組中< = 4將作爲未分組項目返回。

我知道我可以使用HAVING COUNT(*)>4只返回5個和5個以上的組,但是我能做些什麼來返回4個和4個以下的組中的未分組項?

我會很樂意做兩個查詢來獲得結果,但如果有一種方法在一個這樣做,那將是偉大的!

+0

如果您有切換數據庫引擎的選項,這將是一個很好的窗口函數用例。 MySQL不支持它們(我可以找到),但PostgreSQL卻支持它們。 –

回答

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) 
+0

真的很棒。就我而言,在數百萬行中,無條件分組是80ms,條件(此策略)約爲160ms。所以不要超快 – atomkirk

1

我想你可以使用union兩個子查詢結果來解決這個問題。也許你可以通過劃分兩部分來使用子查詢,第一部分得到COUNT(*)> 4條件結果,第二部分得到其他items.id然後檢索所有其他項目。