将行乘以列值

Multiply rows by column value

我需要将数据从源-table 转换到目标-table。

来源 table 有 'content' 列和 'multiplier' 列。基于乘数(X),源的内容应该被写入目标X次。

例如:如果 multilpier 为“0”,则不会写入任何内容,如果为“1”,则将内容一次性写入目标 table。两次,如果乘数为“2”,依此类推。我以前从未在 Postgres 中做过函数。

我的方法:嵌套的 for-while 循环:对于每一行,当 'counter' 小于 'multiplier' 时,将源 table 中的内容插入目标 table.

示例数据:

--create source table
create table public.source_tbl(
id serial, 
multiplier int, 
content varchar,
primary key (id)
);
--create destination table
create table public.dest_tbl(
id serial, 
multiplier int, 
content varchar,
primary key (id)
);
--some content
insert into public.source_tbl(multiplier,content)
values(1,'foo'),(1,'bar'),(1,'random'),(2, 'content'),(3,'My'),(4,'creativity'),(3,'is'),(2,'very'),(6,'limited'),(7,'!!!'), (0, 'nothing should be written');

这就是我想出的代码:

do
$$
declare f record;
begin 
    for f in    select id, multiplier, content
                from public.source_tbl;
    loop
        do
        $$
        declare counter integer counter:=0;
        begin
            while counter < f.multiplier
            loop
                insert into public.dest_tbl(multiplier,content)
                select f.multiplier, f.content;
                counter := counter +1;
            end loop;
        end;
    end loop;
end;
$$

不用说它不起作用,第二个 'declare' 出现语法错误。那我做错了什么?

您不能在 plpgsql 代码中间声明变量。也没有必要为第二个循环创建另一个匿名代码块。试试这个:

do
$$ 
declare 
 f record;
 counter integer :=0;
begin 
    for f in select id, multiplier, content from public.source_tbl  loop
      while counter < f.multiplier loop
         insert into public.dest_tbl(multiplier,content)
         select f.multiplier, f.content;
         counter := counter +1;
       end loop;   
       counter := 0;
    end loop;
end;
$$ language plpgsql;

演示:db<>fiddle

Jim 立即回答了有关语法错误的问题。但是,您不需要为此使用函数或 PL/pgSQL。同样可以通过使用内置函数 generate_series()

来实现
insert into dest_tbl (multiplier, content)
select st.multiplier, st.content
from source_tbl st
  cross join generate_series(1, st.multiplier);