I’m not very experienced in advanced SQL and stackoverflow, so I’m trying my best to explain what I need.
Let’s say I have a table called ‘Shift’ and a table called ‘Schedule’.
‘Shift’ has columns ‘shift_id, shift_start, shift_end, shift_day, shift_function_id’.
shift_start represents a start time.
shift_end represents a end time.
shift_day represents the number of the day in a week (0-6 starting on sunday).
shift_function_id represents a function_id belonging to the shift.
‘Schedule’ has columns ‘schedule_id, schedule_date, schedule_start, schedule_end, schedule_function_id’.
schedule_date represents the date of a schedule.
schedule_start represents start time.
schedule_end represents end time.
schedule_function_id represents a function_id belonging to the schedule.
What I’m trying to do is if a row from ‘Shift’ doesn’t exist in table ‘Schedule’ with a given specific date where shift_start = schedule_start AND shift_end = schedule_end AND shift_function_id = schedule_function_id
, then show the row.
Here’s an example:
SELECT shift_id, shift_day, shift_start, shift_end, function_id, function_name, function_color FROM Shift LEFT JOIN Function ON function_id = shift_function_id WHERE shift_day = $day AND NOT EXISTS ( SELECT 1 FROM Schedule WHERE schedule_date = '$date' AND schedule_start = shift_start AND schedule_end = shift_end AND schedule_function_id = shift_function_id ) ORDER BY function_name, shift_start, shift_end;
The problem is
If I have 2 shifts with the same starting and end time and table ‘Schedule’ contains ONE row with the same function_id and starting and end time, BOTH the 2 shifts won’t show up.
Here’s an example of the table content:
Schedule
schedule_id: 310 schedule_date: 2020-01-11 schedule_start: 16:30:00 schedule_end: 20:00:00 schedule_function_id: 27
Shift
shift_id: 45 shift_day: 6 shift_start: 16:30:00 shift_end: 20:00:00 shift_function_id: 27 shift_id: 46 shift_day: 6 shift_start: 16:30:00 shift_end: 20:00:00 shift_function_id: 27
BOTH 2 rows from ‘Shift’ dont show up anymore’.
What I want
I want if ‘Schedule’ only has 1 row which contains the same information as the given data in ‘Shift’, I want the other row to show up.
If ‘Schedule’ has 2 rows with the same information, none to show up. It just needs to depend on how many rows ‘Schedule’ has with the same information.
IMAGES
When nothing is filled in, it shows 2 rows with same start and end
When I put a record with same start and end time, it removes both shift rows
I need this, when I only fill in one record with same start and end time
Advertisement
Answer
The only way I can think of is to let NOT EXISTS
clause remove all rows, Just append 1 row from duplicate rows with MIN (Or MAX) Shift_id –
SELECT shift_id, shift_day, shift_start, shift_end, function_id, function_name, function_color FROM shift LEFT JOIN function ON function_id = shift_function_id WHERE shift_day = $day AND NOT EXISTS (SELECT 1 FROM schedule WHERE schedule_date = '$date' AND schedule_start = shift_start AND schedule_end = shift_end AND schedule_function_id = shift_function_id) UNION ALL SELECT Min(S1.shift_id), S1.shift_day, S1.shift_start, S1.shift_end, function_id, function_name, function_color FROM shift S1 JOIN shift S2 ON S1.shift_id <> S2.shift_id AND S1.shift_day = S2.shift_day AND S1.shift_start = S2.shift_start AND S1.shift_end = S2.shift_end LEFT JOIN function ON function_id = S1.shift_function_id GROUP BY S1.shift_day, S1.shift_start, S1.shift_end, function_id, function_name, function_color ORDER BY function_name, shift_start, shift_end;
Here is working example.