2012-02-28 130 views
3

在我的Android應用程序中,我需要跟蹤保存在數據庫表中的連續日期的最長連勝和當前連勝。我甚至不知道該從哪裏開始工作。我能想到的最好的方法是查詢表中的每一行,並通過編程遍歷所有行來查找哪裏存在差距。效率不高。任何人有更好的想法?你如何計算表中連續日期的數量?

+1

這或許會鏈接給你一些想法:http://stackoverflow.com/questions/3049586/how-to-calculate-longest-streak-in-sql – gangreen 2012-02-28 02:28:14

回答

1

這是一個我認爲非常酷的SQL解決方案。假設表格中的日期是獨一無二的(不是僅僅將它們組合在一起就太難了),您可以使用從這裏調整的方法http://www.sqlteam.com/article/detecting-runs-or-streaks-in-your-data。我跑遍了這個例子,並且有一些語法錯誤,所以希望我在下面的答案中不再重複它們。我可能使用了一些保留的關鍵字,因此您可能需要修改它。

首先創建一個相當大的日期表以滿足您的需求。我不確定SQLite的最佳方法是什麼,但是在SQL Server中,您可以將整數插入日期時間字段,並且它會將整數隱式轉換爲日期。有很多方法可以將整數插入到表中...

無論如何,一旦創建了日期表,將日期表中的日期和時間表中的最小和最大日期作爲範圍限制器。您將會有以下代碼。 讓我們把它叫做SQL 0

SELECT Dates.Date, 
     CASE 
     WHEN StreakTable.DATE IS NULL THEN 0 
     ELSE 1 
     END AS Result 
FROM Dates 
     LEFT JOIN StreakTable 
     ON Dates.DATE = StreakTable.DATE 
WHERE Dates.DATE BETWEEN (SELECT MIN(DATE) AS MinDate 
          FROM StreakTable) AND (SELECT MAX(DATE) AS MaxDate 
                FROM StreakTable) 

讓我們把下面的SQL 1

SELECT Date, 
     Result, 
     (SELECT COUNT(*) 
     FROM (SQL 0) S 
     WHERE S.Result <> SV.Result 
       AND S.GameDate <= SV.GameDate) AS RunGroup 
FROM (SQL 0) SV 

讓我們把下面的SQL 2

SELECT Result, 
     MIN(Date) AS StartDate, 
     MAX(Date) AS EndDate, 
     COUNT(*)  AS Days 
FROM (SQL 1) A 
GROUP BY Result, 
      RunGroup 
ORDER BY MIN(Date) 

在這一點上,你可以做一些很酷的東西像回答: 什麼是最長的連勝?

SELECT TOP 1 * 
FROM (SQL 2) A 
WHERE Result = 1 
ORDER BY Games DESC 

截至最近日期的當前連勝情況如何?

SELECT * 
FROM (SQL2) A 
WHERE EndDate = (SELECT Max(Date) 
FROM Streak) 

我們有3條或更多的條紋?

SELECT Result, 
    COUNT(*) as NumberOfStreaks 
FROM (SQL 2) A 
GROUP BY Result 
WHERE Days >= 3 
+0

謝謝,這有助於很多。 – Nick 2012-02-29 14:09:36

1

基本上你有一個月和一個月的日子 所以你只需要比較天數和所需的數字。

如果存在差距,您可以通過減去一個月中的天數來輕鬆找到它。例如。你有count(days_visited) where month=1 並返回你20英鎊天,但January has 31所以有11天差距,我這裏還有的sqlite的

http://www.sqlite.org/lang_datefunc.html

日期函數可以使用以下功能 像SELECT date('now','start of year','+9 months','weekday 2');

EDIT

對不起,每個人的解決方案都很難看。這是我知道的。


創建表訪問(day_visited timestamp,visited int); 您在此表格中每天創建一條記錄,指示 用戶是在線還是離線( 'now',1 or 0(在線/離線))。然後你跑過那裏的記錄。 你月的記錄將是一個1和0的int數組。 稱爲vistedrecordsformonth

僞代碼:

 int online=0; 
     int offline=0;  
for(int i=0;i<vistedrecordsformonth.size();i++){  
     boolean flag=false;   
    if(vistedrecordsformonth[i]==1){ //visited 
     if(!flag&&i!=0) //check for flag and not 0 index to insert a record 
     { 
     streaksMap.put(online,offline); //or insert a record into another streakmap or table 
     online=0; 
     offline=0;  
     } 
     flag=true; 
     online++; 
    } 
    else{ 
     flag=false; 
     offline++; 
    } 
} //end of for  

地圖或表將包含一對在線=脫機天爲一個月。 與平常的order by你可以看到在線或離線的日子裏最大的連勝。

這是醜陋的我知道我確定應該有更優雅的東西,但作爲 快速和骯髒,它應該工作。


希望它有助於升技。

+0

我仍然不知道我怎麼能使用它。如果今天是1/9,並且在我的數據庫中,我有日期1/1,1/2,1/3,1/4,1/5,1/7,1/8,1/9(每天1/1和1/9,除了沒有1/6),那麼我需要一個5爲最長的連勝和3爲目前的連勝。檢查總數會給我8個可能的日子,所以我會知道有一個差距但這並沒有給我最長和目前的連勝數。 – Nick 2012-02-28 01:31:02

+0

你可以將你的日期分爲幾個星期,並根據評估條紋。使用00-53週中0〜6週週日的%w日。 – 2012-02-28 01:38:32

+0

簡單的方法就是用'days_visited'和'days_loggedoff'製作一張桌子,您可以在一個月內輕鬆計數。 – 2012-02-28 01:44:26