繁体   English   中英

通过 postgresql 中的循环添加多列

[英]adding multiple columns via a loop in postgresql

我正在尝试在具有多个列的模式中创建一个新表,这些列通过索引命名。

CREATE TABLE rflux (pk SERIAL PRIMARY KEY NOT NULL);

现在我想添加新的列,如 col0 FLOAT、col1、col2、col3、.... 直到 colN。

我知道我可以做类似的事情

ALTER TABLE rflux add column col0 FLOAT add column col1 FLOAT ... ;

但我不想输入所有内容,因为我需要创建 ~4500 列。 我正在尝试用循环来实现它,但我无法让它正常工作。 有没有人有任何想法? 我试过创建一个函数来做到这一点..

create function addColumns()
returns void
as $$
begin
for i in 1..10 loop
alter table rflux add column tmp float;
alter table rflux rename tmp to col||i;
end loop;
return;
end;
$$
language plpgsql;

然后做 select * from addColumns();

但是在将列重命名为 col||i 时,甚至在我尝试 i 时都会出错。 我什至不确定这是否是最好的方法。 如何添加多个列,我可以在其中使用计数器增加列的名称?

编辑..我知道我不能用 4500 列来做这个,但是如果我想用 10 列来解决这个问题,比如说?

谢谢。

您的设计可能更适合数组,hstore或json数据类型。 添加4500列是一场噩梦,等待发生。

如果可以帮助您:

-- VERSION : POSTGRESQL 9.3

-- FICTIVE TABLE #1

CREATE TABLE table_1 ("YEAR" int, "CODE_SP" text, "TOTAL" int);

INSERT INTO table_1 VALUES
(2035, 'TRUC', 2),
(2035, 'MUCH', 4),
(2036, 'FLIC', 7),
(2036, 'LORD', 2),
(2036, 'TRUC', 8),
(2037, 'MUCH', 2),
(2037, 'FLIC', 2),
(2037, 'FLAC', 5),
(2037, 'MORD', 9),
(2038, 'LOOP', 3),
(2038, 'MUCH', 3);

SELECT * FROM table_1;

-- FICTIVE TABLE #2

CREATE TABLE table_2 ("YEAR" int);

INSERT INTO table_2("YEAR")
SELECT serial
FROM generate_series(2035,2038,1) AS serial;

SELECT * FROM table_2;

-- LOOP FOR ADDING COLUMNS ON TABLE #2 

DO
$do$
    DECLARE colnames TEXT;
BEGIN
FOR colnames IN 
    SELECT "CODE_SP"
    FROM table_1
    GROUP BY "CODE_SP"
    ORDER BY "CODE_SP"
LOOP
    EXECUTE 'ALTER TABLE table_2 ADD COLUMN ' || quote_ident(colnames) || ' INT DEFAULT NULL;'; /* careful: in quoted text, the spaces are important */
END LOOP;
END
$do$;

-- LOOP FOR COMPLETTING CELLS ON TABLE #2 

DO
$do$
    DECLARE id_value TEXT;
BEGIN
FOR id_value IN
    SELECT "CODE_SP"
    FROM table_1
    GROUP BY "CODE_SP"
    ORDER BY "CODE_SP"
LOOP
    EXECUTE 'UPDATE table_2 SET ' || quote_ident(id_value) || ' = table_1."TOTAL" FROM table_1 WHERE table_1."CODE_SP" = ' || quote_literal(id_value) || ' AND table_1."YEAR" = table_2."YEAR";'; /* careful: in quoted text, the spaces are important */
END LOOP;
END
$do$;

我没有找到但自己创建的其他解决方案之一。

do $$
declare 
    colnames text[];
    target_array text[]:= array[
                                ['table1','product_id'],
                                ['table2','product_id'],
                                ['table3','product_id']
                                ];  
    
begin
   FOREACH colnames SLICE 1 in  ARRAY target_array
   loop
        execute 'alter table '||colnames[1]||' 
                add  '||colnames[2]||' int
                DEFAULT NULL;';
        raise notice 'table: %, column: %', colnames[1], colnames[2];
   end loop;
end; $$;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM