Отговор на оригиналния въпрос
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
може също да предшества извикване на функцияFROM
item, но в този случай това е шумова дума, тъй като изразът на функцията може да се отнася до по-ранни 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