mysql常见SQL语句

红太狼 2024-03-30 14:14 165阅读 0赞

1、需求

统计某个子串字符串出现的次数子串字符串中是否出现过。

2、案例

2.1 统计某个子串是否在字符串中出现过

  1. mysql> select find_in_set('02','01,02,03,04,05');
  2. +------------------------------------+
  3. | find_in_set('02','01,02,03,04,05') |
  4. +------------------------------------+
  5. | 2 |
  6. +------------------------------------+
  7. 1 row in set (0.00 sec)

find_in_set: 返回字符串列表中字符串的位置,位置从1开始。被查找的数据需要以,分隔。

2.2 统计某个子串在字符串中出现的次数

  1. length:统计的是字符串所占的字节数
  2. char_length:统计的是字符串所占的字符数
  3. 子串出现的次数= (原始字符串字符数 - (原始字符串字符数 - 替换子串后的字符串字符数))/替换子串后的字符串字符数

    mysql> select ‘01,02,03,中文,05’ ‘原始字符串’,

    1. -> length('01,02,03,中文,05') 'code字段的值所占的字节数',
    2. -> char_length('01,02,03,中文,05') 'code字段的值所占的字符数',
    3. -> charset('01,02,03,中文,05') 'code字段的字符编码,一个中文utf8mb4占3个字节',
    4. -> (char_length('01,02,03,中文,05') - char_length(replace('01,02,03,中文,05','02','')))/char_length('02') '02出现的次数';

    +—————————————————-+——————————————————+——————————————————+——————————————————————————————+—————————-+
    | 01,02,03,中文,05 | code字段的值所占的字节数 | code字段的值所占的字符数 | code字段的字符编码,一个中文utf8mb4占3个字节 | 02出现的次数 |
    +—————————————————-+——————————————————+——————————————————+——————————————————————————————+—————————-+
    | 01,02,03,中文,05原始字符串 | 18 | 14 | utf8mb4 | 1.0000 |
    +—————————————————-+——————————————————+——————————————————+——————————————————————————————+—————————-+
    1 row in set (0.00 sec)

统计某个子串在字符串中出现的次数

2.3、将一个数组字段转换成多行

通过json_table来实现。

  1. select
  2. org_no,
  3. code,
  4. substr(code, instr(code,':') + 1, instr(code,';') - instr(code,':') - 1) as '变电站名称',
  5. substr(code, instr(code,'线路名称:') + 5, instr(code,'台区名称:') - instr(code,'线路名称:') - 6) as '线路名称',
  6. substr(code, instr(code,'台区名称:') + 5) as '台区名称',
  7. concat('["', replace(substr(code, instr(code,'台区名称:') + 5), '、','","'), '"]') as '台区名称str',
  8. cast(concat('["', replace(substr(code, instr(code,'台区名称:') + 5), '、','","'), '"]') as json) as '台区名称arr',
  9. json_extract(cast(concat('["', replace(substr(code, instr(code,'台区名称:') + 5), '、','","'), '"]') as json), '$[0]') as 'first台区',
  10. tq.tq_name
  11. from test_001 t
  12. cross join json_table(
  13. cast(concat('["', replace(substr(code, instr(code,'台区名称:') + 5), '、','","'), '"]') as json),
  14. '$[*]' columns (tq_name varchar(50) path '$')
  15. ) tq
  16. where t.org_no like '42%';

将一个数组字段转换成多行

2.4、交叉连接补全数据

需求: 存在如下3个表接口,course课程表,student学生表和 score表。其中,course表中存在3门课程,student表中存在2个学生,score表中,一个学生考了一门课程,另外一个学生考了2门课程。 希望统计出每个学生在所有的课程下的得分,如果没有参加者们课程的考试,则得0分。

1 表结构

  1. CREATE TABLE `course` (
  2. `course_id` int NOT NULL AUTO_INCREMENT COMMENT '课程id',
  3. `course_name` varchar(20) DEFAULT NULL COMMENT '课程名称',
  4. PRIMARY KEY (`course_id`)
  5. ) ENGINE=InnoDB COMMENT='课程表';
  6. CREATE TABLE `score` (
  7. `score_id` int NOT NULL AUTO_INCREMENT COMMENT '分数id',
  8. `student_id` int DEFAULT NULL COMMENT '学生id',
  9. `course_id` int DEFAULT NULL COMMENT '课程id',
  10. `score` int DEFAULT NULL COMMENT '分数',
  11. PRIMARY KEY (`score_id`),
  12. UNIQUE KEY `score_score_id_uindex` (`score_id`)
  13. ) ENGINE=InnoDB COMMENT='分数表';
  14. CREATE TABLE `student` (
  15. `student_id` int NOT NULL AUTO_INCREMENT COMMENT '学生id',
  16. `student_name` varchar(20) DEFAULT NULL COMMENT '学生姓名',
  17. PRIMARY KEY (`student_id`)
  18. ) ENGINE=InnoDB COMMENT='学生表';

2 插入数据

  1. -- 添加课程
  2. insert into course values (1,'语文');
  3. insert into course values (2,'数学');
  4. insert into course values (3,'化学');
  5. -- 添加2个学生
  6. insert into student values (1,'张三');
  7. insert into student values (2,'李四');
  8. -- 添加考试分数
  9. -- 张三只考了语文
  10. insert into score(student_id, course_id, score) values (1,1,80);
  11. -- 李四考了 语文和数学
  12. insert into score(student_id, course_id, score) values (2,1,85);
  13. insert into score(student_id, course_id, score) values (2,2,90);

3 统计出每个学生在所有的课程下的得分

  1. select a.student_id,a.student_name,a.course_id,a.course_name,b.score_id,b.score from (
  2. select
  3. s.student_id,
  4. s.student_name,
  5. c.course_id,
  6. c.course_name
  7. -- 此处交叉查询了
  8. from course c cross join student s
  9. order by s.student_id,c.course_id
  10. ) a left join score b
  11. -- 学生一样 并且分数也一样
  12. on a.student_id = b.student_id and a.course_id = b.course_id
  13. order by a.student_id,a.course_id;

思路:

  1. 交叉查询 出每个学生需要考试多少学科
  2. 然后关联score表,注意 on后面的 and 条件

另外一种写法

  1. select a.student_id,a.student_name,a.course_id,a.course_name,sc.score_id,ifnull(sc.score,0) score from (select c2.course_id, c2.course_name, s2.student_id, s2.student_name
  2. from (select -1 as link,
  3. c1.course_id,
  4. course_name
  5. from course c1) c2
  6. left join
  7. (select -1 as link, s1.student_id, student_name
  8. from student s1) s2 on c2.link = s2.link
  9. ) a left join score sc on a.student_id = sc.student_id and a.course_id = sc.course_id
  10. order by a.student_id,a.course_id

4 运行结果

运行结果

发表评论

表情:
评论列表 (有 0 条评论,165人围观)

还没有评论,来说两句吧...

相关阅读

    相关 mysql常见SQL语句

    1、需求 统计某个`子串`在`字符串`中`出现的次数`,`子串`在`字符串`中是否出现过。 2、案例 2.1 统计某个子串是否在字符串中出现过 my