Hard to make good title for exactly what I need.
This revolves around 3 tables, and is an appointment booking system, and I need to get a list of each doctor/nurse and the time slots they're free.
I don't want to use UNION as with the first sql below it means I have to declare the names of each doctor, which I don't want to do.
Tables...
UserDetails:
ID Role Surname Clinic
1 Doctor House 1
2 Doctor Bob 1
3 Nurse Smith 1
4 Doctor Jim 2
5 Nurse Grant 2
6 Patient Billy 1
7 Patient Jones 1
TimeSlots:
ID TimeSlot
1 10:00
2 10:30
3 11:00
4 11:30
11 16:30
12 17:00
Appointments:
ID StaffID PatientID TimeSlot AppDate
1 1 6 1 today
2 1 7 3 today
3 2 6 2 today
4 1 6 4 tomorrow
(StaffID and PatientID, are Foreign Keys ID from Users Table) I need a query which outputs each time slot and the Doc/Nurse for when they haven't got an appointment for today (or any day based on "AppDate")
I can do this for a specific doctor/nurse:
SELECT TimeSlots.TimeSlot, Users.Role, Users.Surname, Users.Clinic
FROM TimeSlots, Users
WHERE
TimeSlots.ID NOT IN
(SELECT Appointments.TimeSlot
FROM Appointments
INNER JOIN Users
ON Appointments.MedicalStaffID = Users.ID
WHERE AppDate = CONVERT(DATE,GETDATE()) AND Users.Surname = 'House')
AND
Users.Surname = 'House'
ORDER BY TimeSlots.TimeSlot;
Which gives me:
TimeSlot Role Surname Clinic
10:30 Doctor House 1
11:30 Doctor House 1
16:30 Doctor House 1
17:00 Doctor House 1
Which is fine, but I need 1 query to display this for all doctors/nurses, so I have:
TimeSlot Role Surname Clinic
10:30 Doctor House 1
11:30 Doctor House 1
16:30 Doctor House 1
17:00 Doctor House 1
10:00 Doctor Bob 1
11:00 Doctor Bob 1
11:30 Doctor Bob 1
16:30 Doctor Bob 1
17:00 Doctor Bob 1
and so it can also be ordered by the time.
I initially tried working with:
SELECT TimeSlots.TimeSlot, Users.Role, Users.Surname, Users.Clinic
FROM TimeSlots, Users
WHERE
TimeSlots.ID NOT IN (SELECT TimeSlot FROM Appointments WHERE AppDate = GETDATE() AND (Users.Clinic = 'Werrington') AND (Users.Role = 'Doctor' OR Users.Role = 'Nurse'))
AND
(Users.Role = 'Doctor' OR Users.Role = 'Nurse')
AND
(Users.Clinic = 'Werrington')
ORDER BY TimeSlots.TimeSlot;
But that just outputs every Doctor with every Timeslot
On a side note I feel theres a better way to structure the look of the resulting table, can't think of how.
If I understood the question correctly, this should give you what you're loking for...
SET NOCOUNT ON;
DECLARE @UserDetails TABLE (
ID int,
Role varchar(50),
Surname varchar(50),
Clinic int )
INSERT @UserDetails VALUES (1, 'Doctor', 'House', 1)
INSERT @UserDetails VALUES (2, 'Doctor', 'Bob', 1)
INSERT @UserDetails VALUES (3, 'Nurse', 'Smith', 1)
INSERT @UserDetails VALUES (4, 'Doctor', 'Jim', 2)
INSERT @UserDetails VALUES (5, 'Nurse', 'Grant', 2 )
INSERT @UserDetails VALUES (6, 'Patient', 'Billy', 1)
INSERT @UserDetails VALUES (7, 'Patient', 'Jones', 1)
DECLARE @TimeSlots TABLE (
ID int,
TimeSlot varchar(50) )
INSERT @TimeSlots VALUES (1 , '10:00' )
INSERT @TimeSlots VALUES (2 , '10:30' )
INSERT @TimeSlots VALUES (3 , '11:00' )
INSERT @TimeSlots VALUES (4 , '11:30' )
INSERT @TimeSlots VALUES (11, '16:30' )
INSERT @TimeSlots VALUES (12, '17:00' )
DECLARE @Appointments TABLE (
ID int,
StaffID int,
PatientID int,
TimeSlotID int,
AppDate varchar(50) )
INSERT @Appointments VALUES (1, 1, 6, 1, 'today' )
INSERT @Appointments VALUES (2, 1, 7, 3, 'today' )
INSERT @Appointments VALUES (3, 2, 6, 2, 'today' )
INSERT @Appointments VALUES (4, 1, 6, 4, 'tomorrow' )
SET NOCOUNT OFF;
WITH CompleteSchedule AS (
SELECT UD.ID as UserID, UD.Role, UD.Surname, UD.Clinic, TS.ID as TimeSlotID, TS.TimeSlot
FROM @UserDetails UD
CROSS JOIN @TimeSlots TS
)
SELECT CS.*
FROM CompleteSchedule CS
LEFT JOIN @Appointments A ON A.StaffID = CS.UserID AND A.TimeSlotID = CS.TimeSlotID AND A.AppDate = 'today'
WHERE A.ID is null
ORDER BY CS.UserID, CS.TimeSlotID
The CTE will generate a "table" of every staff member X every timeslot. Then you Left Join that with your appoints for the given day. Any resulting row that does not have an appointment ID is an open timeslot.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.