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:
LATERALtambém pode preceder uma chamada de funçãoFROMitem, 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