不使用 UNION 从多个 "Not In" 查询中查询
Query from multiple "Not In" queries without using UNION
很难为我需要的内容取个好标题。
这大约需要 3 table 秒,并且是一个预约系统,我需要获取每个 doctor/nurse 的列表以及它们的空闲时间段。
我不想像下面的第一个 sql 一样使用 UNION,这意味着我必须声明每个医生的姓名,我不想这样做。
Tables...
用户详细信息:
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
时隙:
ID TimeSlot
1 10:00
2 10:30
3 11:00
4 11:30
11 16:30
12 17:00
约会:
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 和 PatientID,是来自用户的外键 ID Table)
我需要一个查询,它输出每个时间段和 Doc/Nurse 用于他们今天(或基于 "AppDate" 的任何一天)
的约会
我可以为特定的 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;
这给了我:
TimeSlot Role Surname Clinic
10:30 Doctor House 1
11:30 Doctor House 1
16:30 Doctor House 1
17:00 Doctor House 1
这很好,但我需要 1 个查询来显示所有 doctors/nurses,所以我有:
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
所以也可以按时间点。
我最初尝试使用:
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;
但这只是输出每个时间段的每个医生
附带说明一下,我觉得有更好的方法来构建结果 table 的外观,想不出如何。
如果我对问题的理解正确,这应该能满足您的需求...
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
CTE 将在每个时间段生成每个工作人员 X 的 "table"。然后你离开加入你在给定日期的约会。任何没有约会 ID 的结果行都是开放时间段。
很难为我需要的内容取个好标题。
这大约需要 3 table 秒,并且是一个预约系统,我需要获取每个 doctor/nurse 的列表以及它们的空闲时间段。
我不想像下面的第一个 sql 一样使用 UNION,这意味着我必须声明每个医生的姓名,我不想这样做。
Tables...
用户详细信息:
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
时隙:
ID TimeSlot
1 10:00
2 10:30
3 11:00
4 11:30
11 16:30
12 17:00
约会:
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 和 PatientID,是来自用户的外键 ID Table) 我需要一个查询,它输出每个时间段和 Doc/Nurse 用于他们今天(或基于 "AppDate" 的任何一天)
的约会我可以为特定的 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;
这给了我:
TimeSlot Role Surname Clinic
10:30 Doctor House 1
11:30 Doctor House 1
16:30 Doctor House 1
17:00 Doctor House 1
这很好,但我需要 1 个查询来显示所有 doctors/nurses,所以我有:
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
所以也可以按时间点。
我最初尝试使用:
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;
但这只是输出每个时间段的每个医生
附带说明一下,我觉得有更好的方法来构建结果 table 的外观,想不出如何。
如果我对问题的理解正确,这应该能满足您的需求...
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
CTE 将在每个时间段生成每个工作人员 X 的 "table"。然后你离开加入你在给定日期的约会。任何没有约会 ID 的结果行都是开放时间段。