2012-02-28 4 views
3

내 안드로이드 애플 리케이션에서 나는 데이터베이스 테이블에 저장된 연속 날짜의 가장 긴 줄무늬와 현재 줄무늬를 추적해야합니다. 나는이 일을 시작하기 위해 어디서부터 시작해야할지조차 모른다. 내가 생각해 낼 수있는 가장 좋은 점은 테이블의 모든 행을 쿼리하고 프로그래밍 방식으로 모두 반복하여 갭이있는 부분을 찾는 것입니다. 별로 효율적이지 않습니다. 누구든지 더 좋은 아이디어가 있습니까?테이블의 연속 날짜 수는 어떻게 계산합니까?

+1

아마도이 링크는 당신에게 몇 가지 아이디어를 줄 것이다 : http://stackoverflow.com/questions/3049586/how-to-calculate-longest-streak-in-sql – gangreen

답변

1

여기 제가 생각하기에 정말 멋진 SQL 만 솔루션입니다. 테이블의 날짜가 고유하다고 가정하면 (그룹화하기가 너무 어렵지는 않음) 여기서 http://www.sqlteam.com/article/detecting-runs-or-streaks-in-your-data에 적용된 방법을 사용할 수 있습니다. 이 예제를 살펴 보았는데 몇 가지 구문 오류가 있습니다. 아래 답변에서 반복하지 않기를 바랍니다. 아마 일부 예약 된 키워드를 사용 했으므로 적응해야 할 수도 있습니다.

먼저 사용자의 요구를 충족시킬 수있는 상당히 큰 날짜 테이블을 만드십시오. SQLite의 가장 좋은 방법은 무엇인지 모르겠지만 SQL Server에서는 Datetime 필드에 정수를 삽입 할 수 있으며 날짜에 정수를 암시 적으로 변환합니다. 테이블에 정수를 삽입하는 데는 여러 가지 방법이 있습니다 ...

어쨌든 날짜 테이블을 만든 후에는 날짜와 테이블의 최대 길이를 범위로 사용하여 날짜 테이블에서 Streak 테이블로 왼쪽으로 조인하십시오 리미터. 그러면 다음 코드가 생성됩니다.

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) 

을 부르 자 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

를 호출하자가 SQL을 부르 자 대답 : 가장 긴 줄은 무엇입니까?

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

1

기본적으로 월 및 일이 이므로 일 수를 필요한 수와 비교하면됩니다.

간격이있는 경우 한 달에 며칠 씩 계산하여 쉽게 찾을 수 있습니다. 예 : 당신은 count(days_visited) where month=1 을 가지고 있고 그것은 이십일을 반환하지만 January has 31가 11에 일 간격있다 및 SELECT date('now','start of year','+9 months','weekday 2');

EDIT처럼 당신은 기능 에 따라 사용할 수 있습니다 SQLite는

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

의 날짜 함수를 바로 여기에

죄송합니다. 모든 솔루션은 추합니다. 나도 알아.


create table visits (day_visited timestamp, visited int); 사용자가 (온라인/오프라인)으로 온라인 또는 오프라인 상태인지 여부를 나타내는이 테이블에서 매일 레코드를 만듭니다. 그런 다음 거기에 기록을 남깁니다. 월 기록은 1과 0을 가진 int 배열이됩니다.

 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  

지도 또는 테이블이 한 달 = 온라인 오프라인 일의 쌍을 포함합니다 : 는 vistedrecordsformonth

의사 코드라고합니다. 보통 order by 인 은 온라인 또는 오프라인 일 중 가장 큰 행보를 확인할 수 있습니다.

그것은 추합니다. 나는 더 우아한 것이 있어야한다고 확신합니다.하지만 빨리 작동하고 더러운 것이 좋습니다.


희망 하시겠습니까?

+0

난 아직 잘 모르겠어요 어떻게 내가 할 수있는 그것을 사용하십시오. 오늘이 1/9이고 데이터베이스에 1/1, 1/2, 1/3, 1/4, 1/5, 1/7, 1/8, 1/9 (매일 1/1/1을 제외한 1/9), 가장 긴 스트릭 쳐 5 번, 현재 스트릭크 3 번이 필요합니다. 전체 갯수를 확인하면 9 일 중 8 번 씩을 얻을 수 있기 때문에 갭이 있음을 알 수 있습니다. 하지만 그것은 내가 가장 길고 현재 스트릭 횟수를 알려주지 못한다. – Nick

+0

날짜를 몇 주 단위로 나눌 수 있으며 줄무늬를 평가할 수 있습니다. '% wday of week 0-6 sunday == 0 % W week of year 00-53'을 사용하십시오. –

+0

쉬운 방법은'days_visited'와'days_loggedoff'를 사용하여 한 달에 쉽게 계산할 수있는 테이블을 만드는 것입니다. –

관련 문제