[SQL] X 일 연속 확인 - 데이터베이스에 주어진 타임 스탬프를
SQLX 일 연속 확인 - 데이터베이스에 주어진 타임 스탬프를
누군가가 나에게 당신이 데이터베이스 테이블에 X 일 연속 확인할 수있는 방법을 생각이나 힌트를 줄 수 (MySQL은) 여기에서 로그인 (사용자 ID, 타임 스탬프) 저장됩니까?
유래는 (예를 들어, 배지 매니아와 같은 - 당신은 연속 30 일 정도에 로그인 할 경우 ...) 그것을 않습니다. 어떤 기능은 당신이 사용하거나 그것을 수행하는 방법의 아이디어는 무엇인가 것인가?
login_dates 곳에서 SELECT 1 같은 뭔가 ...?
해결법
-
==============================
1.다음을 사용하여이를 달성 할 수있는 변수와 함께 자기 외부 조인 시프트. 이 솔루션을 참조하십시오 :
다음을 사용하여이를 달성 할 수있는 변수와 함께 자기 외부 조인 시프트. 이 솔루션을 참조하십시오 :
SELECT IF(COUNT(1) > 0, 1, 0) AS has_consec FROM ( SELECT * FROM ( SELECT IF(b.login_date IS NULL, @val:=@val+1, @val) AS consec_set FROM tbl a CROSS JOIN (SELECT @val:=0) var_init LEFT JOIN tbl b ON a.user_id = b.user_id AND a.login_date = b.login_date + INTERVAL 1 DAY WHERE a.user_id = 1 ) a GROUP BY a.consec_set HAVING COUNT(1) >= 30 ) a
이 반환됩니다 중 1 또는 사용자가 연속 30 일 이상 과거에 언제든지 로그인 한 경우에 따라 0.
이 쿼리의 기봉이 첫번째 부속 선택에 정말입니다. 우리는 더 나은 이것이 어떻게 작동하는지 이해할 수 있도록하자가 자세히 살펴 :
다음의 예시적인 데이터 집합 :
CREATE TABLE tbl ( user_id INT, login_date DATE ); INSERT INTO tbl VALUES (1, '2012-04-01'), (2, '2012-04-02'), (1, '2012-04-25'), (2, '2012-04-03'), (1, '2012-05-03'), (2, '2012-04-04'), (1, '2012-05-04'), (2, '2012-05-04'), (1, '2012-05-05'), (2, '2012-05-06'), (1, '2012-05-06'), (2, '2012-05-08'), (1, '2012-05-07'), (2, '2012-05-09'), (1, '2012-05-09'), (2, '2012-05-11'), (1, '2012-05-10'), (2, '2012-05-17'), (1, '2012-05-11'), (2, '2012-05-18'), (1, '2012-05-12'), (2, '2012-05-19'), (1, '2012-05-16'), (2, '2012-05-20'), (1, '2012-05-19'), (2, '2012-05-21'), (1, '2012-05-20'), (2, '2012-05-22'), (1, '2012-05-21'), (2, '2012-05-25'), (1, '2012-05-22'), (2, '2012-05-26'), (1, '2012-05-25'), (2, '2012-05-27'), (2, '2012-05-28'), (2, '2012-05-29'), (2, '2012-05-30'), (2, '2012-05-31'), (2, '2012-06-01'), (2, '2012-06-02');
이 쿼리 :
SELECT a.*, b.*, IF(b.login_date IS NULL, @val:=@val+1, @val) AS consec_set FROM tbl a CROSS JOIN (SELECT @val:=0) var_init LEFT JOIN tbl b ON a.user_id = b.user_id AND a.login_date = b.login_date + INTERVAL 1 DAY WHERE a.user_id = 1
생성합니다 :
당신이 볼 수 있듯이, 우리가하고있는 것은 일일에 의해 조인 된 테이블을 이동하고있다. 이전 하루 연속없는 하루를 들면, NULL 값이 LEFT에 의해 생성되는 가입하세요.
이제 비 연속적인 일이 어디 우리가 알고있는, 우리는 이동 테이블의 행이 NULL 있는지 여부를 감지하여 일 연속의 각 세트를 차별화하기 위해 변수를 사용할 수 있습니다. 그들이 NULL 경우, 일, 그래서 그냥 변수를 증가, 연속되지 않습니다. 그들이 NOT NULL 인 경우, 다음 변수를 증가하지 않습니다
우리는 증가 변수 일 연속의 각 세트를 구분 한 후, 그 다음합니다 (consec_set 컬럼에 정의 된대로) 각각의 "설정"에 의해 그룹화하고 덜 지정된 이상이있는 세트를 필터링 HAVING 사용하는 단순한 문제입니다 연속 일 (귀하의 예제에서 30)
그리고 마지막으로, 우리는 그 쿼리를 감싸 단순히 30 이상 일 연속 한 세트의 수를 계산합니다. 하나 이러한 세트 더 있었다 경우, 그렇지 않으면 1을 반환 0을 반환합니다.
-
==============================
2.이 날짜 범위에서 별개의 (날짜) == X 인 경우 타임 스탬프의 날짜와 체크에 X를 추가 할 수 있습니다 :
이 날짜 범위에서 별개의 (날짜) == X 인 경우 타임 스탬프의 날짜와 체크에 X를 추가 할 수 있습니다 :
그 30 일 매일 한 번 이상 :
SELECT distinct 1 FROM login_dates l1 inner join login_dates l2 on l1.user = l2.user and l2.timestamp between l1.timestamp and date_add( l1.timestamp, Interval X day ) where l1.user = some_user group by DATE(l1.timestamp) having count( distinct DATE(l1.timestamp) ) = X
(당신은 ... 성능 요구 사항에 대해 말하지 않는다;))
* 편집 ~ 만 지난 X 일에 대한 쿼리 : 동쪽 그 30 일마다 하루에 한 번
SELECT distinct 1 FROM login_dates l1 where l1.user = some_user and l1.timestamp > date_add( CURDATE() , Interval -X day ) group by l1.user having count( distinct DATE(l1.timestamp) ) = X
-
==============================
3.그것만으로도 SQL로 해결하기 어려운 문제입니다.
그것만으로도 SQL로 해결하기 어려운 문제입니다.
문제의 핵심은 하나 개의 쿼리에서 서로 동적 결과 세트를 비교해야한다는 것입니다. 예를 들어, 다음, 하나 DATE에 대한 모든 로그인 / 세션 ID를 얻을 수 (당신이 결정하는 DATE_ADD를 사용할 수 있습니다) 날짜 ()에서 로그인의 그룹에 목록을 JOIN 또는 UNION해야합니다. 당신은 연속 날짜의 N 번호를이 작업을 수행 할 수 있습니다. 당신이 어떤 행이 남아있는 경우, 그 세션은 그 기간에 기록되어있다.
다음 표를 가정합니다 :
세션 id INT, 만든 날짜
모든이 쿼리 반환이 지난 이틀 동안 열을 가지고있는 세션 id :
select t1.sessionid from logins t1 join logins t2 on t1.sessionid=t2.sessionid where t1.created = DATE(date_sub(now(), interval 2 day)) AND t2.created = DATE(date_sub(now(), interval 1 day));
당신이 볼 수 있듯이, SQL은 30 일 동안 밥맛 얻을 것이다. 스크립트를 생성해야합니다. :-디
이것은 더 매일이, 로그인 테이블이 세션으로 업데이트되어 있다고 가정합니다.
이 실제로 문제가 해결되는지 모르겠지만, 나는 프레임에게 문제를 도움이되기를 바랍니다.
행운을 빕니다.
-
==============================
4.이 기본값 1. login_dates 테이블에 여분의 열 consecutive_days이 더 간단하지 않을까요이 그 날에 끝나는 연속 날짜의 길이를 나타냅니다.
이 기본값 1. login_dates 테이블에 여분의 열 consecutive_days이 더 간단하지 않을까요이 그 날에 끝나는 연속 날짜의 길이를 나타냅니다.
이전 일에 대한 항목이 있는지 확인 어디 login_dates에 트리거 후 삽입을 만들 수 있습니다.
존재하지 않는 경우는, 다음 필드는 새로운 순서는 날짜에 시작하는 기본 값 1 의미를 가질 것이다.
여기하다면 이전의 일에 대한 항목이 다음 그 전날의 다음으로 기본 1 일 개 더를 days_logged_in 값을 변경합니다.
전의:
| date | consecutive_days | |------------|------------------| | 2013-11-13 | 5 | | 2013-11-14 | 6 | | 2013-11-16 | 1 | | 2013-11-17 | 2 | | 2013-11-18 | 3 |
from https://stackoverflow.com/questions/11539065/check-for-x-consecutive-days-given-timestamps-in-database by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] SQL 서버 교체, 특정 문자 후 모두 제거 (0) | 2020.04.19 |
---|---|
[SQL] tmp를 테이블에 대한 MySQL의 잘못된 키 파일 만들기 여러 조인 (0) | 2020.04.19 |
[SQL] 연루되는 테이블에서 선택하는 단일 쿼리에서 여러 테이블에 INSERT 행 (0) | 2020.04.19 |
[SQL] 두 개의 열을 결합하여 하나 개의 새로운 컬럼에 추가 (0) | 2020.04.19 |
[SQL] C #을 GUID 및 SQL의 고유 식별자 (0) | 2020.04.19 |