sql >> Database teknologi >  >> RDS >> Sqlserver

fjern dubletter fra komma eller pipeline-operatørstreng

Tilgang

Følgende fremgangsmåde kan bruges til at deduplikere en afgrænset liste over værdier.

  1. Brug REPLACE() funktion til at konvertere forskellige skilletegn til samme afgrænsningstegn.
  2. Brug REPLACE() funktion til at indsætte XML-luknings- og åbningstags for at skabe et XML-fragment
  3. Brug CAST(expr AS XML) funktion til at konvertere ovenstående fragment til XML-datatypen
  4. Brug OUTER APPLY for at anvende den tabelværdierede funktion nodes() at opdele XML-fragmentet i dets XML-tags. Dette returnerer hvert XML-tag på en separat række.
  5. 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.
  6. Tilføj et komma efter den ovennævnte værdi.
  7. Bemærk, at disse værdier returneres på separate rækker. Brugen af ​​DISTINCT søgeord fjerner nu dublerede rækker (dvs. værdier).
  8. 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


  1. CodeIgniter og Oracle-database - ActiveRecord insert() tilføjer dobbelte anførselstegn i forespørgslen

  2. Skift indsat værdi med trigger

  3. Værtspakke på Chokolade

  4. MySQL INDSÆT andet, hvis der findes OPDATERING