sql >> Databáze >  >> RDS >> Sqlserver

odstranit duplikáty z řetězce operátora čárky nebo potrubí

Přístup

Následující přístup lze použít k deduplikaci odděleného seznamu hodnot.

  1. Použijte REPLACE() funkce pro převod různých oddělovačů na stejný oddělovač.
  2. Použijte REPLACE() funkce pro vložení uzavíracích a otevíracích značek XML k vytvoření fragmentu XML
  3. Použijte CAST(expr AS XML) funkce pro převod výše uvedeného fragmentu na datový typ XML
  4. Použijte OUTER APPLY pro použití tabulkové funkce nodes() rozdělit fragment XML do jeho základních značek XML. To vrátí každou značku XML na samostatném řádku.
  5. Extrahujte pouze hodnotu ze značky XML pomocí value() a vrátí hodnotu pomocí zadaného datového typu.
  6. Za výše uvedenou hodnotu připojte čárku.
  7. Upozorňujeme, že tyto hodnoty jsou vráceny na samostatných řádcích. Použití DISTINCT klíčové slovo nyní odstraňuje duplicitní řádky (tj. hodnoty).
  8. Použijte FOR XML PATH('') klauzule ke zřetězení hodnot napříč více řádky do jednoho řádku.

Dotaz

Uvedení výše uvedeného přístupu do formuláře dotazu:

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

Vstup a výsledek

Vzhledem k zadání:

Výše uvedený dotaz vrátí výsledek:

Všimněte si koncové čárky na konci. Nechám to jako cvičení na vás, abyste to odstranili.

UPRAVIT:Počet duplikátů

OP požadováno v komentáři „jak dostanu také počet duplikátů? v samostatném sloupci ".

."

Nejjednodušším způsobem by bylo použít výše uvedený dotaz, ale odstranit poslední řádek FOR XML PATH('') . Poté se spočítají všechny hodnoty a odlišné hodnoty vrácené SELECT výraz ve výše uvedeném dotazu (tj. PivotedTable.PivotedColumn.value('.','nvarchar(max)') ). Rozdíl mezi počtem všech hodnot a počtem různých hodnot je počet duplicitních hodnot.

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) 

Pro stejný vstup uvedený výše je výstupem tohoto dotazu:

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


  1. Jak optimalizovat velký dotaz s opakovanými poddotazy

  2. Jak mohu omezit uživatele MySQL na konkrétní tabulky

  3. Vytvoření nové databáze ze zálohy jiné databáze na stejném serveru?

  4. PostgreSQL:Vytvořte tabulku, pokud neexistuje AS