存储开放时间/节假日
您建议使用哪种 SQL 模式来存储营业时间和节假日,以及使用哪种查询来检查餐厅是否营业?现在我有这个:
CREATE TABLE hours (
"restaurant" integer NOT NULL REFERENCES restaurants ON DELETE CASCADE,
"dow" integer NOT NULL,
"open" time NOT NULL,
"close" time NOT NULL
);
CREATE FUNCTION is_open(r integer) RETURNS boolean AS $$
DECLARE
h record;
t time;
BEGIN
SELECT open, close INTO h
FROM hours WHERE restaurant = r AND dow = EXTRACT(dow FROM now());
IF NOT FOUND THEN
RETURN false;
END IF;
t := current_time;
IF h.close <= h.open THEN
RETURN (t < h.close OR t > h.open);
ELSE
RETURN (t > h.open AND t < h.close);
END IF;
END;
$$ LANGUAGE plpgsql;
但这实际上不起作用,因为,例如,一家餐馆可能会营业到凌晨 2:00,此时我需要检查之前的 dow
。
让事情变得更复杂的是,我必须处理假期:
CREATE TABLE holidays (
"restaurant" integer NOT NULL REFERENCES restauraunts ON DELETE CASCADE,
"day" date NOT NULL
);
这也有同样的问题 - 如果一家餐厅在 15:30 到 2:00 营业,这意味着它们在午夜到两点的街区也会关门。
我一直没能全神贯注地找到一个干净、优雅的解决方案来解决这个问题(几个混乱的解决方案来了又走了)。我需要出去走走,然后再回来——同时,我想我应该让你们尝试一下。
What kind of SQL schema would you suggest for storing hours and holidays, and what kind of query to check if a restaurant is open? Right now I have this:
CREATE TABLE hours (
"restaurant" integer NOT NULL REFERENCES restaurants ON DELETE CASCADE,
"dow" integer NOT NULL,
"open" time NOT NULL,
"close" time NOT NULL
);
CREATE FUNCTION is_open(r integer) RETURNS boolean AS $
DECLARE
h record;
t time;
BEGIN
SELECT open, close INTO h
FROM hours WHERE restaurant = r AND dow = EXTRACT(dow FROM now());
IF NOT FOUND THEN
RETURN false;
END IF;
t := current_time;
IF h.close <= h.open THEN
RETURN (t < h.close OR t > h.open);
ELSE
RETURN (t > h.open AND t < h.close);
END IF;
END;
$ LANGUAGE plpgsql;
But that doesn't really work, because, for instance, a restaurant might be open until 2:00 am, at which point I would need to check for the previous dow
.
To make matters a little more complicated, I have to deal with holidays:
CREATE TABLE holidays (
"restaurant" integer NOT NULL REFERENCES restauraunts ON DELETE CASCADE,
"day" date NOT NULL
);
Which has the same problem - if a restaurant is open from 15:30 to 2:00, that means they are also closed for the block from midnight to two.
I haven't been able to wrap my head around finding a clean, elegant solution for this (several messy ones have come and gone). I need to go take a walk and come back to it - in the mean time, I figured I would let you guys take a crack at it.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
回答我自己的问题似乎有点错误,但我发现了一些似乎有效的东西,尽管它很混乱:
Seems kind of wrong to answer my own question, but I've found something that seems to work, as messy as it is:
总结评论:
1 - 使用通用查询结构 来自这个问题。
2 - 在您的表中添加一个位标志,用于
ClosePastMidnight
或OpenPastMidnight
(以最适合您的思维方式为准),表示关闭是下一个日历日,并相应地调整你的逻辑。To sum up the comments:
1 - Use the general query structure from this question.
2 - Add a bit flag to your table for
ClosePastMidnight
orOpenPastMidnight
(whichever works best for your way of thinking) that indicates close is on next calendar day, and adjust your logic accordingly.您的表格设计缺少信息,当您尝试消除关闭和打开含义的歧义时,这些信息就会变得明显。比如12比2,是指2小时还是14小时?如果不做出假设,就没有办法解决它。
使用间隔:
例如,如果您的餐厅从下午 1:30 到凌晨 1:30,则可以检查 now() 是否在中间:
这样,只有开始的道琼斯指数很重要,您不应该遇到任何环绕问题。
Your table design has missing information that becomes apparent when you try to disambiguate what close and opening means. Such as 12 to 2. Does that mean 2 hours or 14? Without making assumptions there is no way to solve it.
Use intervals:
For example if your restaurant is from 1:30PM to 1:30AM this could check if now() is inbetween:
That way only the starting dow is important and you should not have any wraparound problems.