Saya telah mengajukan pertanyaan di sini: /programming/43807566/how-to-divide-two-values-from-the-same-column-but-at-different-rows
tentang membagi nilai dari tabel yang sama, pada kolom yang sama tetapi pada baris yang berbeda. Sekarang saya memiliki masalah di mana saya memiliki lebih banyak pembilang dan penyebut (dengan berbeda uns
). Apakah masih self join
cara yang baik untuk menyelesaikan masalah ini dengan Postgres atau ada solusi yang lebih baik?
Contoh:
| postcode | value | uns |
|----------|-------|-----|
| AA | 40 | 53 |
| BB | 20 | 53 |
| AA | 10 | 54 |
| AA | 20 | 55 |
| AA | 10 | 56 |
| AA | 30 | 57 |
| AA | 50 | 58 |
| BB | 10 | 54 |
| BB | 10 | 55 |
| BB | 70 | 56 |
| BB | 80 | 57 |
| BB | 10 | 58 |
Hasilnya harus:
| postcode | formula |
|----------|------------|
| AA | 18.888... |
| BB | 14.375 |
Di mana nilai dikelompokkan berdasarkan kode pos dan rumusnya (nilai dengan uns):
(V53 * V56 + V54 * V57 + V55 * V58) / (V56 + V57 + V58)
Membayar perhatian untuk menghindari pembagian akhirnya dengan nol. Formula bisa menjadi lebih rumit tetapi itu adalah contoh yang bagus.
uns
menjadi nama kolom - dari sana, formula apa pun yang menggunakan nilai harus dapat diterapkan. Apakah formula tersebut akan dikodekan secara keras, atau diturunkan secara dinamis entah bagaimana?Jawaban:
Ini adalah masalah pivot / crosstab , seperti Michael yang telah didiagnosis secara akurat.
Jika Anda tidak terbiasa dengan
tablefunc
modul di Postgres, baca instruksi dasar di sini:Permintaan menjadi sederhana dan sangat cepat (lebih cepat dari solusi lain yang disajikan di sini):
NULLIF
untuk mencegah pembagian dengan nol.Aku di sini
sumber
Anda bisa menggabungkan semua pasangan uns / value menjadi objek JSON, lalu menggunakannya untuk mengakses nilai UNS dengan nama. Ini membutuhkan beberapa casting karena nilainya hanya dapat diekstraksi sebagai teks dari objek JSON, tetapi rumusnya terlihat sangat mirip dengan deskripsi Anda kemudian:
Saya telah membagi agregasi, evaluasi penyebut dan pembagi dan pembagian akhir menjadi tiga langkah untuk membuatnya lebih mudah dibaca.
Contoh online: http://rextester.com/IZYT54566
Anda dapat menyederhanakan rumus dengan membuat fungsi:
sumber
Pola PIVOT akan bekerja untuk ini. Itu mengkonversi nilai baris ke kolom dalam satu baris, sesuai dengan kunci bersama mereka. Ada beberapa cara untuk mengimplementasikannya. Beberapa hanya membutuhkan satu pemindaian tabel.
Setelah PIVOT Anda akan memiliki tabel dengan satu baris per kode pos dan kolom per nilai. Sisa kueri akan ditulis seolah-olah mereferensikan satu tabel.
sumber
Dengan asumsi bahwa
(postcode, uns)
yangUNIQUE
(mungkin, seorang PK), pola PIVOT, sebagaimana telah berkomentar oleh @ michael-hijau, dapat diimplementasikan portable menggunakan query berikut:Periksa di SQLFiddle .
sumber
Dengan asumsi bahwa
(postcode, uns)
yangUNIQUE
(mungkin, PK a), mungkin paling sederhana cara, mungkin yang paling portabel satu, meskipun mungkin tidak optimal: digunakan sebagai banyak subselects yang diperlukan :Periksa di SQLFiddle .
sumber