Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7960743
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 4, 20262026-06-04T04:50:30+00:00 2026-06-04T04:50:30+00:00

I’m struggling to design a database schema that represents opening hours for buildings and

  • 0

I’m struggling to design a database schema that represents opening hours for buildings and their tenants. Here are the details/requirements:

Buildings:

  • In general, each building’s normal business hours depend on a season (summer, winter, etc.)
  • Each building has different hours.
  • Numerous holidays, events, etc. will override normal business hours

Tenants:

  • Tenants operate within buildings, and therefore should be constrained by building hours.
  • Normal hours also depend on a season, but are not the same as its building’s seasonal hours.
  • Each tenant has different hours

Ideally, I’d like to be able to query the following:

  • Whether or not a building or tenant is open right now
  • What are building hours today
  • What are building hours for the next X days

My (unfinished) work so far has been these three tables, but I’m still having trouble creating a working solution.

[Season]
id
building_id
title
start_date
end_date

[Schedule]
id
season_id
day_of_week (0-6)
open_time
close_time

[Override]
id
schedule_id
date
is_closed
is_holiday

Thanks all for your time and input on this. All of the answers develop/refine the solution. Catcall’s idea of storing the individual dates is the easiest for us to develop a model and admin/management interface for.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-04T04:50:31+00:00Added an answer on June 4, 2026 at 4:50 am

    Let’s look at the problem a different way. Operating hours are not essentially different for buildings and tenants. That is, the values may vary, but the idea of a building being open or not isn’t essentially different from a tenant being open or not. I created a separate schema, “hours”, to play with this idea.

    -- Essentially a supertype, but I couldn't think of a good noun to 
    -- describe it.  So I named the table "x".  It holds all the attributes 
    -- common to both buildings and tenants. (That is, not very much.)
    --
    create table hours.x (
      x_id integer primary key,
      x_name varchar(35) not null,
      x_type char(1) check (x_type in ('b','t')),
      unique (x_id, x_type)
    );
    
    insert into hours.x values 
    (1, 'First building', 'b'),
    (2, 'Second building', 'b'),
    (3, 'First tenant', 't'),
    (4, 'Second tenant', 't'),
    (5, 'Third tenant', 't');
    
    create table hours.buildings (
      bldg_id integer primary key,
      x_type char(1) not null default 'b' check (x_type = 'b'),
      foreign key (bldg_id, x_type) references hours.x (x_id, x_type),
      other_columns char(1) not null default 'x'
    );
    
    insert into hours.buildings (bldg_id) values 
    (1), (2);
    
    create table hours.tenants (
      tenant_id integer primary key,
      x_type char(1) not null default 't' check (x_type = 't'),
      foreign key (tenant_id, x_type) references hours.x (x_id, x_type),
      bldg_id integer not null references hours.buildings (bldg_id),
      other_columns char(1) not null default 'x'
    );
    
    insert into hours.tenants (tenant_id, bldg_id) values
    (3, 1), (4, 1), (5, 2);
    
    
    -- Operating hours records a half open interval [opening_time, closing_time).
    -- If a queried time matches the opening time, the building or tenant is open.
    -- But if it matches the closing time, it's *not* open.  Examples later.
    create table hours.op_hours (
      x_id integer not null references hours.x (x_id),
      opening_time timestamp not null,
      closing_time timestamp not null,
      check (opening_time < closing_time),
      check (
        -- Open and close on the same date,
        ( opening_time::date = closing_time::date ) or
        -- or close at midnight following the opening.
        ( 
          (opening_time::date + interval '1' day = closing_time::date) and 
          (cast(closing_time as time) = '00:00')
        )
      )
    );
    
    insert into hours.op_hours values
    -- Bldg 1 is normally Mon-Sat, 9:00 to 5:00. Closed on Jan 1, holiday
    (1, '2012-01-02 09:00', '2012-01-02 17:00'),
    (1, '2012-01-03 09:00', '2012-01-03 17:00'),
    (1, '2012-01-04 09:00', '2012-01-04 17:00'),
    (1, '2012-01-05 09:00', '2012-01-05 17:00'),
    (1, '2012-01-06 09:00', '2012-01-06 17:00'),
    (1, '2012-01-07 09:00', '2012-01-07 17:00'),
    -- Closed on Jan 8, a Sunday.
    (1, '2012-01-09 09:00', '2012-01-09 17:00'),
    
    -- Bldg 2 is normally Mon-Fri, 7:30 to midnight.
    (2, '2012-01-02 07:30', '2012-01-03 00:00'),
    (2, '2012-01-03 07:30', '2012-01-04 00:00'),
    (2, '2012-01-04 07:30', '2012-01-05 00:00'),
    (2, '2012-01-05 07:30', '2012-01-06 00:00'),
    (2, '2012-01-06 07:30', '2012-01-07 00:00'),
    -- Closed on Jan 7 and 8, weekend.
    (2, '2012-01-09 07:30', '2012-01-10 00:00'),
    
    -- "First" tenant is open 9:00 to noon and 1:00 to 4:00, Mon-Fri.
    (3, '2012-01-02 09:00', '2012-01-02 12:00'),
    (3, '2012-01-03 09:00', '2012-01-03 12:00'),
    (3, '2012-01-04 09:00', '2012-01-04 12:00'),
    (3, '2012-01-05 09:00', '2012-01-05 12:00'),
    (3, '2012-01-06 09:00', '2012-01-06 12:00'),
    (3, '2012-01-02 13:00', '2012-01-02 16:00'),
    (3, '2012-01-03 13:00', '2012-01-03 16:00'),
    (3, '2012-01-04 13:00', '2012-01-04 16:00'),
    (3, '2012-01-05 13:00', '2012-01-05 16:00'),
    (3, '2012-01-06 13:00', '2012-01-06 16:00'),
    
    -- "Second" tenant is open when the building is open.
    (4, '2012-01-02 09:00', '2012-01-02 17:00'),
    (4, '2012-01-03 09:00', '2012-01-03 17:00'),
    (4, '2012-01-04 09:00', '2012-01-04 17:00'),
    (4, '2012-01-05 09:00', '2012-01-05 17:00'),
    (4, '2012-01-06 09:00', '2012-01-06 17:00'),
    (4, '2012-01-07 09:00', '2012-01-07 17:00'),
    -- Closed on Jan 8, a Sunday.
    (4, '2012-01-09 09:00', '2012-01-09 17:00'),
    
    -- "Third" tenant is open Mon-Thu 7:30 to 9:30, Fri until midnight.
    (5, '2012-01-02 07:30', '2012-01-02 21:30'),
    (5, '2012-01-03 07:30', '2012-01-03 21:30'),
    (5, '2012-01-04 07:30', '2012-01-04 21:30'),
    (5, '2012-01-05 07:30', '2012-01-05 21:30'),
    (5, '2012-01-06 07:30', '2012-01-07 00:00'),
    -- Closed on Jan 7 and 8, weekend.
    (5, '2012-01-09 07:30', '2012-01-09 21:30');
    

    It should be clear that this kind of structure, which records each day’s operating hours for every building and every tenant, will accommodate any definition of season, holidays, events, and so on. Default data can be generated with a fairly simple stored procedure. And the required queries are dead simple. (There’s a lot of value in being able to look at something and see that it’s right.)

    -- Is building 1 open at 9:00 am on Jan 3? (Queries for tenants are essentially
    -- identical. Returns the id number if it's open, but that could be massaged 
    -- into an "is_open" derived column with Boolean values.)
    select x_id
    from hours.op_hours
    where x_id = 1
      and opening_time <= '2012-01-03 09:00' 
      and '2012-01-03 09:00' < closing_time;
    
    -- How about on Jan 1? (Returns an empty set if closed. See above.)
    select x_id
    from hours.op_hours
    where x_id = 1
      and opening_time <= '2012-01-01 09:00' 
      and '2012-01-01 09:00' < closing_time;
    
    -- Which tenants, regardless of building, are open on Jan 4 at 9:00 am?
    select op_hours.x_id
    from hours.op_hours
    inner join hours.tenants on hours.tenants.tenant_id = hours.op_hours.x_id 
    where opening_time <= '2012-01-04 09:00' 
      and '2012-01-04 09:00' < closing_time;
    

    Note that each of those queries operates on a half open interval. You can’t use the BETWEEN operator, because it operates on a closed interval.

    Which requirements does this structure not accommodate?

    • Tenant operating hours must be a subset of building operating hours. Can’t be done declaratively unless your dbms support assertions. Can be done with procedural code in the database.
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm parsing an RSS feed that has an &#8217; in it. SimpleXML turns this
link Im having trouble converting the html entites into html characters, (&# 8217;) i
That's pretty much it. I'm using Nokogiri to scrape a web page what has
I have a jquery bug and I've been looking for hours now, I can't
I have a string like this: La Torre Eiffel paragonata all&#8217;Everest What PHP function
I've got a string that has curly quotes in it. I'd like to replace
I have a French site that I want to parse, but am running into
I am doing a simple coin flipping experiment for class that involves flipping a
I'm trying to decode HTML entries from here NYTimes.com and I cannot figure out
I need a function that will clean a strings' special characters. I do NOT

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.