关系代数详解与SQL示例

关系代数详解与SQL示例

关系代数是关系数据库的理论基础,它提供了一组操作符用于操作关系(表)


1. 基本操作

1.1 选择 (Selection, σ)

选择操作从关系中选择满足特定条件的元组(行)。

关系代数表示:σ条件(R)

SQL示例

-- 选择年龄大于30的员工
SELECT * FROM Employees WHERE age > 30;

1.2 投影 (Projection, π)

投影操作从关系中选择特定的属性(列)。

关系代数表示:π属性列表(R)

SQL示例

-- 选择员工的姓名和部门
SELECT name, department FROM Employees;

1.3 并集 (Union, ∪)

并集操作合并两个相容关系(相同属性)的所有元组,去除重复。

关系代数表示:R ∪ S

SQL示例

-- 合并两个部门的员工列表
SELECT * FROM Dept1_Employees
UNION
SELECT * FROM Dept2_Employees;

1.4 差集 (Set Difference, -)

差集操作返回在第一个关系但不在第二个关系中的元组。

关系代数表示:R - S

SQL示例

-- 找出在Dept1但不在Dept2的员工
SELECT * FROM Dept1_Employees
EXCEPT
SELECT * FROM Dept2_Employees;

1.5 笛卡尔积 (Cartesian Product, ×)

笛卡尔积操作返回两个关系的所有可能组合。

关系代数表示:R × S

SQL示例

-- 员工和部门的笛卡尔积
SELECT * FROM Employees, Departments;

1.6 重命名 (Rename, ρ)

重命名操作改变关系的名称或属性名称。

关系代数表示:ρ新名称(R)

SQL示例

-- 重命名表和列
SELECT emp_id AS employee_id, name AS employee_name FROM Employees AS Emp;

2. 派生操作

2.1 连接 (Join, ⋈)

连接操作是选择+笛卡尔积的组合,根据条件连接两个关系。

关系代数表示:R ⋈条件 S

SQL示例

-- 内连接:员工和他们的部门信息
SELECT * FROM Employees E JOIN Departments D ON E.dept_id = D.dept_id;

-- 自然连接(自动匹配同名属性)
-- 注意:SQL没有直接的自然连接语法,但可以模拟
SELECT E.*, D.department_name 
FROM Employees E JOIN Departments D USING (dept_id);

2.2 交 (Intersection, ∩)

交操作返回同时在两个关系中的元组。

关系代数表示:R ∩ S

SQL示例

-- 找出同时在两个部门的员工
SELECT * FROM Dept1_Employees
INTERSECT
SELECT * FROM Dept2_Employees;

2.3 除法 (Division, ÷)

除法操作返回满足特定条件的元组,常用于"全部"类查询。

关系代数表示:R ÷ S

SQL示例

-- 找出选修了所有必修课的学生
-- 关系代数: π_student_id,course_id(Enrollment) ÷ π_course_id(RequiredCourses)
SELECT DISTINCT student_id 
FROM Enrollment E1
WHERE NOT EXISTS (
    SELECT course_id FROM RequiredCourses
    EXCEPT
    SELECT course_id FROM Enrollment E2 
    WHERE E2.student_id = E1.student_id
);

3. 高级操作

3.1 θ-连接 (Theta Join)

基于任意条件的连接操作。

SQL示例

-- 找出工资高于经理的员工
SELECT E1.* 
FROM Employees E1 JOIN Employees E2 
ON E1.manager_id = E2.emp_id AND E1.salary > E2.salary;

3.2 半连接 (Semi Join)

只返回左关系中能与右关系连接的元组。

SQL示例

-- 找出有下属的经理
SELECT DISTINCT M.*
FROM Employees M
WHERE EXISTS (
    SELECT 1 FROM Employees E 
    WHERE E.manager_id = M.emp_id
);

3.3 反连接 (Anti Join)

返回左关系中不能与右关系连接的元组。

SQL示例

-- 找出没有下属的员工
SELECT E.*
FROM Employees E
WHERE NOT EXISTS (
    SELECT 1 FROM Employees M 
    WHERE M.manager_id = E.emp_id
);

4. 聚合操作

关系代数扩展包括聚合函数。

SQL示例

-- 计算每个部门的平均工资
SELECT department, AVG(salary) 
FROM Employees 
GROUP BY department;

-- 关系代数表示: γ(Employees)

5. 综合示例

查询:找出工资高于部门平均工资的员工

-- 使用关系代数可以表示为:
-- π_E.* (σ_E.salary > avg_salary (E ⋈ dept_id=dept_id γ_dept_id; AVG(salary)→avg_salary(E)))

-- SQL实现:
SELECT E.*
FROM Employees E
JOIN (
    SELECT dept_id, AVG(salary) AS avg_salary
    FROM Employees
    GROUP BY dept_id
) D ON E.dept_id = D.dept_id
WHERE E.salary > D.avg_salary;

关系代数为SQL提供了理论基础,理解关系代数有助于编写更高效、更准确的SQL查询。

你可能感兴趣的:(数据库,sql,数据库)