我正在寻找一种方法在SELECT语句中实现此目的。SQL使用相应的值连接多个列的字符串
FROM
Column1 Column2 Column3
A,B,C 1,2,3 x,y,z
TO
Result
A|1|x,B|2|y,C|3|z
定界符并不重要。我只是试图将所有数据都放在一个列中。理想情况下,我希望在DB2中执行此操作。但我想知道是否有更简单的方法在Oracle中完成此任务。 谢谢
我正在寻找一种方法在SELECT语句中实现此目的。SQL使用相应的值连接多个列的字符串
FROM
Column1 Column2 Column3
A,B,C 1,2,3 x,y,z
TO
Result
A|1|x,B|2|y,C|3|z
定界符并不重要。我只是试图将所有数据都放在一个列中。理想情况下,我希望在DB2中执行此操作。但我想知道是否有更简单的方法在Oracle中完成此任务。 谢谢
您需要使用:
如果打破输出,然后理解它的工作原理,那将很容易。
SQL> WITH t AS
2 (SELECT 'A,B,C' Column1, '1,2,3' Column2, 'x,y,z' Column3 FROM dual
3 )
4 SELECT SUBSTR(column1, 1, instr(column1, ',', 1) -1)
5 ||'|'
6 || SUBSTR(column2, 1, instr(column2, ',', 1) -1)
7 ||'|'
8 || SUBSTR(column3, 1, instr(column1, ',', 1) -1)
9 ||','
10 || SUBSTR(column1, instr(column1, ',', 1, 2) +1 - instr(column1, ',', 1),
11 instr(column1, ',', 1) -1)
12 ||'|'
13 || SUBSTR(column2, instr(column2, ',', 1, 2) +1 - instr(column2, ',', 1),
14 instr(column2, ',', 1) -1)
15 ||'|'
16 || SUBSTR(column3, instr(column3, ',', 1, 2) +1 - instr(column3, ',', 1),
17 instr(column3, ',', 1) -1)
18 ||','
19 || SUBSTR(column1, instr(column1, ',', 1, 3) +1 - instr(column1, ',', 1),
20 instr(column1, ',', 2) -1)
21 as "new_column"
22 FROM t;
new_column
-------------
A|1|x,B|2|y,C
在一个侧面说明,你应该避免在一列存储分隔的值。考虑正常化的数据。
从的Oracle 11g以上,你可以创建一个虚拟列使用上述表达,用它代替执行SQL频繁。
你可以做这样的使用INSTR和SUBSTR:
select
substr(column1,1,instr(column1,',',1)-1) || '|' ||
substr(column2,1,instr(column2,',',1)-1) || '|' ||
substr(column3,1,instr(column3,',',1)-1) || '|' ||
',' ||
substr(column1 ,instr(column1 ,',',1,1)+1,instr(column1 ,',',1,2) - instr(column1 ,',',1)-1) || '|' ||
substr(column2 ,instr(column2 ,',',1,1)+1,instr(column2 ,',',1,2) - instr(column2 ,',',1)-1) || '|' ||
substr(column3 ,instr(column3 ,',',1,1)+1,instr(column3 ,',',1,2) - instr(column3 ,',',1)-1) || '|' ||
',' ||
substr(column1 ,instr(column1 ,',',1,2)+1) || '|' ||
substr(column2 ,instr(column2 ,',',1,2)+1) || '|' ||
substr(column3 ,instr(column3 ,',',1,2)+1)
from yourtable
我尝试了一些事情。只需查看link 首先我创建了一个名为t_ask_test的表格并插入了基于上述问题的数据。通过使用字符串函数
试样台
create table t_ask_test(column1 varchar(10), column2 varchar(10),column3 varchar(10));
插入的行获得的结果
insert into T_ASK_TEST values ('A,B,C','1,2,3','x,y,z');
以下查询将在动态的方式
select substr(column1,1,instr(column1,',',1,1)-1)||'|'||substr(column2,1,instr(column1,',',1,1)-1)||'|'||substr(column3,1,instr(column1,',',1,1)-1) ||','||
substr(column1,instr(column1,',',1,1)+1,instr(column1,',',1,2)-instr(column1,',',1,1)-1)||'|'||substr(column2,instr(column2,',',1,1)+1,instr(column2,',',1,2)-instr(column2,',',1,1)-1)||'|'||substr(column3,instr(column3,',',1,1)+1,instr(column3,',',1,2)-instr(column3,',',1,1)-1) ||','||
substr(column1,instr(column1,',',1,2)+1,length(column1)-instr(column1,',',1,2))||'|'||substr(column2,instr(column2,',',1,2)+1,length(column2)-instr(column2,',',1,2))||'|'||substr(column3,instr(column3,',',1,2)+1,length(column3)-instr(column3,',',1,2)) as test from t_ask_test;
输出将如下
TEST
---------------
A|1|x,B|2|y,C|3|z
如果你必须为每个行条目的动态数则:
的Oracle 11g R2架构设置:
CREATE TABLE TEST (Column1, Column2, Column3) AS
SELECT 'A,B,C', '1,2,3', 'x,y,z' FROM DUAL
UNION ALL SELECT 'D,E', '4,5', 'v,w' FROM DUAL;
查询1:
WITH ids AS (
SELECT t.*, ROWNUM AS id
FROM TEST t
)
SELECT LISTAGG(
REGEXP_SUBSTR(i.Column1, '[^,]+', 1, n.COLUMN_VALUE)
|| '|' || REGEXP_SUBSTR(i.Column2, '[^,]+', 1, n.COLUMN_VALUE)
|| '|' || REGEXP_SUBSTR(i.Column3, '[^,]+', 1, n.COLUMN_VALUE)
, ','
) WITHIN GROUP (ORDER BY n.COLUMN_VALUE) AS value
FROM ids i,
TABLE(
CAST(
MULTISET(
SELECT LEVEL
FROM DUAL
CONNECT BY LEVEL <= GREATEST(
REGEXP_COUNT(i.COLUMN1, '[^,]+'),
REGEXP_COUNT(i.COLUMN2, '[^,]+'),
REGEXP_COUNT(i.COLUMN3, '[^,]+')
)
)
AS SYS.ODCINUMBERLIST
)
) n
GROUP BY i.ID
| VALUE |
|-------------------|
| A|1|x,B|2|y,C|3|z |
| D|4|v,E|5|w |
感谢您的回答。但是这不会在DB2中工作 – icedek
你不应该摆在首位 –
Oracle和DB2进行存储逗号分隔值 - 非常不寻常的组合... – jarlh
理想的情况下,是的。但是有一些用例规范化所有的数据都很昂贵。 只是因为在列中存储逗号分隔值并不理想,并不意味着问题不好,需要downvoted :) – icedek