Phương pháp tiếp cận
Cách tiếp cận sau đây có thể được sử dụng để loại bỏ trùng lặp danh sách các giá trị được phân tách.
- Sử dụng
REPLACE()
chức năng chuyển đổi các dấu phân cách khác nhau thành cùng một dấu phân cách. - Sử dụng
REPLACE()
hàm chèn các thẻ đóng và mở XML để tạo một phân đoạn XML - Sử dụng
CAST(expr AS XML)
hàm để chuyển đổi đoạn trên thành kiểu dữ liệu XML - Sử dụng
OUTER APPLY
để áp dụng hàm giá trị bảngnodes()
để chia đoạn XML thành các thẻ XML cấu thành của nó. Điều này trả về mỗi thẻ XML trên một hàng riêng biệt. - Chỉ trích xuất giá trị từ thẻ XML bằng cách sử dụng
value()
và trả về giá trị bằng kiểu dữ liệu được chỉ định. - Thêm dấu phẩy sau giá trị được đề cập ở trên.
- Lưu ý rằng các giá trị này được trả về trên các hàng riêng biệt. Việc sử dụng
DISTINCT
từ khóa hiện xóa các hàng trùng lặp (tức là các giá trị). - Sử dụng
FOR XML PATH('')
để nối các giá trị trên nhiều hàng thành một hàng duy nhất.
Truy vấn
Đưa phương pháp trên vào biểu mẫu truy vấn:
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('')
Đầu vào &Kết quả
Cho đầu vào:
Truy vấn trên sẽ trả về kết quả:
Chú ý dấu phẩy ở cuối. Tôi sẽ để nó như một bài tập cho bạn để loại bỏ điều đó.
CHỈNH SỬA:Số lượng trùng lặp
OP đã yêu cầu trong một nhận xét " làm cách nào để tôi cũng có được số lượng các bản sao? Trong một cột riêng biệt ".
Cách đơn giản nhất là sử dụng truy vấn trên nhưng xóa dòng cuối cùng FOR XML PATH('')
. Sau đó, đếm tất cả các giá trị và các giá trị riêng biệt được trả về bởi SELECT
biểu thức trong truy vấn trên (tức là PivotedTable.PivotedColumn.value('.','nvarchar(max)')
). Sự khác biệt giữa số lượng tất cả các giá trị và số lượng các giá trị riêng biệt là số lượng các giá trị trùng lặp.
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)
Đối với cùng một đầu vào được hiển thị ở trên, đầu ra của truy vấn này là:
CountOfAllValues CountOfUniqueValues CountOfDuplicateValues
---------------- ------------------- ----------------------
8 4 4