MySQL 列出相关依赖

注释齐全,可以用来学习存储过程的条件和循环、SQL条件

结果展示

DROP TABLE IF EXISTS test.job_depend;
# 创建测试表
CREATE TABLE `job_depend` (
  `sn_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '行号',
  `job_id` varchar(20) DEFAULT NULL COMMENT '作业ID',
  `depend_job_id` varchar(20) DEFAULT NULL COMMENT '依赖作业',
  PRIMARY KEY (`sn_id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 COMMENT='作业依赖';

# 插入测试数据
INSERT INTO test.job_depend (job_id, depend_job_id) VALUES ('b', 'a');
INSERT INTO test.job_depend (job_id, depend_job_id) VALUES ('c', 'b');
INSERT INTO test.job_depend (job_id, depend_job_id) VALUES ('c', 's');
INSERT INTO test.job_depend (job_id, depend_job_id) VALUES ('s', 'c');

# 若存储过程存在则删除
DROP PROCEDURE IF EXISTS dep;
# 创建一个存储过程
CREATE PROCEDURE dep(jobId VARCHAR(21845))
  # 开始内容
  BEGIN
    # 定义一个变量存储合并后的字符串(逗号分隔)
    DECLARE childs VARCHAR(21845);
    # 定义一个变量存储当前查到的字符串(逗号分隔)
    DECLARE ids VARCHAR(21845);
    # 初始化字符串
    SET childs = '';

    # 逗号分隔拼接字符串,支持查到多个
    # INTO 放入 JobId
    # 拼接 % 使自带 like 模糊查找
    SELECT DISTINCT group_concat(job_id)
    INTO jobId
    FROM job_depend
    WHERE job_id LIKE concat('%', jobId, '%');

    SET ids = jobId;

    # 当前查到的字符串不为空时
    WHILE ids IS NOT NULL DO
      # 拼接字符串
      SET childs = concat(ids, ',', childs);

      # SELECT 不重复 拼接字段,默认逗号分隔
      # INTO 放入 当前查找的字符串
      # WHERE (查找值, 字符串集合) 且没有在合并字符串
      SELECT DISTINCT group_concat(depend_job_id)
      INTO ids
      FROM job_depend
      WHERE find_in_set(job_id, ids) > 0
            AND NOT find_in_set(depend_job_id, childs);
    END WHILE;

    SET ids = jobId;

    # 反过来查找依赖 ids 的
    WHILE ids IS NOT NULL DO
      SELECT DISTINCT group_concat(job_id)
      INTO ids
      FROM job_depend
      WHERE find_in_set(depend_job_id, ids) > 0
            AND NOT find_in_set(job_id, childs);
      IF ids IS NOT NULL THEN
        SET childs = concat(childs, ',', ids);
      END IF;
    END WHILE;

    SELECT
      # DISTINCT
      # 如果 job_id 是查询传入的 jobId
      # SQL 下的 IF 条件写法
      CASE find_in_set(job_id, jobId) > 0
      # 为真 则标记 =>
      WHEN TRUE THEN '=>'
      # 否则不显示任何内容
      ELSE '' END AS f,
      job_id,
      depend_job_id
    FROM job_depend
    WHERE find_in_set(job_id, childs)
    # 按下面依赖上面排序(需查找位置的子字符串, 大字符串)
    ORDER BY instr(job_id, jobId);
  END;

# 使用例子
CALL dep('c');

# 查询本程序
SELECT
  SPECIFIC_NAME,
  ROUTINE_TYPE
FROM information_schema.ROUTINES
WHERE SPECIFIC_NAME = 'dep';

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏编程心路

写给新手的Mysql入门指南(一)

关键字最好大写,这样便于阅读。可以用windows的cmd运行工具对数据库操作,前提是mysql的安装目录的子目录bin的路径添加导论系统变量PATH中,mys...

17530
来自专栏别先生

MYSQL子查询与连接

37:子查询与连接 SET 列名 gbk;//改变客户端数据表的编码类型。 子查询 子查询(Subquery)是指出现在其他SQL语句内的SELECT子句 例...

26450
来自专栏butterfly100

mysql explain详解

Explain简介 本文主要讲述如何通过 explain 命令获取 select 语句的执行计划,通过 explain 我们可以知道以下信息:表的读取顺序,数据...

1.8K100
来自专栏性能与架构

MySQL中索引的限制

下面列出了目前 MySQL中与索引使用相关的限制 (1)MyISAM存储引擎索引键长度的总和不能超过1000字节 (2)BLOB和TEXT类型的列只能创建前缀索...

28250
来自专栏Python、Flask、Django

MySQL 本科班学习汇总

10040
来自专栏公众号_薛勤的博客

MySQL常用SQL语句/函数/存储过程

你可以使用 ASC 或 DESC 关键字来设置查询结果是按升序或降序排列。 默认情况下,它是按升序排列

11220
来自专栏calmound

SQL语句知识点

PERSON表 NUMBER NAME SEX AGE 1 THERON male 19 2 JACK male 20 3 LUCY fema...

35060
来自专栏Java架构师历程

Mysql常用查询语句

一查询数值型数据: SELECT * FROM tb_name WHERE sum > 100; 查询谓词:>,=,<,<>,!=,!>,!<,=>,=<

13020
来自专栏撸码那些事

MySQL——通过EXPLAIN分析SQL的执行计划

在MySQL中,我们可以通过EXPLAIN命令获取MySQL如何执行SELECT语句的信息,包括在SELECT语句执行过程中表如何连接和连接的顺序。

13420
来自专栏WebDeveloper

Mysql数据库应用--索引(二)

CREATE TABLE table_name [col_name data_type] [UNIQUE|FULLTEXT|SPATIAL] [INDEX|KE...

12630

扫码关注云+社区

领取腾讯云代金券