Apakah mungkin untuk membangun SQL untuk menggabungkan nilai kolom dari beberapa baris?
Berikut ini adalah contohnya:
Tabel A
PID SEBUAH B C
Tabel B
PID SEQ Desc A 1 Have A 2 a nice 3 hari. B 1 Kerja Bagus. C 1 Ya C 2 kita bisa C 3 lakukan C 4 pekerjaan ini!
Output dari SQL seharusnya -
PID Desc Semoga harimu menyenangkan. B Kerja Bagus. C Ya kita bisa melakukan pekerjaan ini!
Jadi pada dasarnya kolom Desc untuk tabel out put adalah gabungan dari nilai SEQ dari Tabel B?
Adakah bantuan dengan SQL?
sql
oracle
string-aggregation
jagamot
sumber
sumber
Jawaban:
Ada beberapa cara tergantung pada versi apa yang Anda miliki - lihat dokumentasi oracle tentang teknik agregasi string . Yang sangat umum adalah menggunakan
LISTAGG
:Kemudian bergabunglah untuk
A
memilih yangpids
Anda inginkan.Catatan: Di luar kotak,
LISTAGG
hanya berfungsi dengan benar denganVARCHAR2
kolom.sumber
Ada juga
XMLAGG
fungsi, yang berfungsi pada versi sebelum 11.2. KarenaWM_CONCAT
tidak terdokumentasi dan tidak didukung oleh Oracle , disarankan untuk tidak menggunakannya dalam sistem produksi.Dengan
XMLAGG
Anda dapat melakukan hal berikut:Apa yang dilakukan adalah
ename
kolom (disatukan dengan koma) dariemployee_names
tabel dalam elemen xml (dengan tag E)sumber
Dengan klausa model SQL:
Saya menulis tentang ini di sini . Dan jika Anda mengikuti tautan ke utas-OTN Anda akan menemukan lebih banyak lagi, termasuk perbandingan kinerja.
sumber
The LISTAGG fungsi analitik diperkenalkan di Oracle 11g Release 2 , sehingga sangat mudah untuk string agregat. Jika Anda menggunakan 11g Release 2, Anda harus menggunakan fungsi ini untuk agregasi string. Silakan merujuk url di bawah ini untuk informasi lebih lanjut tentang penggabungan string.
http://www.oracle-base.com/articles/misc/StringAggregationTechniques.php
Penggabungan string
sumber
Seperti yang disarankan sebagian besar jawaban,
LISTAGG
adalah pilihan yang jelas. Namun, satu aspek yang menggangguLISTAGG
adalah bahwa jika panjang total string gabungan melebihi 4000 karakter (batas untukVARCHAR2
dalam SQL), kesalahan di bawah ini dilemparkan, yang sulit untuk dikelola dalam versi Oracle hingga 12.1Fitur baru yang ditambahkan dalam 12cR2 adalah
ON OVERFLOW
klausaLISTAGG
. Kueri termasuk klausa ini akan terlihat seperti:Di atas akan membatasi output hingga 4000 karakter tetapi tidak akan membuang
ORA-01489
kesalahan.Ini adalah beberapa opsi tambahan
ON OVERFLOW
klausa:ON OVERFLOW TRUNCATE 'Contd..'
: Ini akan ditampilkan'Contd..'
di akhir string (Default is...
)ON OVERFLOW TRUNCATE ''
: Ini akan menampilkan 4000 karakter tanpa string yang berakhir.ON OVERFLOW TRUNCATE WITH COUNT
: Ini akan menampilkan jumlah total karakter pada bagian akhir setelah karakter yang diakhiri. Misalnya: - '...(5512)
'ON OVERFLOW ERROR
: Jika Anda mengharapkanLISTAGG
gagal denganORA-01489
kesalahan (Yang merupakan standarnya sih).sumber
Bagi mereka yang harus menyelesaikan masalah ini menggunakan Oracle 9i (atau lebih awal), Anda mungkin perlu menggunakan SYS_CONNECT_BY_PATH, karena LISTAGG tidak tersedia.
Untuk menjawab OP, kueri berikut akan menampilkan PID dari Tabel A dan menggabungkan semua kolom DESC dari Tabel B:
Mungkin juga ada contoh di mana kunci dan nilai semua terkandung dalam satu tabel. Kueri berikut dapat digunakan di mana tidak ada Tabel A, dan hanya Tabel B yang ada:
Semua nilai dapat disusun ulang sesuai keinginan. Deskripsi yang digabungkan secara individu dapat disusun kembali dalam klausa PARTITION BY, dan daftar PID dapat disusun ulang dalam klausa ORDER BY final.
Bergantian: mungkin ada saat-saat ketika Anda ingin menggabungkan semua nilai dari seluruh tabel menjadi satu baris.
Gagasan utama di sini adalah menggunakan nilai artifisial untuk kelompok deskripsi yang akan digabungkan.
Dalam kueri berikut, string konstan '1' digunakan, tetapi nilai apa pun akan berfungsi:
Deskripsi gabungan individu dapat disusun kembali dalam klausa PARTITION BY.
Beberapa jawaban lain di halaman ini juga menyebutkan referensi yang sangat membantu ini: https://oracle-base.com/articles/misc/string-aggregation-techniques
sumber
LISTAGG memberikan kinerja terbaik jika menyortir adalah suatu keharusan (00: 00: 05.85)
SELECT pid, LISTAGG(Desc, ' ') WITHIN GROUP (ORDER BY seq) AS description FROM B GROUP BY pid;
COLLECT memberikan kinerja terbaik jika penyortiran tidak diperlukan (00: 00: 02.90):
SELECT pid, TO_STRING(CAST(COLLECT(Desc) AS varchar2_ntt)) AS Vals FROM B GROUP BY pid;
KUMPULKAN dengan pemesanan sedikit lebih lambat (00: 00: 07.08):
SELECT pid, TO_STRING(CAST(COLLECT(Desc ORDER BY Desc) AS varchar2_ntt)) AS Vals FROM B GROUP BY pid;
Semua teknik lainnya lebih lambat.
sumber
Sebelum Anda menjalankan kueri pemilihan, jalankan ini:
SET SERVEROUT ON SIZE 6000
sumber
Coba kode ini:
sumber
Di pilih tempat Anda ingin rangkaian Anda, panggil fungsi SQL.
Sebagai contoh:
Kemudian untuk fungsi SQL:
Sintaks Function Header mungkin salah, tetapi prinsipnya berhasil.
sumber