• mysql.help_topic:join后面on居然还可以用 < 连接实现列转行


    引言(遇到问题)

    今天写代码,看到了如下SQL,直接怀疑他是不是语法错了,on后面不都是等于号吗?

    SELECT
        a.bname,
        SUBSTRING_INDEX( SUBSTRING_INDEX( a.bname, ',', b.help_topic_id + 1 ), ',', - 1 ) AS new_book_name 
    FROM
        book a
        JOIN mysql.help_topic b ON b.help_topic_id < (
            LENGTH( a.bname ) - LENGTH(
            REPLACE ( a.bname, ',', '' )) + 1 
        )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    原来是MySQL的特殊用法!!!

    真实作用

    为搞懂这种写法的真实目的,首先介绍这个sql的真实作用:

    有些时候,为了减少其他字段数据冗余或是一些业务等其他原因,我们可能会将某个特征多条数据合并存为一条数据进行存储,如下图中bname字段这种用法违反第一范式的设计模式。 这种模式下,应用常常需要将这个列依据分隔符进行分割,如用“,”将其分割为多行数据,并得到列转行的结果。
    在这里插入图片描述

    解析

    如果只是想将表中的某些行转为多行的操作,那么直接复制上面的sql代码稍加修改就可以实现了,但是,如果想搞懂这个sql的实现原理,还要逐行解析:

    1. mysql.help_topic

    help_topic是mysql内部属性表,我们这里用这个属性表的目的就是利用这个表中自增id help_topic_id这一字段,由于我们需要将一行转为多行,那么就需要这么一个自增序列字段,help_topic_id共有数百个连续的id,我mysql这个版本共有505个从0开始的连续id,id最大值大于符合分割value值的个数,能满足于大部分需求了。
    在这里插入图片描述
    在这里插入图片描述

    2. LENGTH( a.bname)

    LENGTH函数用于返回字符串的字节长度,长度单位为字节。
    使用uft8编码字符集时,一个汉字是3个字节,一个数字或字母是一个字节

    在这里插入图片描述

    3. JOIN

    这里JOIN用的是笛卡尔积,由于我们的目的是让一行数据转换为多行数据,那么这里就利用help_topic内部表的行数来实现,在两个表联表查询的时候,让b.help_topic_id小于要转换的行数。

            LENGTH( a.bname ) - LENGTH(
            REPLACE ( a.bname, ',', '' )) + 1 
    
    • 1
    • 2

    这里实现的就是统计当前内容中包含了多少数据,即未来要转换的行数

    4. SUBSTRING_INDEX

    MySQL中一个很好用的截取字符串的函数:substring_index。

    • 用法规则:
      substring_index(“待截取有用部分的字符串”,“截取数据依据的字符”,截取字符的位置N)

    • 参数说明

      • string:用于截取目标字符串的字符串。可为字段,表达式等。
      • sep:分隔符,string存在且用于分割的字符,比如“,”、“.”等。
      • num:序号,为非0整数。若为整数则表示从左到右数,若为负数则从右到左数。比如“www.mysql.com”截取字符‘www’,分割符为“.”,从左到右序号为1,即substring_index(“www.mysql.com”,‘.’,1);若从右开始获取“com”则为序号为-1即substring_index(“www.mysql.com”,‘.’,-1);若从做开始获取“www.mysql”则为序号为2即substring_index(“www.mysql.com”,‘.’,2)
    • 详细说明:
      首先,设待处理对象字符串为“15,151,152,16”(虽然这里指的不是iP,可以看作是IP来处理吧)
      这里截取的依据是逗号:“,”具体要截取第N个逗号前部分的字符;

    由于这个函数不能指定截取中间的部分索引的单词,索引需要用它来嵌套一下来实现获取当前第n部分单词的效果。

    最终效果

    在这里插入图片描述

  • 相关阅读:
    SadTalker 让图片说话
    qt QMutex 判断对象是否已经锁的状态
    基于springboot实现线上教学平台项目【项目源码+论文说明】
    solidty提升篇-智能协议-合约的所有权-gas-带参数的函数修饰符
    若依集成多数据源教程
    uniapp AES加密解密
    【Java牛客刷题】入门篇(01)
    微信群发工具,纯Python编写~
    设计模式——工厂模式
    for...of与for...in
  • 原文地址:https://blog.csdn.net/caoyuan666/article/details/126711376