2013-05-17 215 views
2

今天,我需要你的幫助。如何在SQL中執行此操作?

我有一個統計網站,我從遊戲Web服務獲取數據。 我想實現一個新的功能,但我不知道如何。

我想猜猜玩家的連線時間。

我有一個腳本,每小時收集一次數據並將這些數據存儲在一個表中。 想象一下,我有一個表:player_id,分數和小時(整數,只是H),以及月份的天數。

然後,例如,如果小時17和18之間的分數不同,則玩家已連接到他的帳戶。

爲了簡化,假設我有一張桌子,每天的日子從1到31,小時從0到23。

在本月末,我需要執行一個查詢來計算每小時的玩家在此小時內連接的天數。

Example : 

0 => 31  The player has been connected between 23 and 0 : every days 
1 => 3  The player has been connected between 0 and 1 : 3 days a month 
2 => 5  The player has been connected between 1 and 2 : 5 days a month 
3 => 10  The player has been connected between 3 and 4 : 10 days a month 
... 
23 => 4 

我想我可以ORDER BY天,從每小時0 1日時和player_id以每小時23 31天,做第一個與像一個情況下,選擇:

SELECT 
    table.*, 
    (CASE WHEN ACTUAL_ROW.score!=PREVIOUS_ROW.score THEN 1 ELSE 0) AS active 
FROM table 

知道每個如果播放器已連接,則爲行。 然後很簡單,每個小時做一個GROUP BY和一個SUM。 但我不知道如何才能比較以前的行

你有任何想法或提示如何做到這一點? PL/SQL更好地做到這一點?

注:我使用PostgreSQL

感謝

+1

您是否考慮過執行多個簡單的SELECT語句,然後以編程方式在數據庫之外處理結果? – SunSparc

+1

有點問題,如果17至18小時之間的分數不同,那麼玩家已經連接到他的賬戶。但是,如果分數相同,他不一定與他的賬戶沒有關係。數據收集腳本的工作原理是什麼? –

+0

@SunSparc從** data **庫中卸載數據處理不是最好的想法。 Postgres有足夠的工具來做這種唱歌。你只需要學習如何使用這些工具。 –

回答

3

您可以LAG窗函數訪問表的上一行。使用類似

SELECT player_id, count(CASE WHEN score > prev_score THEN 1 END) 
FROM(
SELECT player_id, score, mm, hh, LAG(score) OVER (ORDER BY mm,hh) as prev_score 
FROM your_table) 
GROUP BY player_id 

另外提醒

嘗試 - 存儲完整的時間戳,而不是日期和時刻領域。你可以隨時使用函數獲取時間戳中的日期和時間。

手冊上的窗函數:onetwo

+0

感謝您的幫助 Thoses窗口函數似乎非常有趣。 – Alkalyne

0

這裏的問題是,當玩家「已連接」 而是當玩家「獲得的積分」我們不檢查,這可能是類似的 - 或不; ,每隔一小時(一小時內登錄三次)。 同樣,一名玩家只剩下三個小時的記錄並且在該期間累積積分將導致「記錄」一個,兩個或三個數據點,具體取決於。

有了這些告誡,我們可以用自己的JOIN評分表:

SELECT a.player_id, a.day, a.hour, a.score - b.score AS chg 
    FROM cdata AS a 
    JOIN cdata AS b 
    ON (
     (a.player_id = b.player_id AND a.score != b.score) 
    AND (
     (a.hour > 0 AND a.day = b.day AND b.hour = a.hour-1) 
     OR 
     (a.hour = 0 AND a.day = b.day+1 AND b.hour = 23) 
     ) 
    ) 

,當他 比分改寫這將產生一系列的統計數據對於用戶來說,白天和小時。

您可以在收集子查詢

SELECT player_id, hour, COUNT(player_id) FROM (...) AS changes 
    GROUP BY player_id, hour 
    ORDER BY player_id, hour; 

使用,這將在「變化」 1和31小時之間的數量沒有登錄將 不計入返回。

我試圖用SQLFiddle來提供測試用例。 以上不是PostgreSQL特定的,可以使用PostgreSQL window functions優化內部查詢。

+0

感謝您的幫助 我只能從遊戲中檢查每個小時的統計數據,我只是想估計每個玩家可能連接的時間。 感謝您的測試案例,感謝您的幫助。我會測試每個提案,以瞭解什麼是最好的 – Alkalyne