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