SQL07 集合计算
关系除法
定义表格 R和表格S如下
R
X | Y |
---|---|
X1 | Y1 |
X2 | Y2 |
X2 | Y3 |
X2 | Y3 |
X3 | Y1 |
X3 | Y2 |
S
Y | F |
---|---|
Y1 | F1 |
Y2 | F2 |
对于拥有相同属性的关系(表)R和S 关系除法主要分为如下几步:
1.找到相同属性 Y。在关系R中对Y做投影,即取出Y的值
Y->{Y1, Y2}
2.被除关系R中与S中不相同的属性列是X,关系R在属性X上做取消重复值的投影(去重) X1,X2
3.求得关系R中X属性对应的象集,
X1->{ Y1}
X2->{Y1 ,Y2, Y3}
X3->{ Y1, Y2}
4.R div S 就是看 R中X属性对应的象集是否包含了Y的所有值,分为以下3种情况:
被除数 | 除数 | 商 | 余数 | 含义 | |
---|---|---|---|---|---|
整除 | X3 | Y | n | {} | 表R中恰好包含所有Y的X |
带余除法 | X2 | Y | n | {Y3} | 表R中包含所有Y的X |
除数集合不被被除数包含 | X1 | Y | 0 | {} | 表R中不包含所有Y的X |
下面讲讲SQL如何实现:
如上图所示,从EmpSkills中选择精通Skills 中技能的员工
上述问题可以转换为 skill 表中元素 减去员工个人技术栈的 差集为空,SQL 如下:
SELECT DISTINCT emp
FROM EmpSkills es1
WHERE NOT EXISTS
(
SELECT * FROM Skills
EXCEPT
SELECT * FROM EmpSkills es2
WHERE es1.emp=es2.emp
)
由于并不是所有的SQL引擎都支持EXCEPT运算,我们用 NOT EXISTS 实现。
SELECT DISTINCT emp
FROM EmpSkills es1
WHERE NOT EXISTS
(
SELECT * FROM Skills s1
WHERE NOT EXISTS
(
SELECT * FROM EmpSkills es2
WHERE es2.emp=es1.emp AND es2.skill=s1.skill
)
)
除此之外,还可以HAVING 子句实现
SELECT es.emp
FROM Em