Respuesta a la pregunta original
Postgres permite funciones de devolución de conjuntos (SRF) para multiplicar filas. generate_series() es tu amigo:
INSERT INTO b (all_names, birthday)
SELECT names, current_date -- AS birthday ??
FROM (SELECT names, generate_series(1, number) FROM a);
Desde la introducción de LATERAL en Postgres 9.3 puede ceñirse al SQL estándar:el SRF se mueve desde el SELECT al 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 aquí, como se explica en el manual:
LATERAL también puede preceder a una llamada de función FROM item, pero en este caso es una palabra irrelevante, porque la expresión de la función puede referirse a elementos FROM anteriores en cualquier caso.
Operación inversa
Lo anterior es la operación inversa (aproximadamente) de un agregado simple count() :
INSERT INTO a (name, number)
SELECT all_names, count(*)
FROM b
GROUP BY 1;
... que se ajusta a su pregunta actualizada.
Note una sutil diferencia entre count(*) y count(all_names) . El primero cuenta todas las filas, pase lo que pase, mientras que el segundo solo cuenta las filas donde all_names IS NOT NULL . Si su columna all_names se define como NOT NULL , ambos devuelven lo mismo, pero count(*) es un poco más corto y más rápido.
Acerca de GROUP BY 1 :
- Sentencia GROUP BY + CASE