2009-08-15 2 views
2

나는 다음과 같이 레코드와 테이블이 있습니다SQL 날짜 범위에서 날짜와 일치하는 레코드 수를 쿼리합니까?

CREATE TABLE sample (
    ix int unsigned auto_increment primary key, 
    start_active datetime, 
    last_active datetime 
); 

나는 많은 기록이 지난 30 일 각각 활약 한 방법을 알아야합니다. 요일도 정렬되어 점차적으로 가장 오래된 날짜로 되돌려 야합니다.

저는 MySQL을 사용하고 있으며 쿼리는 PHP에서 실행되지만 PHP 코드는 필요하지 않으며 쿼리 만 필요합니다. 여기

내 시작의 :

SELECT COUNT(1) cnt, DATE(?each of last 30 days?) adate 
FROM sample 
WHERE adate BETWEEN start_active AND last_active 
GROUP BY adate; 

답변

5

외부 조인을 수행하십시오.

테이블이 없음? 테이블을 만드십시오. 나는 항상 이것을 위해 더미 테이블을 유지한다.

create table artificial_range( 
    id int not null primary key auto_increment, 
    name varchar(20) null) ; 

-- or whatever your database requires for an auto increment column 

insert into artificial_range(name) values (null) 
-- create one row. 

insert into artificial_range(name) select name from artificial_range; 
-- you now have two rows 

insert into artificial_range(name) select name from artificial_range; 
-- you now have four rows 

insert into artificial_range(name) select name from artificial_range; 
-- you now have eight rows 

--etc. 

insert into artificial_range(name) select name from artificial_range; 
-- you now have 1024 rows, with ids 1-1024 

지금 편리 사용할 수 있도록하고, 볼 수있는 30 일에 제한 :

편집 : JR Lawhorne 노트 :

당신은 변경해야 "을"DATE_ADD " date_sub "를 클릭하여 생성 된보기에서 이전 30 일을 가져옵니다.

감사합니다. JR!

create view each_of_the_last_30_days as 
select date_sub(now(), interval (id - 1) day) as adate 
from artificial_range where id < 32; 

지금 조회에서 이것을 사용 (I 실제로 테스트하지 않았습니다 당신의 쿼리, 난 그냥 제대로 작동합니다 있으리라 믿고있어) :

편집 : 나는 다른 방법을 결합해야합니다

SELECT COUNT(*) cnt, b.adate 
FROM each_of_the_last_30_days b 
left outer join sample a 
on (b.adate BETWEEN a.start_active AND a.last_active) 
GROUP BY b.adate; 
+0

생성 된보기에서 이전 30 일을 보려면 "date_add"를 "date_sub"로 변경해야합니다. –

0

SQL은 데이터베이스에 저장되는 값의 세트 매칭에 매우 중요하지만, 그것은 가에되지 않은 값 세트를 일치에서 그렇게 크지 않다 데이터 베이스.

CREATE TEMPORARY TABLE days_ago (d SMALLINT); 
INSERT INTO days_ago (d) VALUES 
    (0), (1), (2), ... (29), (30); 

지금 당신이 start_active 각 행의 last_active 사이의 범위에 d일 전에의 날짜를 비교할 수 있습니다 그래서 쉬운 하나의 해결 방법은 당신이 필요로하는 값을 포함하는 임시 테이블을 만드는 것입니다. 그룹당 일치하는 행 수를 d으로 계산하면 계산할 수 있습니다.

SELECT CURRENT_DATE - d DAYS, COUNT(*) cnt, 
FROM days_ago 
LEFT JOIN sample ON (CURRENT_DATE - d DAYS BETWEEN start_active AND last_active) 
GROUP BY d 
ORDER BY d DESC; -- oldest to newest 

또 다른 참고 : GROUP BY 절에 도달 할 때까지 당신이 표현에 선택 목록에 정의 된 열 별칭을 사용할 수 없습니다. 실제로 표준 SQL에서는 ORDER BY 절까지는 사용할 수 없지만 MySQL에서는 GROUP BYHAVING 절에 별칭을 사용하는 것을 지원합니다.

0
은 조회에서, 초 유닉스 타임 스탬프로 날짜를 켜고 차이가 < = 한 달에 초 단위로에 대한 다음보고있는 것만

.쿼리 알려 주시기 바랍니다 도움이 필요하면 http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html#function_unix-timestamp

을하지만, MySQL은 날짜를 처리하기위한 좋은 기능이 있습니다

여기에서 자세한 정보를 찾을 수 있습니다.

[편집] 나는 진짜 질문에 관해서 혼란 스러웠 기 때문에 나는 잔디밭을 끝내야한다. 그러나 잊기도 전에 나는 이것을 적어두고 싶다.

일 수를 계산하려면 위의 설명과 같이 where 절을 사용하여 지난 30 일로 제한해야하지만 일별로 그룹화해야하며 각 시작을 전환하여 선택해야합니다 그 달의 날로 옮긴 다음 그 수를 계산합니다.

시작일과 종료일이 며칠 동안 지속될 수 있으면 각 사용이 하루로 제한된다는 것을 전제로합니다.

+0

어떤 날짜를 유닉스 타임 스탬프로 바꿀 수 있습니까? 'CURRENT_DATE - INTERVAL 30 DAY','start_active' 또는'end_active'? 이것은 OP 그룹에게 지난 30 일의 매일 *에 대한 활동 기록 수를 어떻게 도움이됩니까? – pilcrow

+0

start_active 및 last_active를 unix_timestamp로 바꾸거나 시도하지는 않았지만 subtime()을 사용하여 시간을 빼고 변환하거나 위에서 제안한 페이지에서 다음과 같이 사용할 수 있습니다. select ID MESSAGE에서 SENT_TIME <(CURDATE() - INTERVAL 5 DAY); 시간 함수를 살펴보면 가장 적합한 것이 무엇인지 찾아 낼 수 있습니다. –

+0

@James Black, 귀하의 대답은 귀하가 OP가 30 일의 시간대와 겹치는 레코드의 수를 알고 싶어한다고 생각하는 것을 제안합니다 -하지만 그것은 틀린 질문입니다, 그는 겹치는 레코드의 수를 매일 알고 싶어합니다 * 지난 30 일 동안. (예, SQL 네이티브 유형 또는 통합 신기원 스탬프에서 연산이 쉽습니다.) 제안을 설명하기 위해 코드 솔루션을 게시 할 수 있습니까? – pilcrow

관련 문제