SQL SELF JOIN:自连接

1年前 (2024-04-27)
SQL SELF JOIN 用于将一个表和自身连接,就好像存在两个表一样。为了区分两个表,在 SQL 语句中需要少重名一个表。

自连接通常用于将表的某个字段与该表的同一字段的其它值进行比较。

语法

SELF JOIN 的基本语法如下:

SELECT a.column1, b.column1...

FROM table1 AS a, table1 AS b

WHERE a.common_column < 网站站点" rel="nofollow" />

+----+----------+-----+-----------+----------+

| ID | NAME | AGE | ADDRESS | SALARY |

+----+----------+-----+-----------+----------+

| 1 | Ramesh | 32 | Ahmedabad | 2000.00 |

| 2 | Khilan | 25 | Delhi | 1500.00 |

| 3 | kaushik | 23 | Kota | 2000.00 |

| 4 | Chaitali | 25 | Mumbai | 6500.00 |

| 5 | Hardik | 27 | Bhopal | 8500.00 |

| 6 | Komal | 22 | MP | 4500.00 |

| 7 | Muffy | 24 | Indore | 10000.00 |

+----+----------+-----+-----------+----------+

现在,让我们使用 SELF JOIN 来比较 SALARY 字段,找到比某个客户工资低的其它所有客户,如下所示:

SQL> SELECT a.ID, a.NAME, a.SALARY, b.NAME AS THIS_NAME, b.SALARY AS THIS_SALARY

FROM CUSTOMER AS a, CUSTOMER AS b

WHERE a.SALARY < b.SALARY;

执行结果如下:

+----+----------+--------+-----------+-------------+

| ID | NAME | SALARY | THIS_NAME | THIS_SALARY |

+----+----------+--------+-----------+-------------+

| 2 | Khilan | 1500 | Ramesh | 2000 |

| 2 | Khilan | 1500 | Kaushik | 2000 |

| 1 | Ramesh | 2000 | Chaitali | 6500 |

| 2 | Khilan | 1500 | Chaitali | 6500 |

| 3 | Kaushik | 2000 | Chaitali | 6500 |

| 6 | Komal | 4500 | Chaitali | 6500 |

| 1 | Ramesh | 2000 | Hardik | 8500 |

| 2 | Khilan | 1500 | Hardik | 8500 |

| 3 | Kaushik | 2000 | Hardik | 8500 |

| 4 | Chaitali | 6500 | Hardik | 8500 |

| 6 | Komal | 4500 | Hardik | 8500 |

| 1 | Ramesh | 2000 | Komal | 4500 |

| 2 | Khilan | 1500 | Komal | 4500 |

| 3 | Kaushik | 2000 | Komal | 4500 |

| 1 | Ramesh | 2000 | Muffy | 10000 |

| 2 | Khilan | 1500 | Muffy | 10000 |

| 3 | Kaushik | 2000 | Muffy | 10000 |

| 4 | Chaitali | 6500 | Muffy | 10000 |

| 5 | Hardik | 8500 | Muffy | 10000 |

| 6 | Komal | 4500 | Muffy | 10000 |

+----+----------+--------+-----------+-------------+

从执行结果可以发现,SELF JOIN 以右表为主,它先将左表中的每一行与右表中的行进行比较,然后再将左表中的行与右表中的第二行进行比较,以此类推,直到右表的一行。

示例2

现在有如下所示的员工表,名字为 employee:

+----+----------+-----+--------+------------+

| id | name | sex | salary | manager_id |

+----+----------+-----+--------+------------+

| 1 | joe | m | 7000 | 3 |

| 2 | henry | m | 8000 | 4 |

| 3 | sam | f | 6000 | NULL |

| 4 | max | m | 9000 | NULL |

| 5 | ramesh | m | 7500 | 3 |

| 6 | khilan | f | 11500 | 4 |

| 7 | Chaitali | m | 8600 | 4 |

| 8 | Komal | f | 7800 | 4 |

+----+----------+-----+--------+------------+

现在,让我们使用 SELF JOIN 找出工资超过各自经理的员工姓名:

SELECT e1.name AS employee_name, e1.salary, e2.name AS manager_name, e2.salary

FROM employee AS e1, employee AS e2

WHERE e1.manager_id = e2.id

AND e1.salary > e2.salary;

运行结果:

+---------------+--------+--------------+--------+

| employee_name | salary | manager_name | salary |

+---------------+--------+--------------+--------+

| joe | 7000 | sam | 6000 |

| ramesh | 7500 | sam | 6000 |

| khilan | 11500 | max | 9000 |

+---------------+--------+--------------+--------+

示例3

现在有如下所示的用户表,名字为 user:

+----+------------+-----------------+--------------------------+-------------+-----------------+

| id | username | password | email | cellphone | ip |

+----+------------+-----------------+--------------------------+-------------+-----------------+

| 1 | mozhiyan | 123456 | java@biancheng网站站点" rel="nofollow" />

DELETE u1 FROM user AS u1, user AS u2 WHERE u1.email = u2.email AND u1.id > u2.id;

执行完该语句,user 表的数据如下:

+----+------------+-----------+--------------------------+-------------+-----------------+

| id | username | password | email | cellphone | ip |

+----+------------+-----------+--------------------------+-------------+-----------------+

| 1 | mozhiyan | 123456 | java@biancheng网站站点" rel="nofollow" />