SQL 将多列中的字符串与相应的值连接起来

SQL Concatenate strings across multiple columns with corresponding values

我正在寻找一种在 SELECT 语句中实现此目的的方法。

来自

Column1    Column2    Column3
A,B,C      1,2,3      x,y,z

Result
A|1|x,B|2|y,C|3|z

分隔符无关紧要。我只是想在一个列中获取所有数据。理想情况下,我希望在 DB2 中执行此操作。但我想知道在 Oracle 中是否有更简单的方法来完成这项工作。 谢谢

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

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

您需要使用:

  • 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 及更高版本,您可以使用上述表达式创建一个 VIRTUAL COLUMN 并使用它而不是执行 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 的 table 并根据上述问题插入了数据。使用 字符串函数

获得结果

样本table

 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

如果每行的条目数是动态的,那么:

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 |