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:
LATERALjuga dapat mendahului panggilan fungsiFROMitem, 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