Mysql我是怎麼隨機截取字符數組裏的字符串而且一一對應

場景:臨近年末,各個App都會有我的年度帳單,項目裏爲了圖快,以及節省各個系統模塊之間的接口聯調。直接人工統計數據(😳😳😳😳😳😳😳😳😳😳😳😳😳😳),構造帳單數據JSON。php

話很少說,老夫拿起鍵盤就是幹。前端

五毒有歐,數據俺不九班的由其餘各個系統小組提供,可是有些數據是隨機生成的一些描述性的文本,而該文本從固定的文本數組而來。前端展現效果又要將隨機文本拆成幾個部分來。mysql

正常的sql拼接成json還方便。sql

CONCAT('\"app\":{\"time\":\"', DATE_FORMAT(time, "%Y-%m-%d %T"), '\",\"days\":', days, 
case when typeTime is null then '' else CONCAT(',\"typeTime\":\"', DATE_FORMAT(typeTime, "%Y-%m-%d %T"), '\"') end,'}') 
複製代碼

隨機文原本了json

學富五車:再美的氣質,也掩蓋不了你才華本質 神機妙算:腦力使用積極分子,非你莫屬 打抱不平:你的看法,面面俱到,深刻人心 火眼金睛:獨特的洞察力,總能獲悉一切 見多識廣:最美的閱歷,就是沿路的風景 責任擔當:先天下之憂而憂,後天下之樂而樂數組

從上面能夠看的出,它們之間一一對應的。微信

惟獨那些隨機文本着實思考片刻。來,咱們層層剖析它。app

截取文本

mysql中怎麼從數組中取隨機的文本,參考substring_index函數。分爲兩步走,第一步先去倒數開始往前數倒數幾位,第二步再重新的數組中取第一位。函數

substring_index(substring_index(array, '符合間隔', -n), '符合間隔', 1)
複製代碼

構造隨機因子

如今再看看這個隨機因子怎麼取,參考rand()函數。spa

由於取的是-1到-7之間的隨機數。因此最終的效果就是以下。

-floor(rand()*7+1)
複製代碼

取隨機範圍內的值能夠參考這個公式

FLOOR(start_num + RAND() * (end_num - start_num + 1))
複製代碼

開始第一次截取

隨機串截取方法有了,隨機數也有了,開幹。

select user_id, CONCAT('\"desc\": {\"label\":\"', 
substring_index(substring_index('學富五車;神機妙算;打抱不平;火眼金睛;見多識廣;責任擔當;樂觀積極',';',-FLOOR(rand()*7+1)),';',1),'\"',
',\"description\": \"', substring_index(substring_index('再美的氣質,也掩蓋不了你才華本質;腦力使用積極分子,非你莫屬;你的看法,面面俱到,深刻人心;獨特的洞察力,總能獲悉一切;最美的閱歷,就是沿路的風景;先天下之憂而憂,後天下之樂而樂;愛笑的你運氣必定不會差',';',-FLOOR(rand()*7+1)),';',1),
'\"}'
) as report_content from data; 
複製代碼

結果發現對不上啊,【責任擔當】應該對應【先天下之憂而憂,後天下之樂而樂】,而結果出現部分對應到【再美的氣質,也掩蓋不了你才華本質】

img

努力第二次截取

此次考慮到上回咱們是把隨機因子放在sql裏沒句話裏,因此每次都執行了2次,生成是隨機因子就不同了,截取的結果就對應不上,那,咱們先在子查詢裏先把隨機因子生成後,再在外層用這個隨機因子這下應該不同了把。

select temp.user_id, CONCAT('\"desc\": {\"label\":\"', 
substring_index(substring_index('學富五車;神機妙算;打抱不平;火眼金睛;見多識廣;責任擔當;樂觀積極',';',temp.desc_index),';',1),'\"',
',\"description\": \"', substring_index(substring_index('再美的氣質,也掩蓋不了你才華本質;腦力使用積極分子,非你莫屬;你的看法,面面俱到,深刻人心;獨特的洞察力,總能獲悉一切;最美的閱歷,就是沿路的風景;先天下之憂而憂,後天下之樂而樂;愛笑的你運氣必定不會差',';',temp.desc_index),';',1),
'\"}'
) as report_content from (select user_id, -FLOOR(rand()*7+1) as desc_index from data) temp

複製代碼

吐血的圖片在查找中,從開頭看就看的出來,對應不上啦,前幾個就前部對應【愛笑的你運氣必定不會差】,愛笑的我,運氣就是這麼差。

image-20190117145010072

改變下語句把隨機因子打印出來

select temp.user_id, desc_index, CONCAT(desc_index, '\"desc\": {\"label\":\"', 
substring_index(substring_index('學富五車;神機妙算;打抱不平;火眼金睛;見多識廣;責任擔當;樂觀積極',';',temp.desc_index),';',1),'\"',
',\"description\": \"', substring_index(substring_index('再美的氣質,也掩蓋不了你才華本質;腦力使用積極分子,非你莫屬;你的看法,面面俱到,深刻人心;獨特的洞察力,總能獲悉一切;最美的閱歷,就是沿路的風景;先天下之憂而憂,後天下之樂而樂;愛笑的你運氣必定不會差',';',temp.desc_index),';',1),
'\"}'
) as report_content from (select user_id, -FLOOR(rand()*7+1) as desc_index from data) temp

複製代碼

********,前面這些打星號的,都是髒話,忽略它,隨機因子,明明在子查詢都生成了,爲毛仍是不同。

image-20190117145539095

最終絞盡腦汁的截取

本想在子查詢中使用rand()把隨機因子能夠搞出來,哪成想,在外層的查詢時rand()又TMM的重算了一遍。

一頓參考一頓找資料,偶然間發現了問題所在

Mysql盡然有這樣的bug

2017年有個哥們提了這樣的一個issue,就是上面的連接。

裏面說了一些狀況,在mysql5.6裏,隨機數是同樣的,5.7裏隨機數不同。若是子查詢裏不使用表,隨機數也是同樣。剛恰好mysql就是5.7,剛恰好中招了。

image-20190117151229364

根據做者和Roy Lyseng的建議,我用limit,沒想到,盡然闊以啦,老淚縱橫啊。

仍是老外好,成功的解決方案,也會在issue裏說明下的。

改造後的最終樣子。

select temp.user_id, desc_index, CONCAT(desc_index, '\"desc\": {\"label\":\"', 
substring_index(substring_index('學富五車;神機妙算;打抱不平;火眼金睛;見多識廣;責任擔當;樂觀積極',';',temp.desc_index),';',1),'\"',
',\"description\": \"', substring_index(substring_index('再美的氣質,也掩蓋不了你才華本質;腦力使用積極分子,非你莫屬;你的看法,面面俱到,深刻人心;獨特的洞察力,總能獲悉一切;最美的閱歷,就是沿路的風景;先天下之憂而憂,後天下之樂而樂;愛笑的你運氣必定不會差',';',temp.desc_index),';',1),
'\"}'
) as report_content from (select user_id, -FLOOR(rand()*7+1) as desc_index from data limit 100000) temp


複製代碼

image-20190117151435160

歡迎關注個人微信公衆號

微信公衆號
相關文章
相關標籤/搜索