I have a simple laptop testing booking system with 6 laptops, named Laptop01 to 06 that each have three allocated time slots.
A user is is able to select these time slots if the slot is not booked or if the booking has been cancelled/declined.
While I have working code, I've realised a fatal error that causes a cancelled/declined slot to duplicate.
Let me explain...
event_information
- Holds the booking event information (only ID is needed for this example)event_machine_time
- This hold all the laptops, with three rows per laptop with the unique timings available to choose fromevent_booking
- This holds the actual booking, which then links to another candidate database, not included here
I then run a simple query that joins everything together and (I thought) identifies the booked events:
SELECT machine_laptop, machine_name, B.id AS m_id, C.id AS c_id, C.confirmed AS c_confirmed, C.live AS c_live,
(C.id IS NOT NULL AND C.confirmed !=2 AND C.live !=0) AS booked
FROM event_information A
INNER JOIN event_machine_time B ON ( 1 =1 )
LEFT JOIN event_booking C on (B.id = C.machine_time_id and A.id = C.information_id )
WHERE A.id = :id
ORDER BY `B`.`id` DESC
booked
is checking if confirmed
isn't 2 - which means the booking has been cancelled/declined (0 - not confirmed, 1 - confirmed) and live
is checking for deletion (0 - deleted, 1 - not deleted).
However if a person either gets deleted (live
- 0) or cancels/declines (confirmed
- 2) then in my front end slot selector dropdown it will add an extra slot as the booked
column is still 0, as shown below:
This allows the user to then choose from two slots at the same time, meaning double bookings occur.
I now know that using a Join is the wrong thing to do, and I'm presuming that I need to run a subquery, but I'm not an SQL expert and I would love some help to find examples of similar 'second queries' that I can learn from.
Also apologies if my terminology is wrong.
EDIT:
As requested I've included the output:
Second edit and conclusion:
In the end I managed to craft a solution together using a sub query to remove the cancelled/declined bookings before the output, then use a Group By to only display one of each timing. This most likely isn't the best way, but it worked for me.
SELECT machine_laptop, machine_name, B.id AS m_id, C.id AS c_id, C.confirmed AS c_confirmed, C.live AS c_live, B.start_time AS b_start_time, (
C.id IS NOT NULL
AND C.confirmed !=2
AND C.live !=0
) AS booked
FROM event_information A
INNER JOIN event_machine_time B ON (1=1)
LEFT JOIN (SELECT * FROM event_booking WHERE confirmed <> '2' AND live <> '0') AS C ON ( B.id = C.machine_time_id AND A.id = C.information_id )
WHERE A.id = :id
GROUP BY m_id
ORDER BY machine_name ASC, b_start_time ASC
Thank you for all your input.