Jawaban untuk pertanyaan awal
Postgres memungkinkan fungsi pengembalian set (SRF) untuk mengalikan baris. generate_series()
adalah temanmu:
INSERT INTO b (all_names, birthday)
SELECT names, current_date -- AS birthday ??
FROM (SELECT names, generate_series(1, number) FROM a);
Sejak diperkenalkannya LATERAL
di Postgres 9.3 Anda dapat tetap berpegang pada SQL standar:SRF bergerak dari SELECT
ke FROM
daftar:
INSERT INTO b (all_names, birthday)
SELECT a.names, current_date -- AS birthday ??
FROM a, generate_series(1, a.number) AS rn
LATERAL
tersirat di sini, seperti yang dijelaskan dalam manual:
LATERAL
juga dapat mendahului panggilan fungsiFROM
item, tetapi dalam hal ini adalah kata noise, karena ekspresi fungsi dapat merujuk ke item FROM sebelumnya dalam hal apa pun.
Operasi terbalik
Di atas adalah operasi kebalikan (kurang-lebih) dari agregat sederhana count()
:
INSERT INTO a (name, number)
SELECT all_names, count(*)
FROM b
GROUP BY 1;
... yang sesuai dengan pertanyaan Anda yang telah diperbarui.
Perhatikan perbedaan halus antara count(*)
dan count(all_names)
. Yang pertama menghitung semua baris, apa pun yang terjadi, sedangkan yang kedua hanya menghitung baris di mana all_names IS NOT NULL
. Jika kolom Anda all_names
didefinisikan sebagai NOT NULL
, keduanya mengembalikan yang sama, tetapi count(*)
sedikit lebih pendek dan lebih cepat.
Tentang GROUP BY 1
:
- pernyataan KELOMPOK BERDASARKAN + KASUS