用REGEXP語句實現判斷兩個字符串組合之間是否有交集

之前做了一個呼叫功能,呼叫項目和人員之間通過標籤關聯。比如呼叫項目關聯a標籤,b標籤,人員關聯b標籤,c標籤。方式是通過一個字段保存了用逗號分割的標籤id。只要他們關聯了同一個標籤,到時候呼叫就通知到那個人員。不過後來需求改了要直接把呼叫關聯到人員。這個時候我就需要修改的過去數據,把呼叫的id直接關聯到人員。

如果用java寫代碼的話這是很簡單的,不過我想用語句實現,查找資料後判斷兩個字符串組合是否有交集大部分是通過定義一個函數來實現的,但是我用的tidb數據庫並不能定義函數。

我只能使用like方法

insert into call_label_user(userId,companyId,label)
select clu.userId,clu.companyId,c.id label
-- 呼叫表
from call c
-- 呼叫人員表
join call_label_user clu on (clu.label like concat('%',c.label,'%')
or c.label like concat('%',clu.label,'%')) and clu.label != '' and c.label != ''
and clu.companyId = c.companyId
-- 判斷表格中是否已經存在呼叫人員關聯關係,避免多次執行插入重複數據
left join call_label_user clu2 on clu.userId = clu2.userId and clu.companyId = clu2.companyId and c.id = clu2.label
where clu2.id is null

這個辦法只查詢出了呼叫和人員分別關聯了單個標籤的情況。

很明顯還漏掉了一些情況,於是我又繼續查找資料,這時候我發現了一個神奇的關鍵詞regexp。

insert into call_label_user(userId,companyId,label)
select clu.userId,clu.companyId,c.id label
-- 呼叫表
from call c
-- 呼叫人員表
join call_label_user clu on (clu.label regexp replace(c.label,',','|')
or c.label regexp replace(clu.label,',','|')) and clu.label != '' and c.label != ''
and clu.companyId = c.companyId
-- 判斷表格中是否已經存在呼叫人員關聯關係,避免多次執行插入重複數據
left join call_label_user clu2 on clu.userId = clu2.userId and clu.companyId = clu2.companyId and c.id = clu2.label
where clu2.id is null

通過把,號替換成|就能用正則來判斷,兩邊交叉對比判斷就能獲得所有符合的情況。

我的問題實際上解決了,不過深入思考後我發現這是因爲我保存的標籤id是uuid,不存在重複的情況,如果是名稱或者id是數字那麼這個判斷是不嚴謹的。

比如兩個字符串組合"123,321,456"和"23,32",如果用上述方法是不行的。我決定對其進行優化。

思路是除了正則前面要麼是逗號要麼是開頭,後面要麼是逗號要麼是結尾,經過嘗試後是可行的

select '123,321,456' regexp '23|32';//結果是1
select '123,321,456' regexp '(^|,)(23|32)($|,)';//結果是0
select '123,321,456' regexp '(^|,)(123|32)($|,)';//結果是1
select '123,321,456' regexp '(^|,)(23|321)($|,)';//結果是1

那麼上面的語句可以繼續優化(雖然沒有必要)

insert into call_label_user(userId,companyId,label)
select clu.userId,clu.companyId,c.id label
-- 呼叫表
from call c
-- 呼叫人員表
join call_label_user clu 
on (clu.label regexp concat('(^|,)(',replace(c.label,',','|'),')($|,)')
or c.label regexp concat('(^|,)(',replace(clu.label,',','|'),')($|,)')) 
and clu.label != '' and c.label != ''
and clu.companyId = c.companyId
-- 判斷表格中是否已經存在呼叫人員關聯關係,避免多次執行插入重複數據
left join call_label_user clu2 on clu.userId = clu2.userId and clu.companyId = clu2.companyId and c.id = clu2.label
where clu2.id is null

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章