SQL Server查询:如何根据条件返回值集?

时间:2012-02-07 17:11:49

标签: sql sql-server sql-server-2008-r2

考虑以下场景(有点人为,但不如我正在努力的真实场景那么复杂):

拥有在线文档管理系统的大学希望限制哪些教授可以查看哪些文档。有些教授可以看到属于任何部门的文件,但有些教授只能看到属于特定部门的文件。

这是架构:

create table Professors (
    ProfessorId int primary key,
    ProfessorName varchar(50)
);

create table Departments (
    DepartmentId int primary key,
    DepartmentName varchar(50)
);

create table ProfessorDepartments (
    ProfessorId int,
    DepartmentId int
);

insert into Professors values (1, 'Professor A'), (2, 'Professor B');
insert into Departments values (1, 'Chemistry'), (2, 'Computer Science'), (3, 'Math'), (4, 'Physics');
insert into ProfessorDepartments values (1,2), (1,3);

这里有一个棘手的部分:无限制访问的教授教授部门表中没有列出任何部门。 (这样,教授会自动获得任何新部门的访问权。)

如何获取特定教授允许的部门列表?如果教授访问受限,则列表需要来自ProfessorDepartments表,如果教授具有不受限制的访问权限,则需要来自Departments表。

5 个答案:

答案 0 :(得分:3)

SELECT
  Professors.ProfessorName,
  Departments.DepartmentName
FROM
  Professors
LEFT JOIN
  ProfessorDepartments
    ON Professors.ProfessorId = ProfessorDepartments.ProfessorId
LEFT JOIN
  Departments
    ON ProfessorDepartments.DepartmentId = Departments.DepartmentId
    OR ProfessorDepartments.DepartmentId  IS NULL

答案 1 :(得分:2)

SELECT Professors.ID as ProfessorID, Departments.ID as DepartmentID, 
    Professors.ProfessorName, Departments.DepartmentName
FROM Professors
    LEFT OUTER JOIN ProfessorDepartments ON ProfessorDepartments.ProfessorID=Professors.ID
    LEFT OUTER JOIN Departments ON ProfessorDepartments.DepartmentID IS NULL OR 
        ProfessorDepartments.DepartmentID=Departments.ID

应该做的伎俩

答案 2 :(得分:1)

Dems的回答看起来就像是最好的。

这是我的尝试。

SELECT 
    p.ProfessorName, d.DepartmentName
FROM #Professors p
CROSS JOIN #departments d
WHERE NOT EXISTS (
    SELECT * FROM #ProfessorDepartments pd WHERE pd.ProfessorId = p.ProfessorId)

UNION ALL

SELECT p.ProfessorName, d.DepartmentName
FROM #Professors p
INNER JOIN #ProfessorDepartments pd
ON pd.ProfessorId = p.ProfessorId
INNER JOIN #Departments d
ON d.DepartmentId = pd.DepartmentId

答案 3 :(得分:0)

我可能不完全理解你的问题,但是这个怎么样:

SELECT P.ProfessorName
        ,CASE WHEN D.DepartmentName IS NULL THEN 'Unrestricted Access' ELSE D.DepartmentName END
FROM Professors P LEFT OUTER JOIN ProfessorDepartments PD ON
    P.ProfessorId = PD.ProfessorId
    LEFT OUTER JOIN Departments D ON
        PD.DepartmentId = D.DepartmentId

修改

在看到Will的解决方案后,我更新了我的脚本:

SELECT P.ProfessorName, D.DepartmentName
FROM Professors P 
        LEFT OUTER JOIN ProfessorDepartments PD ON P.ProfessorId = PD.ProfessorId
        LEFT OUTER JOIN Departments D ON PD.DepartmentId IS NULL OR PD.DepartmentId = D.DepartmentId

答案 4 :(得分:0)

你可以这样做:

declare @prof varchar(50)
select @prof = 'Professor B'

if(select count(pd.ProfessorId) from Professors p
    inner join ProfessorDepartments pd on p.ProfessorId = pd.ProfessorId
    where p.ProfessorName = @prof) = 0
begin
  select DepartmentName from Departments
end
else
begin
  select d.DepartmentName from Professors p
    inner join ProfessorDepartments pd on p.ProfessorId = pd.ProfessorId
    inner join Departments d on pd.DepartmentId = d.DepartmentId
    where p.ProfessorName = @prof
end