<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>