首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >不使用UNION来自多个"Not In“查询的查询

不使用UNION来自多个"Not In“查询的查询
EN

Stack Overflow用户
提问于 2015-05-07 18:32:34
回答 1查看 106关注 0票数 3

很难为我所需要的获得好的头衔。

它围绕着3张桌子,是一个预约系统,我需要得到每一位医生/护士的名单,以及他们免费的时段。

我不想像下面的第一个sql那样使用UNION,这意味着我必须声明每个医生的名字,而我不想这样做。

桌子..。

UserDetails:

代码语言:javascript
运行
复制
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:

代码语言:javascript
运行
复制
ID   TimeSlot
1     10:00
2     10:30
3     11:00
4     11:30
11    16:30
12    17:00

任命:

代码语言:javascript
运行
复制
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 )我需要一个查询,它输出每个时隙和医生/护士,以便他们今天没有预约(或基于“AppDate”的任何一天)

我可以为特定的医生/护士这样做:

代码语言:javascript
运行
复制
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;

这给了我:

代码语言:javascript
运行
复制
TimeSlot   Role   Surname    Clinic
  10:30   Doctor   House       1
  11:30   Doctor   House       1
  16:30   Doctor   House       1
  17:00   Doctor   House       1

这很好,但是我需要一个查询来显示给所有的医生/护士,所以我有:

代码语言:javascript
运行
复制
   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

因此,它也可以按时间排序。

我一开始试着用:

代码语言:javascript
运行
复制
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;

但这只是输出每一个医生与每一个时隙

另外,我觉得有一种更好的方法来构造结果表的外观,我想不出是怎么回事。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-05-07 19:07:58

如果我正确地理解了这个问题,这会给你你想要的.

代码语言:javascript
运行
复制
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的“表”,每一个时隙。然后你就离开了,在指定的一天里加入你的任命。没有约会ID的任何结果行都是打开的时隙。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30109033

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档