我有以下字符串這樣劃分逗號分隔的串入列與空字符串
str:=',1,,3,4,5,6,,8,9';
str2:=',a,l,,gj,,b';
我怎麼可以把逗號分離串入這樣的列只使用SQL? (順序應該是下同)
COL
---------
NULL
1
NULL
3
4
5
6
NULL
8
9
COL2
----------
NULL
a
l
NULL
gj
NULL
b
感謝
我有以下字符串這樣劃分逗號分隔的串入列與空字符串
str:=',1,,3,4,5,6,,8,9';
str2:=',a,l,,gj,,b';
我怎麼可以把逗號分離串入這樣的列只使用SQL? (順序應該是下同)
COL
---------
NULL
1
NULL
3
4
5
6
NULL
8
9
COL2
----------
NULL
a
l
NULL
gj
NULL
b
感謝
您可以使用cross apply
具有層次connect by
來實現這一目標:
with t (text) as (select ',1,,3,4,5,6,,8,9' from dual union all
select ',1,,2' from dual)
select regexp_substr(text, '[^,]+', 1, lvl) x
from t cross apply (
select level lvl
from dual
connect by level <= regexp_count(t.text, ',') + 1
);
上面的作品可以同時處理多行。
如果你只有一個行轉換,使用方法:
with t (text) as (select ',1,,3,4,5,6,,8,9' from dual)
select
regexp_substr(text, '[^,]+', 1, level) x
from t connect by level <= regexp_count(text, ',') + 1;
如果你想要得到的結果相同順序輸入字符串發生,試試這個:
with t (text) as (select ',1,,3,4,5,6,,8,9' from dual union all
select ',1,,2' from dual)
select replace(regexp_substr(text, '[^,]*,?', 1, lvl),',') x
from t cross apply (
select level lvl
from dual
connect by level <= regexp_count(t.text, ',') + 1
);
如果您的分隔符是^|{
,請確保您正確地轉義特殊字符。試試這個:
with t (text) as (select '^|{1^|{^|{3^|{4^|{5^|{6^|{^|{8^|{9' from dual union all
select '^|{1^|{^|{2' from dual)
select replace(regexp_substr(text, '[^(\^\|\{)]*(\^\|\{)?', 1, lvl),'^|{') x
from t cross apply (
select level lvl
from dual
connect by level <= regexp_count(t.text, '\^\|\{') + 1
);
謝謝你的ans,但是結果與上面提到的不一樣。 –
需要按順序,如下(NULL,1,NULL,3,4,5,6,NULL,8,9) –
工作就像一個魅力。謝謝! –
使用像波紋管:
declare @ids varchar(max), @xml XML
set @ids='135,136'
SET @xml = cast(('<X>' + replace(@ids, ',', '</X><X>') + '</X>') as xml)
SELECT xmlNode.value('.', 'varchar(50)')
FROM @xml.nodes('X') as T(xmlNode)
請將第一行代碼縮進4位,因此它將顯示爲代碼 –
問題在於Oracle,所以此語法無效。 –
regex_replace +連接通過做你需要什麼,但不包括NULL值,所以需要以避免從正則表達式的輸出代替空字符串一招。在這種情況下,我在每個','之前向輸入添加一個#字符,然後在regex_replace完成任務後將其刪除。
您可以用下面的嘗試(這當然是一列的查詢,你只需要複製它的第二個)
select
replace(result,'#','') from
(select
regexp_substr(replace(',SMITH,ALLEN,WARD,JONES',',','#,'),'[^,]+',1,level) result from dual
connect by regexp_substr(replace(',SMITH,ALLEN,WARD,JONES',',','#,'), '[^,]+', 1, level) is not null
);
這裏是另外一個使用xmltable
:
SELECT DECODE (column_value, '-~-', NULL, COLUMN_VALUE)
FROM xmltable(('"' || REPLACE(REGEXP_REPLACE(',1,,3,4,5,6,,8,9','^,|,$|,,', ',-~-,'),
',', '","') || '"'))
如果你需要一個文字NULL
:
SELECT TRIM(column_value)
FROM xmltable(('"' || REPLACE(REGEXP_REPLACE(',1,,3,4,5,6,,8,9','^,|,$|,,', ',NULL,'),
',', '","') || '"'))
結果
NULL
1
NULL
3
4
5
6
NULL
8
9
使用遞歸子查詢保條款(亦稱公共表格表達);這裏是一個使用簡單的字符串函數和不依賴於(昂貴的)正則表達式的例子:
樣本數據:
CREATE TABLE table_name (id, list) AS
SELECT 1, 'a,b,c,d' FROM DUAL UNION ALL -- Multiple items in the list
SELECT 2, 'e' FROM DUAL UNION ALL -- Single item in the list
SELECT 3, NULL FROM DUAL UNION ALL -- NULL list
SELECT 4, 'f,,g' FROM DUAL; -- NULL item in the list
查詢:
WITH bounds (id, list, start_pos, end_pos, lvl) AS (
SELECT id, list, 1, INSTR(list, ','), 1 FROM table_name
UNION ALL
SELECT id,
list,
end_pos + 1,
INSTR(list, ',', end_pos + 1),
lvl + 1
FROM bounds
WHERE end_pos > 0
)
SELECT id,
SUBSTR(
list,
start_pos,
CASE end_pos
WHEN 0
THEN LENGTH(list) + 1
ELSE end_pos
END - start_pos
) AS item,
lvl
FROM bounds
ORDER BY id, lvl;
輸出 :
ID ITEM LVL
---------- ------- ----------
1 a 1
1 b 2
1 c 3
1 d 4
2 e 1
3 (NULL) 1
4 f 1
4 (NULL) 2
4 g 3
只需要轉換一行? – GurV
逗號的數量是否已知最大值? –
您正在使用哪個版本的Oracle? – GurV