sql >> Database >  >> RDS >> Sqlserver

verwijder duplicaten uit een komma- of pijplijnoperatortekenreeks

Aanpak

De volgende benadering kan worden gebruikt om een ​​lijst met waarden met scheidingstekens te dedupliceren.

  1. Gebruik de REPLACE() functie om verschillende scheidingstekens om te zetten in hetzelfde scheidingsteken.
  2. Gebruik de REPLACE() functie om XML-sluit- en openingstags te injecteren om een ​​XML-fragment te maken
  3. Gebruik de CAST(expr AS XML) functie om het bovenstaande fragment om te zetten in het XML-gegevenstype
  4. Gebruik OUTER APPLY om de tabelwaardefunctie nodes() toe te passen om het XML-fragment te splitsen in zijn samenstellende XML-tags. Dit retourneert elke XML-tag op een aparte rij.
  5. Extract alleen de waarde uit de XML-tag met behulp van de value() functie en retourneert de waarde met het opgegeven gegevenstype.
  6. Voeg een komma toe na de bovengenoemde waarde.
  7. Houd er rekening mee dat deze waarden op afzonderlijke rijen worden geretourneerd. Het gebruik van de DISTINCT trefwoord verwijdert nu dubbele rijen (d.w.z. waarden).
  8. Gebruik de FOR XML PATH('') clausule om de waarden over meerdere rijen samen te voegen tot één rij.

Zoekopdracht

De bovenstaande benadering in vraagvorm zetten:

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('') 

Invoer en resultaat

Gezien de input:

De bovenstaande zoekopdracht geeft het resultaat:

Let op de afsluitende komma aan het einde. Ik laat het als een oefening aan jou over om dat te verwijderen.

BEWERK:Aantal duplicaten

OP gevraagd in een opmerking "hoe krijg ik ook het aantal duplicaten? in een aparte kolom ".

De eenvoudigste manier zou zijn om de bovenstaande query te gebruiken, maar de laatste regel te verwijderen FOR XML PATH('') . Vervolgens worden alle waarden en afzonderlijke waarden geteld die worden geretourneerd door de SELECT expressie in de bovenstaande query (d.w.z. PivotedTable.PivotedColumn.value('.','nvarchar(max)') ). Het verschil tussen het aantal van alle waarden en het aantal verschillende waarden is het aantal dubbele waarden.

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) 

Voor dezelfde invoer als hierboven is de uitvoer van deze vraag:

CountOfAllValues CountOfUniqueValues CountOfDuplicateValues
---------------- ------------------- ----------------------
8                4                   4


  1. MySql Error 150 - Buitenlandse sleutels

  2. Oracle Database Enforce CHECK op meerdere tabellen

  3. MySQL-toezegging en transactie

  4. MySQL - Maak een paar waarden uniek