SQL |唯一约束
SQL 约束
SQL 中的唯一约束用于检查子查询的结果中是否有重复的元组。它返回一个布尔值,指示重复元组的存在/不存在。只有当子查询没有重复的元组时,唯一构造才返回 true,否则返回 false。
要点:
- 在空子查询上评估为真。
- 仅当存在作为子查询的输出的唯一元组时才返回 true(如果两个元组的任何属性的值不同,则两个元组是唯一的)。
- 如果子查询具有至少一个属性为 NULL 的两个重复行,则返回 true。
句法:
SELECT table.ID
FROM table
WHERE UNIQUE (SELECT table2.ID
FROM table2
WHERE table.ID = table2.ID);
注意:在执行期间,首先评估外部查询以获取 table.ID。在此之后,内部子查询被处理,它产生一个新的关系,其中包含内部查询的输出,例如 table.ID == table2.ID。如果新关系中的每一行都是唯一的,则 unique 返回 true,并且将相应的 table.ID 作为元组添加到生成的输出关系中。但是,如果新关系中的每一行都不是唯一的,则 unique 评估为 false 并且相应的 table.ID 不会添加到输出关系中。
当且仅当存在两个元组 t1 和 t2 使得 t1 = t2 时,应用于子查询的唯一性返回 false。它认为 t1 和 t2 是两个不同的元组,当 unique 应用于包含 t1 和 t2 的子查询时,t1 = t2 并且这些元组的至少一个属性包含 NULL 值。在这种情况下,唯一谓词的计算结果为真。这是因为,SQL 中的 NULL 值被视为未知值,因此,两个 NULL 值被认为是不同的。
注意:没有 UNIQUE 子句的 SQL 语句也可以写成:
SELECT table.ID
FROM table
WHERE 1 <= (SELECT count(table2.ID)
FROM table2
WHERE table.ID = table2.ID);
查询
示例 1:查找 2017 年最多教授一门课程的所有教师。
导师关系:
EmployeeID | Name | CourseID | Year |
---|---|---|---|
77505 | Alan | SC110 | 2017 |
77815 | Will | CSE774 | 2017 |
85019 | Smith | EE457 | 2017 |
92701 | Sam | PYS504 | 2017 |
60215 | Harold | HSS103 | 2016 |
77505 | Alan | BIO775 | 2017 |
92701 | Sam | ECO980 | 2017 |
- SQL查询:
SELECT I.EMPLOYEEID, I.NAME
FROM Instructor as I
WHERE UNIQUE (SELECT Inst.EMPLOYEEID
FROM Instructor as Inst
WHERE I.EMPLOYEEID = Inst.EMPLOYEEID
and Inst.YEAR = 2017);
输出:
EmployeeID | Name |
---|---|
77815 | Will |
85019 | Smith |
解释:在 Instructor 关系中,2017 年期间只有讲师 Will 和 Smith 教授一门课程。与这些讲师对应的子查询仅包含一个元组,因此与这些讲师对应的唯一子句评估为 true,从而产生这两个讲师在输出关系中。
示例 2:查找计算机科学系中只有一名教师分配给该课程的所有课程。
课程关系:
CourseID | Name | Department | InstructorID |
---|---|---|---|
CSE505 | Computer Network | Computer Science | 11071 |
CSE245 | Operating System | Computer Science | 74505 |
CSE101 | Programming | Computer Science | 12715 |
HSS505 | Psychology | Social Science | 85017 |
EE475 | Signals & Systems | Electrical | 22150 |
CSE314 | DBMS | Computer Science | 44704 |
CSE505 | Computer Network | Computer Science | 11747 |
CSE314 | DBMS | Computer Science | 44715 |
- SQL查询:
SELECT C.COURSEID, C.NAME
FROM Course as C
WHERE UNIQUE (SELECT T.INSTRUCTORID
FROM Course as T
WHERE T.COURSEID = C.COURSEID
and C.DEPARTMENT = 'Computer Science');
输出:
COURSEID | Name |
---|---|
CSE245 | Operating System |
CSE101 | Programming |
说明:在课程关系中,计算机科学系唯一分配一名讲师的课程是操作系统和编程。这两个课程对应的唯一约束只有一个由相应的讲师组成的元组。因此,这两个课程的唯一子句评估为真,并且这些课程显示在输出关系中。 Course 关系中的其他课程要么有两个或多个讲师,要么不属于计算机科学系,因此这些课程不会显示在输出关系中。