Mysql 如何在emp表中根据员工层次结构进行排名
我有emp表,金是公司的首席执行官,他没有经理。 国王应该获得“1”级。 金是琼斯、克拉克、布莱克的经理。因此,这些将获得排名“2”……等等 emp和经理关系的中间表:Mysql 如何在emp表中根据员工层次结构进行排名,mysql,sql,oracle,Mysql,Sql,Oracle,我有emp表,金是公司的首席执行官,他没有经理。 国王应该获得“1”级。 金是琼斯、克拉克、布莱克的经理。因此,这些将获得排名“2”……等等 emp和经理关系的中间表: empno ename mgr 7566 JONES KING 7782 CLARK KING 7698 BLAKE KING 7900 JAMES BLAKE 7844 TURNER BLAKE 7654 MARTIN BLAKE 7521 WARD
empno ename mgr
7566 JONES KING
7782 CLARK KING
7698 BLAKE KING
7900 JAMES BLAKE
7844 TURNER BLAKE
7654 MARTIN BLAKE
7521 WARD BLAKE
7499 ALLEN BLAKE
7934 MILLER CLARK
7902 FORD JONES
7788 SCOTT JONES
7876 ADAMS SCOTT
7369 SMITH FORD
7839 KING NULL
最终输出应如下所示:
mgr rank
KING 1
JONES 2
CLARK 2
BLAKE 2
JAMES 3
TURNER 3
MARTIN 3
WARD 3
ALLEN 3
MILLER 3
SCOTT 3
FORD 3
ADAMS 4
SMITH 4
提前谢谢。我希望这件事在甲骨文中完成。过去我花了一段时间才对继承权的问题了如指掌。。。然而,一旦你花时间去摆弄它们,它们通常就没有那么难对付了
SQL> with w_data as (
2 select 7566 empno, rtrim('JONES ') ename, rtrim('KING ') mgr from dual union all
3 select 7782 empno, rtrim('CLARK ') ename, rtrim('KING ') mgr from dual union all
4 select 7698 empno, rtrim('BLAKE ') ename, rtrim('KING ') mgr from dual union all
5 select 7900 empno, rtrim('JAMES ') ename, rtrim('BLAKE') mgr from dual union all
6 select 7844 empno, rtrim('TURNER') ename, rtrim('BLAKE') mgr from dual union all
7 select 7654 empno, rtrim('MARTIN') ename, rtrim('BLAKE') mgr from dual union all
8 select 7521 empno, rtrim('WARD ') ename, rtrim('BLAKE') mgr from dual union all
9 select 7499 empno, rtrim('ALLEN ') ename, rtrim('BLAKE') mgr from dual union all
10 select 7934 empno, rtrim('MILLER') ename, rtrim('CLARK') mgr from dual union all
11 select 7902 empno, rtrim('FORD ') ename, rtrim('JONES') mgr from dual union all
12 select 7788 empno, rtrim('SCOTT ') ename, rtrim('JONES') mgr from dual union all
13 select 7876 empno, rtrim('ADAMS ') ename, rtrim('SCOTT') mgr from dual union all
14 select 7369 empno, rtrim('SMITH ') ename, rtrim('FORD ') mgr from dual union all
15 select 7839 empno, rtrim('KING ') ename, NULL mgr from dual
16 )
17 select empno, ename, mgr, level
18 from w_data
19 connect by mgr = PRIOR ename
20 start with mgr IS NULL
/
21
EMPNO ENAME MGR LEVEL
---------- ------ ----- ----------
7839 KING 1
7698 BLAKE KING 2
7499 ALLEN BLAKE 3
7900 JAMES BLAKE 3
7654 MARTIN BLAKE 3
7844 TURNER BLAKE 3
7521 WARD BLAKE 3
7782 CLARK KING 2
7934 MILLER CLARK 3
7566 JONES KING 2
7902 FORD JONES 3
EMPNO ENAME MGR LEVEL
---------- ------ ----- ----------
7369 SMITH FORD 4
7788 SCOTT JONES 3
7876 ADAMS SCOTT 4
14 rows selected.
SQL>
- w_数据只是为了伪造你的测试数据
- 按管理器连接=先前的ename 这将获取每条记录,并将经理与上一级员工进行比较
- “以mgr开头”为空 这告诉甲骨文从哪里开始
- 等级是继承权的深度
ORDER BY
子句中的情况。大概是这样的:
SELECT [blah]
FROM [intermediate tbl]
ORDER BY
CASE WHEN mgr IS NULL THEN 1
CASE WHEN mgr = 'KING' THEN 2
... ELSE ... END
我相信在Oracle中有一种更短的方法可以做到这一点(我的经验是使用SSMS):
在Oracle文档中搜索connectby
子句和名为LEVEL
的伪列。您列出了两种不同的RDBMS,这到底是用于哪个数据库,还是必须与数据库无关?SQL语法将因引擎而异。对于MySQL,没有办法。connect by是Oracle的专有扩展,也不支持recursice CTE(SQL标准)。使用用户变量和临时表,我相信在mySQL中可能有一种方法可以做到这一点。但不是在一条语句中。@xQbert我标记了msql以获取与引擎相关的特定命令以外的任何逻辑。正如我在问题中提到的,我更喜欢用甲骨文来回答。谢谢。今天我学习了新的子句连接方式,从开始。我想知道如果没有这个CONNECT BY子句,我们如何实现分层查询。我用您的输入得到了最终查询。查询是:SELECT empno,ename,mgr,LEVEL FROM emp CONNECT BY previor empno=mgr START WITH mgr is null
使用递归公共表表达式也可以,但mySQL不支持它们。Oracle在较新版本中也有。@Naveen:我相信“递归子查询分解”也可以做到,但是,我仍然在努力解决这个问题以及O.O(基本上,它是一个自我引用的with子句…),谢谢你的回复。这是一个通用的,我使用CONNECT BY子句得到了答案。
ORDER BY decode(mgr, 'NULL', 1, 'KING', 2, ...)