sql 中 substring 用法_sql 中 substring 截取子串教程

这是一个陷阱。
省略SUBSTRING中的长度参数可能会导致获取的内容过多。

SQL递归查询实现 SQL递归CTE完整教程

说实话,当我第一次开始学习递归 CTE 时,我对它感到困惑。
后来我不得不将它用于一个项目,所以我硬着头皮想出来了。
说白了,这是SQL自己玩弄自己,就像一层一层剥洋葱一样,特别适合处理分层数据。

举组织架构的例子是最直观的。
例如,我们公司有一个员工表,只有几列:employee_id(员工编号)、employee_name(姓名)和manager_id(直接经理编号)。
现在老板要你查某个人,比如张三,列出他所有的下属,标明关系级别。
使用递归CTE就是这么简单:
sql 带递归下属AS( -
初步查询:先找到张三的直属下属 SELECT 员工 ID、员工姓名、经理 ID、1 AS 级别 来自员工 WHERE manager_id = (SELECTemployee_idFROMemployeesWHEREemployee_name='张三') 优联 -
递归查询:将上一轮的下属视为领导者,然后找到其下属 SELECT e.employee_id、e.employee_name、e.manager_id、s.level + 1 来自员工 e INNER JOIN 子级 s ON e.manager_id = s.employee_id ) -
最后选择所有下属信息 从孩子中选择;
这里的要点是什么?第一个查询选择一个起点,例如 CEO 或特定员工。
然后使用 UNION ALL 将结果连接到递归查询,该查询引用刚刚创建的坐标表。
每次递归都会将级别增加 1 ,直到不再有子级。

但是使用时要小心:如果终止条件写得不好,SQL真的会陷入死循环,最终报错。
我曾经有一个实习生在编写代码时忘记添加 WHERE level <= 5 限制。
结果程序跑了一夜,差点把服务器搞崩溃。

性能也是一个障碍。
我测试过,在公司老系统中,用递归CTE来检查几百人的层级关系,数据库有点摇摇欲坠。
后来我改用WITH NOLOCK语句来添加索引,速度变得更快了。
所以我在这方面的经验是:不会用就不要用,尤其是2 01 2 年之前的SQL Server版本,根本不支持递归CTE。

有趣的是,现在有些场景实际上可以使用临时表+循环来代替。
例如,使用 T-SQL 您可以执行以下操作:
sql DECLARE @employee_id INT = (SELECTemployee_idFROMemployeesWHEREemployee_name='张三'); 声明@level INT = 1 ; 声明@max_level INT = 1 0; -
防止无限循环
;WITH下属CTE AS ( SELECT 员工 ID、员工姓名、经理 ID、@level AS 级别 来自员工 其中 manager_id = @employee_id 联合所有 选择 e.employee_id、e.employee_name、e.manager_id、@level + 1 来自员工 e INNER JOIN 下属CTE ON e.manager_id = 下属CTE.employee_id 其中 @level < @max_level ) 从子CTE中选择;
但说实话,写了太多,我还是觉得递归CTE更优雅。
尤其是跨数据库移植时,可以直接使用PostgreSQL和MySQL 8 .0+,更改变得简单。
Oracle的用法类似,但语法关键字略有不同。

我在调试时有一个小技巧:向 CTE 添加一个计数器,比如 level,并在每次重复时打印它。
或者使用SQL Server的查询分析器,它有一个显示递归执行计划的功能,非常有用。
我记得有一次我更改了CTE并添加了WHERE级别<3>结果发现数据表中有一个隐藏的退休员工在循环中运行,这几乎造成了一个大错误。

最后,说实话,递归CTE是一项技术活。
如果你用得好,你会让你的老板大吃一惊,但如果你用得不好……哈哈。
我见过的最离谱的用法是查看树形数据,递归查看部门下的所有项目,然后加入预算表,最后创建动态仪表盘。
SQL写起来比代码长,但是效果很好。
不过这类工作现在都外包给BI工具了,不会用就少用吧。

一文讲懂SQL子查询

WHERE中可以输入子查询,结果可以作为条件。
例:勾选“宁乙”后出生的,先勾选生日,然后输入WHERE。
错误:聚合函数无法直接选择多列,需添加GROUP BY。
修复:使用子查询结果建表,FROM后添加别名。
作业:检查学生的主要教师信息,删除重复项,然后按 WHERE 教师进行筛选。