1、原始數據演示
處理結果演示
sql語句
SELECT
a.id,
a. NAME,
substring_index(
substring_index(
a.shareholder,
',',
b.help_topic_id + 1
),
',' ,- 1
) AS shareholder
FROM
company a
JOIN mysql.help_topic b ON b.help_topic_id < (
length(a.shareholder) - length(
REPLACE (a.shareholder, ',', '')
) + 1
)
建表語句
CREATE TABLE `company` (
`id` int(20) DEFAULT NULL,
`name` varchar(100) DEFAULT NULL,
`shareholder` varchar(100) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `company` VALUES ('1', '阿里巴巴', '馬雲');
INSERT INTO `company` VALUES ('2', '淘寶', '馬雲,孫正義');
原理分析
這個join最基本原理是笛卡爾積。通過這個方式來實現循環。
分析:
length(a.path) - length(replace(a.path,‘,’,‘’))+1 表示了,按照逗號分割後,分割需要循環的次數。
join過程:
根據ID進行循環
{
判斷:i 是否 <= n
獲取最靠近第 i 個逗號之前的數據, 即 substring_index(substring_index(a.path,‘,’,b.help_topic_id),‘,’,-1)
}
這種方法的缺點在於,我們需要一個擁有連續數列的獨立表。並且連續數列的最大值一定要大於符合分割的值的個數。
例如有一行的path有100個逗號分割的值,那麼我們的table 就需要有至少100個連續行。
當然,mysql內部也有現成的連續數列表可用。如mysql.help_topic: help_topic_id 共有504個數值,一般能滿足於大部分需求了。