PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Insérer plusieurs lignes dans une table en fonction du nombre dans une autre table

Réponse à la question initiale

Postgres permet aux fonctions de retour d'ensemble (SRF) de multiplier les lignes. generate_series() est ton ami :

INSERT INTO b (all_names, birthday)
SELECT names, current_date -- AS birthday ??
FROM  (SELECT names, generate_series(1, number) FROM a);

Depuis l'introduction de LATERAL dans Postgres 9.3 vous pouvez vous en tenir au SQL standard :le SRF se déplace depuis le SELECT au FROM liste :

INSERT INTO b (all_names, birthday)
SELECT a.names, current_date -- AS birthday ??
FROM   a, generate_series(1, a.number) AS rn

LATERAL est implicite ici, comme expliqué dans le manuel :

LATERAL peut également précéder un appel de fonction FROM élément, mais dans ce cas, il s'agit d'un mot parasite, car l'expression de la fonction peut faire référence à des éléments FROM antérieurs dans tous les cas.

Opération inverse

Ce qui précède est l'opération inverse (approximativement) d'un simple agrégat count() :

INSERT INTO a (name, number)
SELECT all_names, count(*)
FROM   b
GROUP  BY 1;

... qui correspond à votre question mise à jour.

Notez une différence subtile entre count(*) et count(all_names) . Le premier compte toutes les lignes, quoi qu'il arrive, tandis que le second ne compte que les lignes où all_names IS NOT NULL . Si votre colonne all_names est défini comme NOT NULL , les deux renvoient la même chose, mais count(*) est un peu plus court et plus rapide.

À propos de GROUP BY 1 :

  • Instruction GROUP BY + CASE