Pendekatan
Pendekatan berikut dapat digunakan untuk menghapus duplikat daftar nilai yang dibatasi.
- Gunakan
REPLACE()
berfungsi untuk mengubah pembatas yang berbeda menjadi pembatas yang sama. - Gunakan
REPLACE()
berfungsi untuk menginjeksi tag penutup dan pembuka XML untuk membuat fragmen XML - Gunakan
CAST(expr AS XML)
berfungsi untuk mengubah fragmen di atas menjadi tipe data XML - Gunakan
OUTER APPLY
untuk menerapkan fungsi bernilai tabelnodes()
untuk membagi fragmen XML menjadi tag XML penyusunnya. Ini mengembalikan setiap tag XML pada baris terpisah. - Ekstrak nilai saja dari tag XML menggunakan
value()
fungsi, dan mengembalikan nilai menggunakan tipe data yang ditentukan. - Tambahkan koma setelah nilai yang disebutkan di atas.
- Perhatikan bahwa nilai-nilai ini dikembalikan pada baris terpisah. Penggunaan
DISTINCT
kata kunci sekarang menghapus baris duplikat (yaitu nilai). - Gunakan
FOR XML PATH('')
klausa untuk menggabungkan nilai di beberapa baris menjadi satu baris.
Kueri
Menempatkan pendekatan di atas dalam bentuk kueri:
SELECT DISTINCT PivotedTable.PivotedColumn.value('.','nvarchar(max)') + ','
FROM (
-- This query returns the following in theDataXml column:
-- <tag>test1</tag><tag>test2</tag><tag>test1</tag><tag>test2</tag><tag>test3</tag><tag>test4</tag><tag>test4</tag><tag>test4</tag>
-- i.e. it has turned the original delimited data into an XML fragment
SELECT
DataTable.DataColumn AS DataRaw
, CAST(
'<tag>'
-- First replace commas with pipes to have only a single delimiter
-- Then replace the pipe delimiters with a closing and opening tag
+ replace(replace(DataTable.DataColumn, ',','|'), '|','</tag><tag>')
-- Add a final set of closing tags
+ '</tag>'
AS XML) AS DataXml
FROM ( SELECT 'test1,test2,test1|test2,test3|test4,test4|test4' AS DataColumn) AS DataTable
) AS x
OUTER APPLY DataXml.nodes('tag') AS PivotedTable(PivotedColumn)
-- Running the query without the following line will return the data in separate rows
-- Running the query with the following line returns the rows concatenated, i.e. it returns:
-- test1,test2,test3,test4,
FOR XML PATH('')
Masukan &Hasil
Diberikan masukan:
Kueri di atas akan mengembalikan hasilnya:
Perhatikan tanda koma di akhir. Saya akan meninggalkannya sebagai latihan bagi Anda untuk menghapusnya.
EDIT:Hitungan Duplikat
OP diminta dalam komentar "bagaimana cara mendapatkan jumlah duplikat juga? di kolom terpisah ".
Cara paling sederhana adalah dengan menggunakan kueri di atas tetapi hapus baris terakhir FOR XML PATH('')
. Kemudian, menghitung semua nilai dan nilai berbeda yang dikembalikan oleh SELECT
ekspresi dalam kueri di atas (yaitu PivotedTable.PivotedColumn.value('.','nvarchar(max)')
). Perbedaan antara jumlah semua nilai dan jumlah nilai yang berbeda adalah jumlah nilai duplikat.
SELECT
COUNT(PivotedTable.PivotedColumn.value('.','nvarchar(max)')) AS CountOfAllValues
, COUNT(DISTINCT PivotedTable.PivotedColumn.value('.','nvarchar(max)')) AS CountOfUniqueValues
-- The difference of the previous two counts is the number of duplicate values
, COUNT(PivotedTable.PivotedColumn.value('.','nvarchar(max)'))
- COUNT(DISTINCT PivotedTable.PivotedColumn.value('.','nvarchar(max)')) AS CountOfDuplicateValues
FROM (
-- This query returns the following in theDataXml column:
-- <tag>test1</tag><tag>test2</tag><tag>test1</tag><tag>test2</tag><tag>test3</tag><tag>test4</tag><tag>test4</tag><tag>test4</tag>
-- i.e. it has turned the original delimited data into an XML fragment
SELECT
DataTable.DataColumn AS DataRaw
, CAST(
'<tag>'
-- First replace commas with pipes to have only a single delimiter
-- Then replace the pipe delimiters with a closing and opening tag
+ replace(replace(DataTable.DataColumn, ',','|'), '|','</tag><tag>')
-- Add a final set of closing tags
+ '</tag>'
AS XML) AS DataXml
FROM ( SELECT 'test1,test2,test1|test2,test3|test4,test4|test4' AS DataColumn) AS DataTable
) AS x
OUTER APPLY DataXml.nodes('tag') AS PivotedTable(PivotedColumn)
Untuk input yang sama seperti yang ditunjukkan di atas, output dari kueri ini adalah:
CountOfAllValues CountOfUniqueValues CountOfDuplicateValues
---------------- ------------------- ----------------------
8 4 4