簡體   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