通用表表达式(CTE,COMMON TABLE EXPRESSION)
通用表表达式(CTE)是标准的SQL语法,本质上是临时命名的结果集。CTE最初于1999年出现在SQL标准(即所谓的SQL-99标准),然而第一个实现好像是在出现在2007年的SQL Server 2008
SQL通常在面向过程的递归结构方面支持较弱,CTE允许查询引用自身。递归CTE将重复执行数据的子集,直到获得完整的结果集。这对于处理分层或树状数据特别有用。
目前主流数据库平台都已支持CTE语法,只是在数据类型和函数等细节方面存在细微差异,影响不大。国产的达梦数据库从7.0开始也支持了CTE语法,点赞!
按照SQL标准写,就是舒服,建议使用符合标准SQL,而非方言。
SQL Server
-- 递归所有下级
WITH --RECURSIVE cte1 AS ( SELECT g.* , cast (g.name_chs as varchar(1000)) as full_name , (ROW_NUMBER() over(order by g.sortorder)) * POWER(10, 5) as order_num , 5 as levelId from gspfunc g where g.id = 'HIP' UNION ALL SELECT g.* , cast(cte1.full_name + '-' + g.name_chs as varchar(1000)) as full_name , order_num + (ROW_NUMBER() over(order by g.sortorder) * POWER(10, levelid-1)) as order_num , levelid - 1 as levelid FROM cte1 join gspfunc g ON g.parentid = cte1.id ) SELECT id, code, name_chs, full_name, path, order_num, levelid , * FROM cte1 order by cte1.order_num; -- 递归找上级 WITH --RECURSIVE cte1 AS ( SELECT g.*, cast (g.name_chs as varchar(1000)) as full_name FROM gspfunc g WHERE g.code = 'service-status-monitor' UNION ALL SELECT g.*, cast(cte1.full_name + '-' + g.name_chs as varchar(1000)) as full_name FROM cte1 join gspfunc g ON g.id = cte1.parentid ) SELECT id, code, name_chs, full_name , path, * FROM cte1 ORDER BY cte1.full_name;
Oracle、DM
WITH --RECURSIVE cte1(id, code, name_chs, parentid, full_name) AS ( SELECT g.id, g.CODE , g.NAME_CHS , g.PARENTID , cast (g.name_chs as varchar(1000)) as full_name from gspfunc g where g.id = 'HIP' UNION ALL SELECT g.id, g.CODE, g.NAME_CHS , g.PARENTID , cast(cte1.full_name || '-' || g.name_chs as varchar(1000)) as full_name FROM cte1 join gspfunc g ON g.parentid = cte1.id ) SELECT id, code, name_chs, PARENTID , full_name FROM cte1 ORDER BY cte1.full_name;
MySQL
WITH RECURSIVE cte1 AS ( SELECT g.id, g.CODE , g.NAME_CHS , g.PARENTID , cast(g.name_chs as char(1000)) as full_name from gspfunc g where g.id = 'HIP' UNION ALL SELECT g.id, g.CODE, g.NAME_CHS , g.PARENTID , CONCAT(cte1.full_name , '-' , g.name_chs) as full_name FROM cte1 join gspfunc g ON g.parentid = cte1.id ) SELECT id, code, name_chs, PARENTID, full_name FROM cte1 ORDER BY cte1.full_name;
PostgreSQL
WITH RECURSIVE cte1 AS ( SELECT g.id, g.CODE , g.NAME_CHS , g.PARENTID , cast(g.name_chs as varchar(1000)) as full_name from gspfunc g where g.id = 'HIP' UNION ALL SELECT g.id, g.CODE, g.NAME_CHS , g.PARENTID , cast(cte1.full_name || '-' || g.name_chs as varchar(1000)) as full_name FROM cte1 join gspfunc g ON g.parentid = cte1.id ) SELECT id, code, name_chs, PARENTID, full_name FROM cte1 ORDER BY cte1.full_name;