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