SQL 服务器中连接的高级应用

Advanced applications of joins in SQL Server

我正在使用医院数据库。我正在创建一个视图以查看员工数量,doctors.my table 结构是,

create table department(
DEPT_ID VARCHAR(5) primary key check(DEPT_id LIKE('D%')),
DEPT_NAME VARCHAR(25) not null,
DEPT_LOCATION VARCHAR(25) 
)




CREATE TABLE doctors(
DOCT_ID VARCHAR(5) PRIMARY KEY CHECK (DOCT_ID LIKE('DR%') OR DOCT_ID LIKE ('DC%')),
F_NAME  VARCHAR(25) NOT NULL,
L_NAME  VARCHAR(20),
T_P     CHAR(10) not null,
NIC     CHAR(10),
ADD_LINE1  VARCHAR(10),
ADD_LINE2  VARCHAR(25),
ADD_LINE3  VARCHAR(20),
type varchar(10)  check(type in('regular','call on')),
DEPT_ID    VARCHAR(5) CONSTRAINT FK_DOCT_DEPT FOREIGN KEY REFERENCES DEPARTMENT(DEPT_ID) on delete set null
)



    create table Staff( 

    Staff_id int identity(1,1) primary key,
    F_name Varchar(25) not null ,
    L_name Varchar(25) ,
    Position Varchar(25),
    Tp   char(10),
    Add_line_1 Varchar(25),
    Add_line_2 Varchar(25),
    Add_line_3 Varchar(25),
    Salary money,
    Work_experience_yrs int,
    Dept_id Varchar(5) constraint fk_dept_staff foreign key references department(dept_id)
    )

到目前为止我已经尝试过的代码,

SELECT dpt.dept_id,
       dpt.dept_name,
       Count(dct.DOCT_ID)num_of_doctors,
       Count(stf.dept_id)AS num_of_staff
FROM   department dpt
       INNER JOIN doctors dct
               ON dpt.DEPT_ID = dct.Dept_id
       INNER JOIN staff stf
               ON stf.Dept_id = dpt.DEPT_ID
GROUP  BY dpt.DEPT_ID,
          dpt.DEPT_NAME 

doctors table             
doct_id     dept_id
dc1         d1
dr1         d1
dr2         d2
dr3         d3
dr4         d3
dr5         d1

staff_id  dept_id
1           d1
2           d1
3           d3
4           d2
5           d3
6           d3

expected result
dept_id   num_of_doct   num_of_staffs
d1          3            2
d2          1            1
d3          2            3

它没有给我想要的结果...请给我建议

当你的部门有 3 名医生和 2 名员工时,你的查询将显示 3 名医生和 3 名员工,因为你首先加入 tables,加入后员工的记录数也将是 3,因为它的部门有3名医生

如果我没记错的话你正在找这个

SELECT dpt.dept_id,
       dpt.dept_name,
       num_of_doctors,
       num_of_staff
FROM   department dpt
       INNER JOIN (SELECT Count(1) AS num_of_doctors,
                          Dept_id
                   FROM   doctors
                   GROUP  BY DEPT_ID) dct
               ON dpt.DEPT_ID = dct.Dept_id
       INNER JOIN (SELECT Count(1) AS num_of_staff,
                          DEPT_ID
                   FROM   staff
                   GROUP  BY DEPT_ID) stf
               ON stf.Dept_id = dpt.DEPT_ID

我的查询的不同之处在于它会分别计算每个部门的医生和员工人数,然后将结果与 department table 合并。

注意:如果你想在一个部门没有工作人员或医生时将计数显示为零,那么你应该使用LEFT JOIN

SELECT dpt.dept_id,
       dpt.dept_name,
       num_of_doctors,
       num_of_staff
FROM   department dpt
       LEFT JOIN (SELECT Count(1) AS num_of_doctors,
                          Dept_id
                   FROM   doctors
                   GROUP  BY DEPT_ID) dct
               ON dpt.DEPT_ID = dct.Dept_id
       LEFT JOIN (SELECT Count(1) AS num_of_staff,
                          DEPT_ID
                   FROM   staff
                   GROUP  BY DEPT_ID) stf
               ON stf.Dept_id = dpt.DEPT_ID
WITH dct_cnt AS (
    SELECT
        dpt.dept_id
        , COUNT(DISTINCT dct.DOCT_ID) num_of_doctors
    FROM
        department dpt INNER JOIN doctors dct ON dpt.dept_id = dct.dept_id
    GROUP BY
        dpt.dept_id
), staff_cnt AS (
    SELECT
        dpt.dept_id
        , COUNT(DISTINCT stf.staff_id) num_of_staff
    FROM
        department dpt INNER JOIN staff stf ON dpt.dept_id=stf.dept_id
    GROUP BY
        dpt.dept_id
)
SELECT
    dpt.dept_id
    , dpt.dept_name
    , dct_cnt.num_of_doctors
    , staff_cnt.num_of_staff
FROM
    department dpt 
    LEFT JOIN dct_cnt ON dpt.dept_id = dct_cnt.dept_id
    LEFT JOIN staff_cnt ON dpt.dept_id = staff_cnt.dept_id