2012-02-07 95 views
2

考慮以下情形(有點做作,但比真實的情景,我掙扎不那麼複雜):SQL Server查詢:如何根據條件返回一組值?

與在線文件管理系統一所大學要限制其教授可以看到哪些文件。一些教授可以看到屬於任何部門的文件,但有些只能看到屬於特定部門的文件。

這裏的模式:

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表列出的任何部門。 (這樣,教授將自動進入任何新部門。)

如何獲得特定教授允許的部門列表?如果教授訪問受限,則該列表需要來自教授部門表;如果教授訪問權限不夠,則需要來自部門表。

+0

然後,如果添加了新教授的是,他將有無限制的訪問,因爲是不是在其他表吧? – 2012-02-07 17:14:05

+0

@aF。對。默認行爲是給教授不受限制的訪問權限。 – MCS 2012-02-07 17:14:55

+0

@MCS - 恕我直言,我覺得你這樣做是落後的,你應該是隱式授予訪問,而不是刪除它。 – 2012-02-07 17:27:03

回答

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 
+0

不錯。我不知道你可以在連接子句中使用OR。 – MCS 2012-02-07 17:25:34

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 

編輯

看到威爾的解決方案後,我有更新我的腳本:

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 
+1

我相信他希望各部門要返回,如果沒有相應的記錄ProfessorDepartments,不只是「無限制訪問」 – 2012-02-07 17:25:19

+0

我看到現在,這樣的話@中國aF的解決方案也正是OP所期待的。 – 2012-02-07 17:33:47

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 
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 

應該做的伎倆

+0

缺少'ON('你的第二個連接,有些領域是在一個以上的表,所以沒有指定talbe使他們模棱兩可的引用。 – MatBailie 2012-02-07 17:24:18

+0

謝謝,做我從未想過要做到這一點,很好的解決方案編輯 – 2012-02-07 17:26:56

+0

! – 2012-02-07 17:37:33

1

民主黨回答看起來像最好的之一。

這是我的嘗試。

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