Отговор на оригиналния въпрос
Postgres позволява функциите за връщане на набор (SRF) да умножават редове. generate_series() е твой приятел:
INSERT INTO b (all_names, birthday)
SELECT names, current_date -- AS birthday ??
FROM (SELECT names, generate_series(1, number) FROM a);
От въвеждането на LATERAL в Postgres 9.3 можете да се придържате към стандартния SQL:SRF се премества от SELECT към FROM списък:
INSERT INTO b (all_names, birthday)
SELECT a.names, current_date -- AS birthday ??
FROM a, generate_series(1, a.number) AS rn
LATERAL е имплицитно тук, както е обяснено в ръководството:
LATERALможе също да предшества извикване на функцияFROMitem, но в този случай това е шумова дума, тъй като изразът на функцията може да се отнася до по-ранни FROM елементи във всеки случай.
Обратна операция
Горното е обратната операция (приблизително) на обикновен агрегат count() :
INSERT INTO a (name, number)
SELECT all_names, count(*)
FROM b
GROUP BY 1;
... което отговаря на актуализирания ви въпрос.
Обърнете внимание на фина разлика между count(*) и count(all_names) . Първият брои всички редове, независимо какво, докато вторият брои само редове, където all_names IS NOT NULL . Ако колоната ви all_names се дефинира като NOT NULL , и двете връщат едно и също, но count(*) е малко по-кратък и по-бърз.
Относно GROUP BY 1 :
- Изявление GROUP BY + CASE