SQL 展现父子关系,你想找出子节点对应的父节点信息。例如,你希望显示每个员工及其管理者的名字。你希望返回的结果集如下所示。
SQL 展现父子关系 问题描述
你想找出子节点对应的父节点信息。例如,你希望显示每个员工及其管理者的名字。你希望返回的结果集如下所示。
SQL 展现父子关系 解决方案
基于 MGR
和 EMPNO
对 EMP
表做自连接查询,找出每个员工的管理者的名字。然后使用数据库提供的字符串连接函数生成符合要求的字符串。
DB2、Oracle 和 PostgreSQL
自连接 EMP
表。然后使用双竖线||
连接字符串。
MySQL
自连接 EMP
表,然后使用 CONCAT
函数连接字符串。
SQL Server
自连接 EMP
表,然后使用加号“+
”连接字符串。
SQL 展现父子关系 扩展知识
以上所有解决方案的实现思路大致相同。不同之处仅在于字符串连接的方式,所以下面的讨论能够兼顾到所有的解决方案,不用再一一解释每一个具体的做法。
基于 MGR
和 EMPNO
的连接查询是关键所在。首先通过自连接 EMP
表创建一个笛卡儿积(下面只显示了笛卡儿积返回值的一部分)。
如上所示,笛卡儿积返回了每一种可能的 EMPNO/EMPNO
组合。(这样看起来所有人都是 EMPNO 7369
的管理者,甚至也包括 7369
本人。)
下一步要过滤结果集,以便只返回每个员工及其管理者的 EMPNO
。增加 MGR
和 EMPNO
相等的判断条件即可。
现在已经得到了每个员工及其管理者的 EMPNO
,接下来只要查询 B.ENAME
提取出每个管理者的名字即可。如果你还没有完全理解本解决方案的原理,那么可以先忽略自连接方案,转而尝试下面的标量子查询方案。
上述标量子查询方案实际上等价于自连接方案,只有一行数据除外:员工 KING 出现在了结果集里,而自连接方案的查询结果里却不包括该员工。你可能会问:“为什么不会包括?”注意,Null
不等于任何值,甚至不等于它自身。在自连接解决方案中,我们基于 EMPNO
和 MGR
做相等连接查询(equi-join),这就剔除了 MGR
值等于 Null
的员工。如果既使用自连接方案,又希望员工 KING 出现在最终的结果集里,就必须使用外连接,就像下面的两种查询那样。第一种解决方案使用了 ANSI 外连接,第二种则用了 Oracle 的外连接语法。这两种解决方案的结果自然是相同的,我们把输出结果放在了第二个方案的后面。