當前業務需求:
根據某一個字段的字符串通過指定的分隔符,將原始的一行數據分隔爲多行數據
原數據:
需要的結果數據格式
實現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)