Saya menemukan cara untuk menggabungkan string dari baris yang berbeda menjadi satu baris. Saya ingin melakukan ini di banyak tempat berbeda, jadi memiliki fungsi untuk memfasilitasi ini akan menyenangkan. Saya sudah mencoba solusi menggunakan COALESCE
dan FOR XML
, tetapi solusi tersebut tidak cocok untuk saya.
Agregasi string akan melakukan sesuatu seperti ini:
id | Name Result: id | Names
-- - ---- -- - -----
1 | Matt 1 | Matt, Rocks
1 | Rocks 2 | Stylus
2 | Stylus
Saya telah melihat fungsi agregat yang ditentukan CLR sebagai pengganti COALESCE
dan FOR XML
, tetapi tampaknya SQL Azure tidak mendukung hal-hal yang ditentukan CLR, yang menyebalkan bagi saya karena saya tahu bisa menggunakannya akan menyelesaikan banyak hal. masalah bagi saya.
Apakah ada solusi yang mungkin, atau metode optimal serupa (yang mungkin tidak seoptimal CLR, tapi hei saya akan mengambil apa yang bisa saya dapatkan) yang dapat saya gunakan untuk mengumpulkan barang-barang saya?
for xml
tidak berhasil untuk Anda?for xml
menunjukkan penggunaan 25% dalam hal kinerja kueri (sebagian besar kueri!)for xml path
kueri. Beberapa lebih cepat dari yang lain. Itu bisa tergantung pada data Anda tetapi yang menggunakandistinct
menurut pengalaman saya lebih lambat daripada menggunakangroup by
. Dan jika Anda menggunakan.value('.', nvarchar(max))
untuk mendapatkan nilai gabungan Anda harus mengubahnya menjadi.value('./text()[1]', nvarchar(max))
Jawaban:
LARUTAN
Definisi optimal dapat bervariasi, tetapi berikut ini cara menggabungkan string dari baris yang berbeda menggunakan Transact SQL biasa, yang akan berfungsi dengan baik di Azure.
PENJELASAN
Pendekatan ini terdiri dari tiga langkah:
Beri nomor baris yang menggunakan
OVER
danPARTITION
mengelompokkan dan mengurutkannya sesuai kebutuhan untuk penggabungan. Hasilnya adalahPartitioned
CTE. Kami menyimpan jumlah baris di setiap partisi untuk menyaring hasilnya nanti.Menggunakan rekursif CTE (
Concatenated
) iterasi melalui nomor baris (NameNumber
kolom) menambahkanName
nilai keFullName
kolom.Filter semua hasil kecuali yang tertinggi
NameNumber
.Harap diingat bahwa untuk membuat kueri ini dapat diprediksi, seseorang harus menentukan pengelompokan (misalnya, dalam baris skenario Anda dengan baris yang sama
ID
digabung) dan pengurutan (saya berasumsi bahwa Anda cukup mengurutkan string menurut abjad sebelum penggabungan).Saya telah menguji solusi dengan cepat di SQL Server 2012 dengan data berikut:
Hasil query:
sumber
Apakah metode yang menggunakan FOR XML PATH seperti di bawah ini benar-benar lambat? Itzik Ben-Gan menulis bahwa metode ini memiliki kinerja yang baik dalam bukunya T-SQL Querying (Mr. Ben-Gan adalah sumber yang dapat dipercaya, menurut saya).
sumber
id
kolom itu setelah ukuran tabel menjadi masalah.&
dialihkan ke&
, dan seterusnya). Solusi yang lebih tepatfor xml
disediakan di sini .Bagi kita yang menemukan ini
dan tidak menggunakan Database Azure SQL:STRING_AGG()
di PostgreSQL, SQL Server 2017 dan Azure SQLhttps://www.postgresql.org/docs/current/static/functions-aggregate.html
https://docs.microsoft.com/en-us/sql/t-sql/ functions / string-agg-transact-sql
GROUP_CONCAT()
di MySQLhttp://dev.mysql.com/doc/refman/5.7/en/group-by-functions.html#function_group-concat
(Terima kasih kepada @Brianjorden dan @milanio untuk pembaruan Azure)
Kode Contoh:
SQL Fiddle: http://sqlfiddle.com/#!18/89251/1
sumber
STRING_AGG
didorong kembali ke 2017. Ini tidak tersedia pada 2016.Meskipun jawaban @serge benar tetapi saya membandingkan konsumsi waktu jalannya terhadap xmlpath dan saya menemukan xmlpath sangat cepat. Saya akan menulis kode pembanding dan Anda dapat memeriksanya sendiri. Ini adalah cara @serge:
Dan ini adalah cara xmlpath:
sumber
Pembaruan: Ms SQL Server 2017+, Azure SQL Database
Kamu bisa memakai:
STRING_AGG
.Penggunaannya cukup sederhana untuk permintaan OP:
Baca lebih banyak
Nah jawaban lama saya dihapus dengan benar (kiri dalam kebijaksanaan di bawah), tetapi jika ada yang kebetulan mendarat di sini di masa depan, ada kabar baik. Mereka telah menerapkan STRING_AGG () di Azure SQL Database juga. Itu harus menyediakan fungsionalitas tepat yang awalnya diminta dalam posting ini dengan dukungan bawaan dan bawaan. @hrobky menyebutkan ini sebelumnya sebagai fitur SQL Server 2016 pada saat itu.
--- Posting Lama: Reputasi di sini tidak cukup untuk membalas @hrobky secara langsung, tetapi STRING_AGG tampak hebat, namun saat ini hanya tersedia di SQL Server 2016 vNext. Semoga ini juga akan segera menyusul ke Azure SQL Databse ..
sumber
STRING_AGG()
dinyatakan tersedia di SQL Server 2017, di tingkat kompatibilitas apa pun. docs.microsoft.com/en-us/sql/t-sql/functions/…Anda dapat menggunakan + = untuk menggabungkan string, misalnya:
jika Anda memilih @test, ini akan memberi Anda semua nama yang digabungkan
sumber
select @test += name + ', ' from names
ORDER BY
pertanyaan dalam kueri Anda. Anda harus menggunakan salah satu alternatif yang terdaftar.Saya menemukan jawaban Serge sangat menjanjikan, tetapi saya juga mengalami masalah kinerja dengan itu seperti yang tertulis. Namun, ketika saya menata ulangnya untuk menggunakan tabel sementara dan tidak menyertakan tabel CTE ganda, kinerja berubah dari 1 menit 40 detik menjadi sub-detik untuk 1000 rekaman gabungan. Ini untuk siapa saja yang perlu melakukan ini tanpa FOR XML di versi SQL Server yang lebih lama:
sumber