首页 > 数据库 > 数据库开发技术 > SQL 表值函数之字符串拆分
CREATE TABLE movies(id int primary key, name varchar(50), class varchar(200));
INSERT INTO movies VALUES (1, '千与千寻', '动画、剧情、奇幻');
INSERT INTO movies VALUES (2, '阿甘正传', '剧情、爱情');
INSERT INTO movies VALUES (3, '唐伯虎点秋香', '喜剧、古装、爱情');
CREATE OR REPLACE TYPE str_list IS TABLE OF VARCHAR2(4000);
CREATE OR REPLACE FUNCTION string_split(p_str IN VARCHAR2, p_sep IN VARCHAR2 := ',')
RETURN str_list pipelined
IS
ln_idx PLS_INTEGER;
lv_list VARCHAR2(4000) := p_str;
BEGIN
LOOP
ln_idx := INSTR(lv_list, p_sep);
IF ln_idx > 0 THEN
pipe ROW(SUBSTR(lv_list, 1, ln_idx - 1));
lv_list := SUBSTR(lv_list, ln_idx + LENGTH(p_sep));
ELSE
pipe ROW(lv_list);
EXIT;
END IF;
END LOOP;
END string_split;
SELECT v.column_value
FROM string_split('Oracle,MySQL,SQL Server,PostgreSQL,SQLit') v;
COLUMN_VALUE|
------------|
Oracle |
MySQL |
SQL Server |
PostgreSQL |
SQLit |
SELECT id, name, column_value
FROM movies
CROSS JOIN string_split(class, '、');
ID|NAME |COLUMN_VALUE|
--|------------|------------|
1|千与千寻 |动画 |
1|千与千寻 |剧情 |
1|千与千寻 |奇幻 |
2|阿甘正传 |剧情 |
2|阿甘正传 |爱情 |
3|唐伯虎点秋香|喜剧 |
3|唐伯虎点秋香|古装 |
3|唐伯虎点秋香|爱情 |
WITH RECURSIVE t(sub, str) AS (
SELECT concat('Oracle,MySQL,SQL Server,PostgreSQL,SQLite',','), concat('Oracle,MySQL,SQL Server,PostgreSQL,SQLite',',')
UNION ALL
SELECT substr(str, 1, instr(str, ',')-1), substr(str, instr(str, ',')+1)
FROM t WHERE instr(str, ',')>0
)
SELECT sub
FROM t WHERE instr(sub, ',') = 0;
sub |
----------|
Oracle |
MySQL |
SQL Server|
PostgreSQL|
SQLite |
WITH RECURSIVE t(id, name, sub, str) AS (
SELECT id, name, concat(class,'、'), concat(class,'、')
FROM movies
UNION ALL
SELECT id, name,substr(str, 1, instr(str, '、')-1), substr(str, instr(str, '、')+1)
FROM t WHERE instr(str, '、')>0
)
SELECT id, name, sub
FROM t WHERE instr(sub, '、') = 0;
id|name |sub |
--|------------|----|
1|千与千寻 |动画 |
2|阿甘正传 |剧情 |
3|唐伯虎点秋香|喜剧 |
1|千与千寻 |剧情 |
2|阿甘正传 |爱情 |
3|唐伯虎点秋香|古装 |
1|千与千寻 |奇幻 |
3|唐伯虎点秋香|爱情 |
SELECT v.value
FROM string_split('Oracle,MySQL,SQL Server,PostgreSQL,SQLit', ',') v;
value |
----------|
Oracle |
MySQL |
SQL Server|
PostgreSQL|
SQLit |
SELECT id, name, value
FROM movies
CROSS APPLY string_split(class, '、');
id|name |value |
--|------------|------|
1|千与千寻 |动画 |
1|千与千寻 |剧情 |
1|千与千寻 |奇幻 |
2|阿甘正传 |剧情 |
2|阿甘正传 |爱情 |
3|唐伯虎点秋香|喜剧 |
3|唐伯虎点秋香|古装 |
3|唐伯虎点秋香|爱情 |
SELECT id, name, class
FROM movies
WHERE EXISTS (SELECT 1 FROM string_split(class, '、') WHERE value = '剧情');
id|name |class |
--|-------|---------------|
1|千与千寻|动画、剧情、奇幻|
2|阿甘正传|剧情、爱情 |
SELECT * FROM abs(10);
abs|
---|
10|
SELECT *
FROM regexp_split_to_table('Oracle,MySQL,SQL Server,PostgreSQL,SQLit', ',') v;
v |
----------|
Oracle |
MySQL |
SQL Server|
PostgreSQL|
SQLit |
SELECT *
FROM movies
CROSS JOIN regexp_split_to_table(class, '、') v;
id|name |class |v |
--|------------|--------------|---|
1|千与千寻 |动画、剧情、奇幻|动画|
1|千与千寻 |动画、剧情、奇幻|剧情|
1|千与千寻 |动画、剧情、奇幻|奇幻|
2|阿甘正传 |剧情、爱情 |剧情|
2|阿甘正传 |剧情、爱情 |爱情|
3|唐伯虎点秋香|喜剧、古装、爱情|喜剧|
3|唐伯虎点秋香|喜剧、古装、爱情|古装|
3|唐伯虎点秋香|喜剧、古装、爱情|爱情|
WITH RECURSIVE t(sub, str) AS (
SELECT '', 'Oracle,MySQL,SQL Server,PostgreSQL,SQLite'||','
UNION ALL
SELECT substr(str, 1, instr(str, ',')-1), substr(str, instr(str, ',')+1)
FROM t WHERE instr(str, ',')>0
)
SELECT sub
FROM t WHERE sub != '';
sub |
----------|
Oracle |
MySQL |
SQL Server|
PostgreSQL|
SQLite |
WITH RECURSIVE t(id, name, sub, str) AS (
SELECT id, name, '', class||'、'
FROM movies
UNION ALL
SELECT id, name,substr(str, 1, instr(str, '、')-1), substr(str, instr(str, '、')+1)
FROM t WHERE instr(str, '、')>0
)
SELECT id, name, sub
FROM t WHERE sub != '';
id|name |sub |
--|------------|----|
1|千与千寻 |动画 |
2|阿甘正传 |剧情 |
3|唐伯虎点秋香|喜剧 |
1|千与千寻 |剧情 |
2|阿甘正传 |爱情 |
3|唐伯虎点秋香|古装 |
1|千与千寻 |奇幻 |
3|唐伯虎点秋香|爱情 |
原文作者:SQL编程思想;如有侵权,请联系管理员删除。