PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Inserir várias linhas em uma tabela com base no número em outra tabela

Resposta à pergunta original


O Postgres permite que funções de retorno de conjunto (SRF) multipliquem linhas. generate_series() é seu amigo:
INSERT INTO b (all_names, birthday)
SELECT names, current_date -- AS birthday ??
FROM  (SELECT names, generate_series(1, number) FROM a);

Desde a introdução de LATERAL no Postgres 9.3 você pode manter o SQL padrão:o SRF se move do SELECT para o FROM Lista:
INSERT INTO b (all_names, birthday)
SELECT a.names, current_date -- AS birthday ??
FROM   a, generate_series(1, a.number) AS rn

LATERAL está implícito aqui, conforme explicado no manual:

LATERAL também pode preceder uma chamada de função FROM item, mas neste caso é uma palavra de ruído, porque a expressão da função pode se referir a itens FROM anteriores em qualquer caso.

Operação reversa


O acima é a operação inversa (aproximadamente) de um simples agregado count() :
INSERT INTO a (name, number)
SELECT all_names, count(*)
FROM   b
GROUP  BY 1;

... que se encaixa na sua pergunta atualizada.

Observe uma diferença sutil entre count(*) e count(all_names) . O primeiro conta todas as linhas, não importa o que, enquanto o último conta apenas as linhas em que all_names IS NOT NULL . Se sua coluna all_names é definido como NOT NULL , ambos retornam o mesmo, mas count(*) é um pouco mais curto e rápido.

Sobre GROUP BY 1 :
  • GROUP BY + instrução CASE