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