Svar på den ursprungliga frågan
Postgres tillåter set-returning-funktioner (SRF) för att multiplicera rader. generate_series()
är din vän:
INSERT INTO b (all_names, birthday)
SELECT names, current_date -- AS birthday ??
FROM (SELECT names, generate_series(1, number) FROM a);
Sedan introduktionen av LATERAL
i Postgres 9.3 du kan hålla dig till standard SQL:SRF flyttas från SELECT
till 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
är implicit här, som förklaras i manualen:
LATERAL
kan också föregå ett funktionsanropFROM
objekt, men i det här fallet är det ett brusord, eftersom funktionsuttrycket kan hänvisa till tidigare FRÅN-objekt i alla fall.
Omvänd funktion
Ovanstående är den omvända operationen (ungefär) av en enkel aggregerad count()
:
INSERT INTO a (name, number)
SELECT all_names, count(*)
FROM b
GROUP BY 1;
... som passar din uppdaterade fråga.
Notera en subtil skillnad mellan count(*)
och count(all_names)
. Den förra räknar alla rader, oavsett vad, medan den senare endast räknar rader där all_names IS NOT NULL
. Om din kolumn all_names
definieras som NOT NULL
, båda returnerar samma, men count(*)
är lite kortare och snabbare.
Om GROUP BY 1
:
- GROUP BY + CASE-sats