2015-10-20 32 views
-1

我正在寻找一种方法在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中完成此任务。 谢谢

+3

你不应该摆在首位 –

+0

Oracle和DB2进行存储逗号分隔值 - 非常不寻常的组合... – jarlh

+0

理想的情况下,是的。但是有一些用例规范化所有的数据都很昂贵。 只是因为在列中存储逗号分隔值并不理想,并不意味着问题不好,需要downvoted :) – icedek

回答

0

您需要使用:

  • SUBSTR
  • INSTR
  • ||级联运算符

如果打破输出,然后理解它的工作原理,那将很容易。

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频繁。

-1

它在oracle中很简单。只需使用连接操作符||。 在下面的解决方案,我用下划线作为分隔符

select Column1 ||'_'||Column2||'_'||Column3 from table_name; 
+0

不是。相应的值需要连接。 用你的上面的语句,结果将是“A,B,C_1,2,3_x,y,z” – icedek

+0

你的意思是相应的值需要连接在一起。 如果表就像 1× B 2Ÿ ç3 Z 我的查询将使 A_1_x B_2_y C_3_Z – Raj

+0

只看该问题的“结果”。 – icedek

1

你可以做这样的使用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 
1

我尝试了一些事情。只需查看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 
1

如果你必须为每个行条目的动态数则:

SQL Fiddle

的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 

Results

|    VALUE | 
|-------------------| 
| A|1|x,B|2|y,C|3|z | 
|  D|4|v,E|5|w | 
+0

感谢您的回答。但是这不会在DB2中工作 – icedek