Mysql根据某一字段值按照某一特定符转化为列数据

当前业务需求:
根据某一个字段的字符串通过指定的分隔符,将原始的一行数据分隔为多行数据

原数据:
原数据
需要的结果数据格式
需要的数据

实现sql:

select acct.id, substring_index(substring_index(many, ',', h.id), ',', -1)  as one
from sys acct
         cross join help_select_id h
where h.id < (char_length(many) - char_length(replace(many, ',', '')) + 2)

分析 :

select acct.id,
#        由于数据保存使用的是逗号分隔;所以进行取元素
       substring_index(
       substring_index(many, ',', h.id)
           , ',', -1) as one
from sys acct
         #     创建的一个辅助表;此表只有一个id字段;数据值是自增;由于数据是我自己插入的;所以第一条数
         #     据是从1开始的;假如此表的第一条数据id是0;那么需要修改where条件后面 +的数量为1而不是2
         #     注意  ①help_select_id 表的数据需要是自增的;每个id之间的间隔是1;不可存在 2,4这种跳跃式数据;
         #② 此表的id的个数必须大于等于 many字段的分隔符最多的个数[例如:如果 many = 'AD,SS,SE,WW'是该字段
         # 以逗号为分隔符,逗号最多的值;那么 help_select_id的id个数必须大于等于 3]
         cross join help_select_id h
where h.id
          # 首先计算出逗号的个数;此处后面 +2 的原因
#  ①如果直接使用   h.id < char_length(many) - char_length(replace(many, ',', '')) 会造成数据的缺失;
#       原因分析:  假如 many = 'AD,WJ,KS,' ;上面计算出的差值是3,即实际判断条件为   h.id < 3 ;
#       由于我的 help_select_id表的第一条数据是从1开始的;那么满足这个条件的就有两条;
#       然后整个执行的sql可以理解为下面的语句
#       select acct.id,
#              得到最终字符串 AD
#       substring_index(
#               得到字符串 AD
#       substring_index('AD,WJ,KS,' ,',' ,1)
#       , ',' ,-1) as one
#       from sys acct cross join help_select_id h where h.id = 1 union
#       select acct.id,
#               得到最终字符串 WJ
#       substring_index(
#               得到字符串  AD,WJ
#       substring_index('AD,WJ,KS,' ,',' ,2)
#       , ',' ,-1) as one
#       from sys acct cross join help_select_id h where h.id = 2;
#       上面的sql执行的结果只会是两条          id     one
#                                            1      AD
#                                            1      WJ
#       就会造成KS数据的缺失;
#       那加1就好了;为什么要加2呢?  如果你的字段数据后缀都以逗号结尾,确实+1以满足需求;但如果你的字段数据不是
#        以逗号结束,那么就又少了一条
# ②例如 many='AD,WJ,KS' ;注意此值和①中的值相比,结尾少了一个逗号;那么
#       h.id < char_length(many) - char_length(replace(many, ',', ''))  + 1 只加1 结果相当于 h.id < 3
#       由于我的 help_select_id表的第一条数据是从1开始的;那么满足这个条件的就有两条;
#       然后整个执行的sql可以理解为下面的语句
#       select acct.id,
#           得到最终字符串  AD
#       substring_index(
#           得到字符串   AD
#         substring_index('AD,WJ,KS' ,',' ,1)
#       , ',' ,-1) as one
#       from sys acct cross join help_select_id h where h.id = 1 union
#       select acct.id,
#           得到最终字符串  WJ
#       substring_index(
#          得到字符串 AD,WJ
#       substring_index('AD,WJ,KS' ,',' ,2)
#       , ',' ,-1) as one
#       from sys acct cross join help_select_id h where h.id = 2;
#     上面的sql执行的结果只会是两条             id     one
#                                            1      AD
#                                            1      WJ
# 所以 需要 +2 ;注意:我的 help_select_id表的数据是从1开始的;如果你是从0开始,那就应该只 +1 即可
          < (char_length(many) - char_length(replace(many, ',', '')) + 2)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章