I am trying to implement an appointment manager for a dentist office.
Thing is I am not sure how to properly implement such function. Right now I have managed to create these two tables that will handle it:
CREATE TABLE Horarios (
id_horario BIGSERIAL PRIMARY KEY,
hora TIME UNIQUE NOT NULL
);
CREATE TABLE Consultas (
id_consulta BIGSERIAL PRIMARY KEY,
paciente INTEGER REFERENCES Pacientes(id_paciente),
creado_por INTEGER REFERENCES Administrativo(id_administrativo),
fecha_designada DATE NOT NULL,
consulta_completa BOOLEAN DEFAULT false,
hora_inic INTEGER REFERENCES Horarios(id_horario),
hora_fin INTEGER REFERENCES Horarios(id_horario),
dentista INTEGER REFERENCES Dentistas(id_dentista)
);
All hour timestamps are hardcoded values like ("07:00")
So far, its all good I have been using this query to fetch all availables appointments:
SELECT
h.id_horario,
h.hora
FROM
Horarios h
WHERE
NOT EXISTS (
SELECT 1
FROM Consultas c
WHERE
c.fecha_designada = $1
AND c.dentista = $2
AND h.hora >= (SELECT hora FROM Horarios WHERE id_horario = c.hora_inic)
AND h.hora < (SELECT hora FROM Horarios WHERE id_horario = c.hora_fin)
)
ORDER BY
h.hora;
It will check for all, timestamps that are between the start_hour(hora_inic) and the end_hour(hora_fin) of said appointment.
And it works great when you have to create appointments in advance.
But when you have to create lets say:
An appointment from 7:00 to 7:30 and then another from 8:00 to 8:30 it doesn’t let me create an appointment from 7:30 to 8:00.
Now this is obviously a logical error.
I have been trying to change my query and both my backend and frontend. in order to aliviate this problem. But I believe this is just poorly design on my part.
I could use some guidance or advice in how to fix this or how to create an appointment app. Since thats the part that giving me issues right now.
Appreciate the time it took you to read my post. Thank you!
2
Answers
From mentally reviewing the code, nothing seems to be wrong. I would need to run some sample queries to see what the inner query is returning to debug that. Do not do the "SELECT 1", do a "SELECT *" and replace the h.hora value with ‘7:30’.
But…
The choice of creating a table to define hours strikes me as odd. You do not need a list of which hours exist in a day. You know they can go from 00:00 to 23:59; you do not need to validate the values.
More than a master of "hours", the usual way for this is to have a table of "slots" (which might be free or reserved). Each slot has its own fixed starting and ending time. The main downside is that it limits flexibility, if the appointments are of different duration; you can work around this by grouping several slots (either by business logic or creating an 1-N "appointment" class). Also, you need a procedure to generate the slots periodically.
The benefits are numerous:
Tryed to guess the basic data structure and to offer a solution accordingly…
… added cte with dentistas to work with their hours individualy …
The grid cte prepares the data for later aggregations defining the ocupied and available periods as well as mixed groupings
R e s u l t :
fiddle