• 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部分单词的效果。

    最终效果

    在这里插入图片描述

  • 相关阅读:
    Python3: 列表(List) 2023-11-15
    服务器——SSL/TLS协议信息泄露漏洞(CVE-2016-2183)修复办法
    [ jquery 选择器 :nth-of-type() ] 选取指定类型(p)父元素下的第几个子元素
    基于C#的无边框窗体动画效果的完美解决方案 - 开源研究系列文章
    微信小程序源码获取和反编译
    芯科蓝牙BG27开发笔记2-调试第一个程序
    Flink standalone 模式下运行WordCount程序过程
    代码随想录训练营 DP
    MongoDB - 索引知识
    太坑了,我竟然从RocketMQ源码中扒出了7种导致消息重复消费的原因
  • 原文地址:https://blog.csdn.net/caoyuan666/article/details/126711376