<h1>550. Game Play Analysis IV</h1> 因為這題難度有點不對勁,所以我也把這題記錄下來 我是使用oracle,這題花了我3小時 不是這題很難,而是這題我覺得有陷阱在裡面 我原本是這樣寫的: <pre><code>SELECT ROUND( COUNT( DISTINCT A.player_id )/( SELECT COUNT( DISTINCT C.player_id ) FROM Activity C ) , 2 ) as fraction FROM Activity A JOIN Activity B ON A.player_id = B.player_id AND ( A.event_date + INTERVAL '1' DAY ) = B.event_date</code></pre> 用JOIN來將所有符合條件的tuple取出來,再用COUNT()算出符合條件的player_id有幾種,之後加上一個subquery在後面,得知玩家數量 這裡很有趣的地方是: 你把SELECT中兩個attribute分開取,兩邊都不會有問題,也能取出正確內容 但是兩個結合後,就會跳出: "ora-00937 not a single-group group function" 所以我在這邊卡了兩小時 後來之前用另一種寫法 也就是下面的程式碼 另一點是....我原本在算日期+1的時候使用DATEADD() 結果就是oracle又又又不提供該函數 我開始覺得oracle真的很...算了 一堆函數都沒辦法用 雖然oracle可以直接+1就好了,但是我覺得用函數表示會比較讓人理解 下面是我最後的寫法: first_login會取出player_id及最早登入的時間 使用first_login跟Activity做LEFT OUTER JOIN 這樣的話,我就可以知道所有玩家的數量,同時也可以知道符合條件的玩家數量 (因為COUNT()在指定欄位的狀況下不會把NULL算進去,所以所有在JOIN時不符合條件導致後面內容為NULL的tuple的都不會算進去) 順便講一下: COUNT( * )會顯示將所有資料的數量 COUNT( attribute_name )會顯示所有"該欄位非NULL"的資料的數量 COUNT( DISTINCT attribute_name )會顯示該欄位非NULL的種類數量(不重複) 我記得是這樣 <pre><code>WITH first_login as( SELECT player_id,MIN(event_date) AS event_date FROM Activity GROUP BY player_id ) SELECT ROUND( COUNT(b.player_id)/COUNT( DISTINCT A.player_id ) , 2 ) as fraction FROM Activity A LEFT OUTER JOIN first_login B ON A.player_id = B.player_id AND ( A.event_date - INTERVAL '1' DAY ) = B.event_date </code></pre>