mysql拆分字串做條件查詢

2022-07-05 12:06:30

mysql拆分字串作為查詢條件

有個群友問一個問題

這表的ancestors列存放的是所有的祖先節點,以,分隔

例如我查詢dept_id為103的所有祖先節點,現在我只有一個dept_id該怎麼查

然後我去網上找到這樣一個神奇的sql,改改表名就成了下面的這樣

	SELECT
		substring_index( substring_index( a.ancestors, ',', b.help_topic_id + 1 ), ',',- 1 ) AS shareholder 
	FROM
		sys_dept a
		JOIN mysql.help_topic b ON b.help_topic_id < ( length( a.ancestors ) - length( REPLACE ( a.ancestors, ',', '' ) ) + 1 ) 
	WHERE
	dept_id = 103 

嗯,沒錯結果出來了,然後我就很好奇,什麼原理,一個個來看

mysql.help_topic

這個是一個mysql自帶的幫助解釋註釋表,查詢結果如下

id從0開始,我這個版本最大id到584,版本不同應該id最大值也不一樣,這個表的作用一會說

REPLACE

這個函數應該都知道吧,替換字元用的

LENGHT

獲取字串的長度

substring_index

查分字串,三個引數,要拆分的字串,根據拆分的字元,從第幾個開始

如果最後的那個引數為正數則從左開始數,然後獲取對應下標左邊的所有字元

如果為負數,則從右邊開始數,獲取對應下標右邊的所有字串,這個就不演示了

分析

先來看第一段

( length( a.ancestors ) - length( REPLACE ( a.ancestors, ',', '' ) ) + 1 )

我們假設當前資料的ancestors值為 0,100,101 那麼第一個length(a.ancestors)的值就是9 減去後面的一段

length( REPLACE ( a.ancestors, ',', '' ) ) 因為我們假設的值裡面有兩個 , 所以length為7 最後在加1 那麼這段值為 3

和前面的 join on條件能查出的資料也就是mysql.help_topic這個表中所有id小於3的資料,也就是id為0,1,2的三條資料

那麼現在先來看看這樣查詢的結果是啥

那麼我們假設現在是第一行,mysql.help_topic表中的help_topic_id為0

substring_index( substring_index( a.ancestors, ',', b.help_topic_id + 1 ), ',',- 1 )

最裡面的substring_index 拆分後為0,因為沒有能在拆分的了所以外面的substring_index返回的也是0

第二行help_topic_id為1的時候獲取結果為0,100

然後執行外層的substring_index 根據,拆分,值為-1 所以從右邊找一位,獲取的值就是100

第三行結果為0,100,101,外層substring_index 執行後結果為101

....只能心中大喊牛逼

那麼現在知道mysql.help_topic這個表的作用了嗎?就是用來對拆分出的資料分行,專業點叫笛卡爾積 (真的不懂..)

這種方法也有缺點:就是拆出的行數不能大於mysql.help_topic這個表的資料條數