Antwoord op oorspronkelijke vraag
Met Postgres kunnen set-retourfuncties (SRF) rijen vermenigvuldigen. generate_series()
is je vriend:
INSERT INTO b (all_names, birthday)
SELECT names, current_date -- AS birthday ??
FROM (SELECT names, generate_series(1, number) FROM a);
Sinds de introductie van LATERAL
in Postgres 9.3 je kunt je aan standaard SQL houden:de SRF gaat van de SELECT
naar de FROM
lijst:
INSERT INTO b (all_names, birthday)
SELECT a.names, current_date -- AS birthday ??
FROM a, generate_series(1, a.number) AS rn
LATERAL
is hier impliciet, zoals uitgelegd in de handleiding:
LATERAL
kan ook voorafgaan aan een functieaanroepFROM
item, maar in dit geval is het een ruiswoord, omdat de functie-uitdrukking in ieder geval kan verwijzen naar eerdere FROM-items.
Omgekeerde werking
Het bovenstaande is de omgekeerde bewerking (ongeveer) van een eenvoudig totaal count()
:
INSERT INTO a (name, number)
SELECT all_names, count(*)
FROM b
GROUP BY 1;
... die past bij uw bijgewerkte vraag.
Let op een subtiel verschil tussen count(*)
en count(all_names)
. De eerste telt alle rijen, wat er ook gebeurt, terwijl de laatste alleen rijen telt waar all_names IS NOT NULL
. Als uw kolom all_names
is gedefinieerd als NOT NULL
, geven beide hetzelfde terug, maar count(*)
is iets korter en sneller.
Over GROUP BY 1
:
- GROUP BY + CASE-instructie