这是我关于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 *指定在哪个工作日重复输入。每个条目可以在几个不同的工作日重复。
我想实现一个函数,该函数获取特定时间戳范围内可用的所有条目。我解决这个问题的想法要么很慢,要么缺乏准确性。
我很欣赏任何提示。提前谢谢!
示例:
以下条目存储在数据库中:
搜索时间范围为2012-01-10 09:00(星期二)至2012-01-11 11:00(星期三)。
结果:
如果搜索的时间范围与整整一周重叠,则应找到所有条目。
答案 0 :(得分:0)
听起来你想在
时选择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)
我真的,真的不确定我做对了。所以我将对问题采取不同的看法。我也将使用SQL时间戳而不是Unix时代,所以每个人都可以看到发生了什么。
另外,我假设优惠在午夜结束,或多或少。似乎没有其他假设现在对我有意义。
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
因此,如果您可以构建一个返回与此产品表相同结果的视图,则只需查询该视图。
这里有三节课。
之后,经过评论和更正。 。
-- 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'
关于它们的最好的事情是,假设基础数据是正确的,很明显查询正在做正确的事情。对数据进行故障排除比对代码进行故障排除要容易得多。