Odpowiedź na pierwotne pytanie
Postgres pozwala funkcjom zwracania zestawu (SRF) na mnożenie wierszy. generate_series()
jest twoim przyjacielem:
INSERT INTO b (all_names, birthday)
SELECT names, current_date -- AS birthday ??
FROM (SELECT names, generate_series(1, number) FROM a);
Od czasu wprowadzenia LATERAL
w Postgresie 9.3 możesz trzymać się standardowego SQL:SRF przenosi się z SELECT
do 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
jest tutaj dorozumiana, jak wyjaśniono w instrukcji:
LATERAL
może również poprzedzać wywołanie funkcji FROM
element, ale w tym przypadku jest to słowo zakłócające, ponieważ wyrażenie funkcji może w każdym przypadku odnosić się do wcześniejszych elementów FROM.
Operacja odwrotna
Powyższe jest odwrotną operacją (w przybliżeniu) prostego agregatu count()
:
INSERT INTO a (name, number)
SELECT all_names, count(*)
FROM b
GROUP BY 1;
... co pasuje do Twojego zaktualizowanego pytania.
Zwróć uwagę na subtelną różnicę między count(*)
i count(all_names)
. Pierwsza liczy wszystkie wiersze, bez względu na wszystko, podczas gdy druga liczy tylko wiersze, w których all_names IS NOT NULL
. Jeśli Twoja kolumna all_names
jest zdefiniowany jako NOT NULL
, oba zwracają to samo, ale count(*)
jest nieco krótszy i szybszy.
Informacje o GROUP BY 1
:
- Oświadczenie GROUP BY + CASE