最近又遇到了一個需求(每次都是用這個開頭,感受本身都膩了-_-||),是根據已有的牌局記錄表統計概括出天天每一個玩家在每一個遊戲上面進行的局數。首先牌局記錄表的結構大體以下:sql
其中log_date表示當局日期,game_id表示當局屬於哪一個遊戲,points是一個json類型的值,裏面記錄着參與這局遊戲的玩家信息與得分狀況,現有的原始數據以下:json
由於points是一個json數組,裏面保存着用戶的得分和user_id這些信息,所以能夠考慮把points變爲多行來實現分離每一個user_id的效果,如圖所示:數組
把每一個user_id都分離以後就能夠利用窗口函數統計每一個user_id對應的局數了,SQL語句以下:函數
SELECT game_id, user_id, SUM (COUNT(*)) OVER (PARTITION BY game_id, user_id) AS round_count FROM ( SELECT log_date, game_id, ( json_array_elements (points :: json) ->> 'user_id' ) AS user_id FROM game_record ) AS A GROUP BY game_id, user_id;
其中,over字句使得sum(count(*))函數被看成一個窗口函數處理,並在game_id,user_id都相等的行集上進行計算,得出局數,結果以下:.net
//-------------------------------------------分割線2018-07-31-----------------------------------------------code
下方評論區有大神提到能夠不用窗口函數,在此要感謝大神redraiment提醒了我。當時的想法是剛學了窗口函數,還不會用,因此想實踐一下,因此纔用到這裏的,其實更簡單的方法就是大神所說,直接group by分組就好了,SQL代碼以下。(果真不能爲了用新知識而用新知識,仍是得按部就班,不能一口氣吃成個胖子啊@-@)blog
SELECT game_id, user_id, count(*) FROM ( SELECT log_date, game_id, ( json_array_elements (points :: json) ->> 'user_id' ) AS user_id FROM game_record ) AS A GROUP BY game_id, user_id;