Meja adalah:
+----+------+
| Id | Name |
+----+------+
| 1 | aaa |
| 1 | bbb |
| 1 | ccc |
| 1 | ddd |
| 1 | eee |
+----+------+
Output yang dibutuhkan:
+----+---------------------+
| Id | abc |
+----+---------------------+
| 1 | aaa,bbb,ccc,ddd,eee |
+----+---------------------+
Pertanyaan:
SELECT ID,
abc = STUFF(
(SELECT ',' + name FROM temp1 FOR XML PATH ('')), 1, 1, ''
)
FROM temp1 GROUP BY id
Kueri ini berfungsi dengan baik. Tetapi saya hanya perlu penjelasan bagaimana cara kerjanya atau apakah ada cara lain atau pendek untuk melakukan ini.
Saya menjadi sangat bingung untuk memahami hal ini.
sql
sql-server
database
Puneet Chawla
sumber
sumber
ID
unik dalam tabel yang berbeda dari entitas yang berbeda, dan tabel ini menyimpan barang-barang milik mereka.Jawaban:
Inilah cara kerjanya:
1. Dapatkan string elemen XML dengan UNTUK XML
Menambahkan UNTUK XML PATH ke akhir permintaan memungkinkan Anda untuk output hasil permintaan sebagai elemen XML, dengan nama elemen yang terkandung dalam argumen PATH. Misalnya, jika kita menjalankan pernyataan berikut:
Dengan mengirimkan string kosong (UNTUK XML PATH ('')), kami mendapatkan yang berikut:
2. Hapus koma terkemuka dengan STUFF
Pernyataan STUFF secara harfiah "memasukkan" satu string ke string lain, menggantikan karakter di dalam string pertama. Namun, kami menggunakannya hanya untuk menghapus karakter pertama dari daftar nilai yang dihasilkan.
Parameternya
STUFF
adalah:Jadi kita berakhir dengan:
3. Bergabunglah pada id untuk mendapatkan daftar lengkap
Selanjutnya kita cukup gabungkan ini pada daftar id di tabel temp, untuk mendapatkan daftar ID dengan nama:
Dan kami memiliki hasil kami:
Semoga ini membantu!
sumber
LISTAGG
fungsi dalam Oracle 11gR2. Saya melewatkan fungsi itu pada hari-hari ketika saya harus menggunakan ini sebagai gantinya. techonthenet.com/oracle/functions/listagg.phplist
fungsi selama beberapa dekade. Sayangnya Microsoft berbasis SQLServer di ASE Sybase sebagai gantinya, dan tidak pernah repot dengan fungsi daftar sampai tahun lalu. Saya setuju - ini membingungkan. Dan kemudian mereka melakukannya, mereka menyebutnyastring_agg
. Saya pikirlist
cukup jelas.Artikel ini mencakup berbagai cara untuk merangkai string dalam SQL, termasuk versi yang disempurnakan dari kode Anda yang tidak mengkodekan nilai-nilai gabungan XML.
Untuk memahami apa yang terjadi, mulailah dengan kueri batin:
Karena Anda menentukan
FOR XML
, Anda akan mendapatkan satu baris berisi fragmen XML yang mewakili semua baris.Karena Anda belum menentukan alias kolom untuk kolom pertama, setiap baris akan dibungkus dengan elemen XML dengan nama yang ditentukan dalam tanda kurung setelah
FOR XML PATH
. Misalnya, jika sudahFOR XML PATH ('X')
, Anda akan mendapatkan dokumen XML yang tampak seperti:Tapi, karena Anda belum menentukan nama elemen, Anda hanya mendapatkan daftar nilai:
The
.value('.', 'varchar(max)')
hanya mengambil nilai dari fragmen XML yang dihasilkan, tanpa XML-encoding setiap "khusus" karakter. Anda sekarang memiliki string yang terlihat seperti:The
STUFF
Fungsi kemudian menghapus terkemuka koma, memberikan Anda hasil akhir yang terlihat seperti:Sekilas terlihat membingungkan, tetapi cenderung berkinerja cukup baik dibandingkan dengan beberapa opsi lain.
sumber
TYPE
direktif memberitahu SQL untuk mengembalikan data menggunakanxml
jenis. Tanpa itu, data dikembalikan sebagainvarchar(max)
. Ini digunakan di sini untuk menghindari masalah penyandian XML jika ada karakter khusus diname
kolom.TYPE
dan.value('.', 'varchar(max)')
, maka Anda bisa berakhir dengan entitas yang disandikan dalam hasil.Mode PATH digunakan dalam menghasilkan XML dari kueri SELECT
Outputnya adalah elemen-sentris XML di mana setiap nilai kolom dalam rowset yang dihasilkan dibungkus dalam elemen baris. Karena klausa SELECT tidak menentukan alias untuk nama kolom, nama elemen anak yang dihasilkan sama dengan nama kolom yang sesuai dalam klausa SELECT.
Untuk setiap baris dalam rowset, sebuah tag ditambahkan.
Untuk Langkah 2: Jika Anda menentukan string panjang nol, elemen pembungkus tidak diproduksi.
Pada Langkah 4 kita menggabungkan nilai-nilai.
Pada Langkah 6 kami mengelompokkan tanggal dengan ID.
STUFF (source_string, start, length, add_string) Parameter atau Argumen source_string String sumber untuk dimodifikasi. mulai Posisi di source_string untuk menghapus karakter panjang dan kemudian masukkan add_string. length Jumlah karakter yang akan dihapus dari source_string. add_string Urutan karakter untuk dimasukkan ke dalam source_string di posisi awal.
sumber
','
ditentukan, dikombinasikan dengan('')
path setelah xml, menyebabkan penggabungan terjadiSELECT 'a' FROM some_table FOR XML PATH('')
akan menghasilkan:'aaaaaaa'
. Tetapi jika nama kolom akan ditentukan:SELECT 'a' AS Col FROM some_table FOR XML PATH('')
Anda mendapatkan hasil:<Col>a</Col><Col>a</Col><Col>a</Col>
Ada fungsi yang sangat baru di Azure SQL Database dan SQL Server (dimulai dengan 2017) untuk menangani skenario yang tepat ini. Saya percaya ini akan berfungsi sebagai metode resmi asli untuk apa yang Anda coba capai dengan metode XML / STUFF. Contoh:
STRING_AGG - https://msdn.microsoft.com/en-us/library/mt790580.aspx
EDIT: Ketika saya awalnya memposting ini saya menyebutkan SQL Server 2016 karena saya pikir saya melihat bahwa pada fitur potensial yang harus dimasukkan. Entah saya ingat itu salah atau ada yang berubah, terima kasih atas edit yang disarankan untuk memperbaiki versinya. Juga, cukup terkesan dan tidak sepenuhnya menyadari proses peninjauan multi-langkah yang hanya menarik saya untuk opsi terakhir.
sumber
Di
for xml path
, jika kita mendefinisikan nilai apa pun[ for xml path('ENVLOPE') ]
maka tag ini akan ditambahkan dengan setiap baris:sumber
Di sini, dalam fungsi STUFF permintaan di atas digunakan untuk hanya menghapus koma pertama
(,)
dari string xml yang dihasilkan(,aaa,bbb,ccc,ddd,eee)
maka akan menjadi(aaa,bbb,ccc,ddd,eee)
.Dan
FOR XML PATH('')
cukup mengonversi data kolom menjadi(,aaa,bbb,ccc,ddd,eee)
string tetapi di PATH kita melewati '' sehingga tidak akan membuat tag XML.Dan pada akhirnya kami telah mengelompokkan catatan menggunakan kolom ID .
sumber
Saya melakukan debugging dan akhirnya mengembalikan permintaan 'boneka' saya ke sana dengan cara biasa.
Secara sederhana
memberi saya isi tabel untuk menulis ke tabel log dari pemicu saya debug.
sumber
sumber
STUFF ((PILIH berbeda ',' + CAST (T.ID) DARI Tabel T di mana T.ID = 1 UNTUK XML PATH ('')), 1,1, '') SEBAGAI Nama
sumber
Saya sering menggunakan dengan klausa mana
sumber