邁向大數據-Mysql group群內如何取特定資料

Mysql的Group功能最令人詬病,透過Group功能可以進行群組加總,但若要取出群組單筆資料時,都只能取得該群組最先建立的一筆資料,可是通常我們都需要取出群組最後一筆資料。雖然可以用php跑迴圈判斷處理,但這樣就會增加connect資料庫的次數,如果群組中取出的資料符合條件者才要處理,若群有100種,那每次都要跑100圈,萬一更多呢,啊~伺服器要擺工啦。

最終,能一次性在關聯性資料中取出目標資料還是最好的方式。

主要用到的手法,子查詢subquery和別名alias。在網路上會找到用BIAOMING GROU來解決,也行,但用起來彈性不大,且在某些版本的伺服器如5.7.17就沒作用。

容易失敗的因素

  • 資料表的別名(alias)
    只要有關聯式應用時,直接取用的表或subquery產出的表,養成習慣取別名(alias),或取alias方式所用的mysql伺服器並不接受
    適合較多伺服器版本的用法,SELECT 欄位 AS 別名,若是子查詢 (SELECT  ...) AS 別名
  • 欄位未指定所用的資料別別名
    只要有關聯式應用時,不論直接取用的表或subquery產出的表,養成習慣取別名(alias)。
    並指定取出欄位,盡量不要用*,以避色同樣欄位名的衝突,當欄名一樣時,系統沒辦法判斷你要依據那個表。
    指定取出所需欄位也可減輕暫存資料的佔用,可加快處理速度。

示範的資料表

    資料表 shareindex記錄全球各大股指每日指數記錄
    欄位如下
    id | sharename(指數名稱) | tradedate(交易日) | openI(開盤) | closeI(收盤) | maxI(盤中最高) | minI(盤中最低) | worker (記錄者) | modify (編輯時間).....(其他欄位)
    sharename指數名稱欄位內資料包含JP225、USDJ、UK100、DAX40、HK等
    這些指數只要非休市時每天都有一筆記錄。

取出每一指數最新一筆資料

    例如:要調出日經225、道瓊工指等最後一筆指數資料
  • 直接用GROUP無法取出最新的一筆
    SELECT * FROM shareindex GROUP BY sharename
    會取出每一個指數第1筆建立的資料。
    嗯,取出的不是最大值也不是最小值,總之不是所要的
  • 透過子查詢取出每種類型的最後一筆
    SELECT
       S1.*
    FROM
        (SELECT * FROM shareindex ORDER BY tradedate DESC) AS S1
    GROUP BY
       S1.sharename
    ORDER BY
       S1.sharename ASC
    先以子查詢按近自遠重新排序後,將最新的資料排在前方,再依子查詢產出的資料GROUP,即可取各指數出最新的一筆
  • 沒效?
    查一下所使用的mysql版本,如果是5.7以上,是因為不允許子句排序所造成的
    子句(SELECT * FROM shareindex ORDER BY tradedate DESC) AS S1
    要多加LIMIT才能實現子句排序。
    LIMIT就要有技巧了,要再加一些條件並計算好LIMIT後不會漏資料才行

延申應用 - 取出每一指數最高收盤的記錄

    例如:要調出日經225、道瓊工指等每一股市指數創造最高的收盤指數是在那一天,指數是多少
  • LEFT JOIN + 子查詢調用MAX
  • SELECT
       S1sharename,S1.tradedate,S1.openI,S2.maxIndex
    FROM
       shareindex AS S1
    LEFT JOIN
       (SELECT sharename,MAX(closeI) as maxIndex FROM shareindex GROUP BY sharename) AS S2
    ON
      S1.sharename=S2.sharename
    order by
       S1.sharename ASC
    可以取出每個指數,最高收盤的那筆資料
    不過會取出不必要使用的欄位資料,以及重覆的欄位名稱,若還要串聯其他資料表就可能會產生問題
    因為用*,因此每筆會抓出shareindex的所有欄位,以及子查詢產出的臨時表的欄位sharename和maxIndex
  • 將MAX換成MIN,就可取出各指數最低收盤的記錄
  • 可利用WHERE進一步條件篩選
  • 當然也可利用這樣的架框,進一步選取各指數當日最大盤差或單日最大漲幅之類。不過這又複雜一點,要結合多個子查詢,有空再另外記錄。


這個網誌中的熱門文章

沒印表機沒關係 便利商店找印去

被時代淘汱的英文怎麼說

探訪神秘的烏法魯神殿

色情廣告視窗關不掉? 動手解解看吧~

玩轉水晶石工作室 妝點個人部落