2012-02-18 8 views
0

내 첫 번째 게시물은 stackoverflow입니다. 제 질문이 규칙을 올바르게 여기에 맞지 않는다면 알려주세요.특정 범위 내에서 반복되는 날짜 찾기

PHP/MySQL에서 특정 시간 범위 내에서 모든 항목을 찾을 수있는 검색을 구현하려고합니다. 여기서 항목은 평일에 어떤 항목이 유효한지 지정합니다. 제공이 항목을 설명하고 (열 시작 (타임 스탬프))가 사용할 수있는 경우에서

CREATE TABLE offer (
    offer_id int unsigned not null auto_increment, 
    start int unsigned not null, 
    primary key(offer_id), 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

CREATE TABLE offer_weekdays (
    offer_id int unsigned not null, 
    weekday tinyint unsigned not null, 
    index (offer_id), 
    foreign key (offer_id) references offer(offer_id) 
      ON delete restrict ON update cascade, 
    unique key (offer_id, weekday) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

표 :

는 데이터베이스 모델이다. * offer_weekdays * 테이블은 항목이 반복되는 요일을 지정합니다. 각 항목은 여러 다른 평일에 반복 될 수 있습니다.

특정 타임 스탬프 범위에서 사용할 수있는 모든 항목을 가져 오는 기능을 구현하고 싶습니다. 이 문제를 해결하기위한 나의 아이디어는 느리거나 정확하지 않습니다.

감사합니다. 미리 감사드립니다!

:

다음 항목이 데이터베이스에 저장됩니다

  1. 시작 : 2011-01-11 10시 (화), 반복 : 화
  2. 시작 : 2011 -01-11 8시 (화), 반복 : 화
  3. 시작 : 2011-01-12 12시 (수), 반복 : 수, 목, 금

검색된 시간 범위는 2012-01-10 09:00 (화)부터 2012-01-11 11:00 (수)까지입니다.

결과 :

  1. 가 발견되지 발견했다. 평일 범위에 맞지만, 08:00에만 유효하지만, 은 09:00부터 검색합니다.
  2. 을 찾을 수 없습니다. 유효 기간은 12:00이지만 검색은 11:00까지입니다.

검색된 시간 범위가 한 주 전체로 겹치면 모든 항목을 찾아야합니다. 당신이 정말있을 때

The offer starts within the search interval, OR 
(the offer starts *before* search interval and 
start time of the offer >= start time of the search range 
as long as repeating weekdays match) 

선택합니다 같은

+0

쿠폰의 종료 시간을 저장하지 않으시겠습니까? 2012-01-19에서 2012-01-25까지 모든 쿠폰을 원하면 2012-01-29부터 시작하는 모든 쿠폰이 되겠습니까? (그 기간은 평일마다 다루기 때문에.) –

+0

명확하게하기 위해 예제를 추가했습니다. 더 이상의 질문이 있으면 저에게 물어보십시오. – Normalo

+0

예를 들어 년 또는 평일의 오타가 있습니까? –

답변

0

그것은 내가 바로 것을 가지고 정말 확실하지, 소리가 난다. 그래서 나는이 문제를 다른 시각에서 살펴볼 것입니다. 유닉스 시대 대신 SQL 타임 스탬프를 사용하기 때문에 모든 사람들이 무슨 일이 일어나는지 볼 수 있습니다.

나는 또한 자정에 끝나는 것을 추측하고 있습니다. 지금 당장 나에게 맞는 다른 가정이없는 것 같습니다.

create table offerings (
    offer_id integer not null, 
    offer_start timestamp not null, 
    offer_end timestamp not null check (offer_end > offer_start), 
    primary key (offer_id, offer_start) 
); 

-- Offer 1 starts 2012-01-10 10:00, ends 2012-01-10 23:59, repeats every Tue. 
insert into offerings values (1, '2012-01-10 10:00', '2012-01-10 23:59'); 
insert into offerings values (1, '2012-01-17 10:00', '2012-01-17 23:59'); 
insert into offerings values (1, '2012-01-24 10:00', '2012-01-24 23:59'); 
insert into offerings values (1, '2012-01-31 10:00', '2012-01-31 23:59'); 

-- Offer 2 starts 2012-01-10 08:00, ends 2012-01-10 23:59, repeats every Tue. 
insert into offerings values (2, '2012-01-10 08:00', '2012-01-10 23:59'); 
insert into offerings values (2, '2012-01-17 08:00', '2012-01-17 23:59'); 
insert into offerings values (2, '2012-01-24 08:00', '2012-01-24 23:59'); 
insert into offerings values (2, '2012-01-31 08:00', '2012-01-31 23:59'); 

-- Offer 3 starts 2012-01-11 12:00, ends 2012-01-11 23:59, repeats every Wed, Thu, Fri. 
insert into offerings values (3, '2012-01-11 12:00', '2012-01-11 23:59'); 
insert into offerings values (3, '2012-01-12 12:00', '2012-01-12 23:59'); 
insert into offerings values (3, '2012-01-13 12:00', '2012-01-13 23:59'); 

insert into offerings values (3, '2012-01-18 12:00', '2012-01-18 23:59'); 
insert into offerings values (3, '2012-01-19 12:00', '2012-01-19 23:59'); 
insert into offerings values (3, '2012-01-20 12:00', '2012-01-20 23:59'); 

insert into offerings values (3, '2012-01-25 12:00', '2012-01-25 23:59'); 
insert into offerings values (3, '2012-01-26 12:00', '2012-01-26 23:59'); 
insert into offerings values (3, '2012-01-27 12:00', '2012-01-27 23:59'); 

이제 선택이 간단합니다.

select * 
from offerings 
where offer_start >= '2012-01-10 09:00' 
    and offer_end <= '2012-01-11 11:00'; 

offer_id offer_start   offer_end 
-- 
1   2012-01-10 10:00:00 2012-01-10 23:59:00 

따라서이 오퍼링 테이블과 동일한 결과를 리턴하는 뷰를 빌드 할 수 있다면 뷰를 조회 할 수 있습니다.

여기에는 세 가지 강의가 있습니다.

  1. 혼동하지 않도록하십시오. 당신이 필요로하는 것을 찾으십시오.
  2. 부활절 문제가 발생했습니다. (당신이 뭔가를 계산할 수있다해서 당신 해야을 의미하지 않는다.)
  3. 를 제공하는 테이블에 단순화 후에, 나는 여전히가 확실하지 내가 기준을 이해 해요. 주석 및 수정 후

나중에. . .

-- PostgreSQL 
create table offerings (
    offer_id integer not null, 
    offer_at timestamp not null, 
    primary key (offer_id, offer_at) 
); 

-- A little data for offer 1. Inserts for 2 and 3 are similar. 
insert into offerings 
select 1 offering_id, '2011-01-11 10:00'::timestamp + (n || ' days')::interval offer_at 
from generate_series(0, 1000, 7) n 
where '2011-01-11 10:00'::timestamp + (n || ' days')::interval < '2012-03-01'; 

다시 쿼리는 간단합니다. (그리고 약간의 행운과 함께, 실제로.이 시간을 수정)이 두 쿼리 1.

select * 
from offerings 
where offer_at between '2012-01-10 09:00' and '2012-01-10 11:00' 

select * 
from offerings 
where offer_at between '2012-01-10 09:00' and '2012-01-11 11:00' 

그들에 대한 가장 좋은 것은 기본 데이터를 가정하면, 그것은 그 명백한 맞습니다입니다, 만 제공 수를 반환합니다 검색어가 올바른 일을하고 있습니다. 코드 문제를 해결하는 것보다 데이터 문제를 해결하는 것이 훨씬 쉽습니다.

+0

매주 반복되는 요일에 새로운 서비스가 저장됩니다. 맞습니까? 너무 많은 데이터와 유지 보수가 발생할 것이므로 미래의 일정을 위해 백그라운드 작업으로 항목을 계속 추가해야합니다. – Normalo

+0

@Normalo : 데이터가 올바른 논리입니까? –

+0

내 의견을 분명히하기 위해서 : 2012-02-24 09:00에서 2012-02-25 11:00까지 검색 할 때 나에게도 제공해야합니다. – Normalo

관련 문제