Tilgang
Følgende fremgangsmåde kan bruges til at deduplikere en afgrænset liste over værdier.
- Brug
REPLACE()
funktion til at konvertere forskellige skilletegn til samme afgrænsningstegn. - Brug
REPLACE()
funktion til at indsætte XML-luknings- og åbningstags for at skabe et XML-fragment - Brug
CAST(expr AS XML)
funktion til at konvertere ovenstående fragment til XML-datatypen - Brug
OUTER APPLY
for at anvende den tabelværdierede funktionnodes()
at opdele XML-fragmentet i dets XML-tags. Dette returnerer hvert XML-tag på en separat række. - Udtræk kun værdien fra XML-tagget ved hjælp af
value()
funktion, og returnerer værdien ved hjælp af den angivne datatype. - Tilføj et komma efter den ovennævnte værdi.
- Bemærk, at disse værdier returneres på separate rækker. Brugen af
DISTINCT
søgeord fjerner nu dublerede rækker (dvs. værdier). - Brug
FOR XML PATH('')
klausul for at sammenkæde værdierne på tværs af flere rækker til en enkelt række.
Forespørgsel
Anbringelse af ovenstående fremgangsmåde i forespørgselsform:
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('')
Input og resultat
Givet input:
Ovenstående forespørgsel vil returnere resultatet:
Læg mærke til det efterfølgende komma til sidst. Jeg overlader det som en øvelse til dig at fjerne det.
EDIT:Antal dubletter
OP anmodede i en kommentar "hvordan får jeg også antallet af dubletter? i en separat kolonne ".
Den enkleste måde ville være at bruge ovenstående forespørgsel, men fjerne den sidste linje FOR XML PATH('')
. Derefter tælles alle værdier og forskellige værdier returneret af SELECT
udtryk i ovenstående forespørgsel (dvs. PivotedTable.PivotedColumn.value('.','nvarchar(max)')
). Forskellen mellem antallet af alle værdier og antallet af distinkte værdier er antallet af duplikerede værdier.
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)
For det samme input som vist ovenfor er outputtet af denne forespørgsel:
CountOfAllValues CountOfUniqueValues CountOfDuplicateValues
---------------- ------------------- ----------------------
8 4 4