PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Einfügen mehrerer Zeilen in eine Tabelle basierend auf der Zahl in einer anderen Tabelle

Antwort auf die ursprüngliche Frage

Postgres ermöglicht Set-Returning-Funktionen (SRF), um Zeilen zu multiplizieren. generate_series() ist dein Freund:

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

Seit der Einführung von LATERAL in Postgres 9.3 Sie können sich an Standard-SQL halten:Die SRF bewegt sich von SELECT zum 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 ist hier implizit, wie im Handbuch erklärt:

LATERAL kann auch vor einem Funktionsaufruf FROM stehen item, aber in diesem Fall handelt es sich um ein Füllwort, da sich der Funktionsausdruck in jedem Fall auf frühere FROM-Items beziehen kann.

Umgekehrter Betrieb

Das Obige ist (ungefähr) die umgekehrte Operation eines einfachen Aggregats count() :

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

... was zu Ihrer aktualisierten Frage passt.

Beachten Sie einen feinen Unterschied zwischen count(*) und count(all_names) . Ersteres zählt alle Zeilen, egal was passiert, während letzteres nur Zeilen zählt, in denen all_names IS NOT NULL ist . Wenn Ihre Spalte all_names ist als NOT NULL definiert , beide geben dasselbe zurück, aber count(*) ist etwas kürzer und schneller.

Über GROUP BY 1 :

  • GROUP BY + CASE-Anweisung