如何将多个列合并为新列

gopyfrb3  于 2021-08-13  发布在  Java
关注(0)|答案(3)|浏览(404)

我需要将多个列(有相当多的列和行)合并到一个新的列中。
例如,缩短测试表

Col1    Col2    Col3    Col4    Col5    Col6
942 72987   14759   441277503   73553030    null
943 72987   14759   441278315   73553166    null
944 72987   14759   441362593   73570082    null
945 72987   14759   441380217   73572619    null
946 72987   14759   441394189   73574533    null
947 72987   14759   441394189   73574533    null

我想用逗号分隔符(“,”)合并col1-col5,并将创建的字符串放入col6
所以在第六节课我想要例如: 942,72987,14759,441277503,73553030 有什么解决方案吗?如何在sql/pl/sql中实现它?正如我所说的,有很多列,所以我希望避免使用 Col1 || Col2 || Col3 || Col4 || Col5 事先谢谢你,米莎ł

2lpgd968

2lpgd9681#

你可以用 trim() 使用一些条件逻辑:

select trim(leading ',' from
            (case when col1 is not null then ',' || col1 else '' end) ||
            (case when col2 is not null then ',' || col2 else '' end) ||
            (case when col3 is not null then ',' || col3 else '' end) ||
            (case when col4 is not null then ',' || col4 else '' end) ||
            (case when col5 is not null then ',' || col5 else '' end)
           )
e5njpo68

e5njpo682#

请按以下方式尝试pl/sql块:

SET SERVEROUT ON
DECLARE
    LV_COLUMNS VARCHAR2(20000);
BEGIN
    SELECT LISTAGG('CASE WHEN ' || COLUMN_NAME || ' IS NOT NULL THEN ' || COLUMN_NAME || ' || '',''|| '
      || 'ELSE NULL END'
      , '||') WITHIN GROUP(ORDER BY COLUMN_ID)
      INTO LV_COLUMNS
      FROM USER_TAB_COLS
     WHERE TABLE_NAME = 'YOUR_TABLE_NAME'
       AND COLUMN_NAME <> 'COL6'
       AND HIDDEN_COLUMN = 'NO';

    DBMS_OUTPUT.PUT_LINE('UPDATE YOUR_TABLE_NAME SET COL6 = TRIM('','' FROM (' || LV_COLUMNS || '))');
    EXECUTE IMMEDIATE 'UPDATE YOUR_TABLE_NAME SET COL6 = TRIM('','' FROM (' || LV_COLUMNS || '))';
    COMMIT;
END;
/
zu0ti5jz

zu0ti5jz3#

我会按照@apc的路线使用 USER_TAB_COLUMNS 要生成必要的sql:

CREATE TABLE t (col1 VARCHAR2(5), col2 NUMBER, col3 VARCHAR2(30), 
                col4 VARCHAR2(7), col5 DATE,   col6 VARCHAR2(200));
SELECT column_name
  FROM user_tab_columns
 WHERE table_name = 'T'
   AND column_name <> 'COL6';

COL1
COL2
COL3
COL4
COL5

现在可以将它们与listag连接起来:

SELECT LISTAGG(column_name, '||'',''||') 
       WITHIN GROUP (ORDER BY column_id) AS sql
  FROM user_tab_columns
 WHERE table_name = 'T'
   AND column_name <> 'COL6';

COL1||','||COL2||','||COL3||','||COL4||','||COL5

现在我将这个复制并粘贴到相应的查询f.i。

UPDATE t 
   SET col6 = COL1||','||COL2||','||COL3||','||COL4||','||COL5;

要连接这些列,需要将它们转换为varchar2。oracle尝试自动数据类型转换。你必须检查这是否有效,是否对你足够好。数字可能有前导空格、逗号或小数点、日期可能需要格式字符串等。
你可以这样想:

SELECT column_name, 
       CASE WHEN data_type IN ('NUMBER','FLOAT') 
              THEN 'TO_CHAR('||column_name||')'
            WHEN data_type IN ('DATE') 
              THEN 'TO_CHAR('||column_name||',''YYYY-MM-DD'')'
            ELSE column_name
        END AS cstr
  FROM user_tab_columns
 WHERE table_name = 'T'
   AND column_name <> 'COL6';

COL1   COL1
COL2   TO_CHAR(COL2)
COL3   COL3
COL4   COL4
COL5   TO_CHAR(COL5,'YYYY-MM-DD')

根据您的情况,您可以使用虚拟列而不是复制真实数据:

ALTER TABLE t DROP COLUMN col6; 
ALTER TABLE t ADD (col6 NUMBER GENERATED ALWAYS 
               AS (COL1||','||COL2||','||COL3||','||COL4||','||COL5));

相关问题