Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

usuń duplikaty z przecinka lub ciągu operatora potoku

Podejście

Poniższe podejście może służyć do deduplikacji rozdzielonej listy wartości.

  1. Użyj REPLACE() funkcja konwertowania różnych ograniczników w ten sam ogranicznik.
  2. Użyj REPLACE() funkcja do wstrzykiwania znaczników zamykających i otwierających XML w celu utworzenia fragmentu XML
  3. Użyj CAST(expr AS XML) funkcja do konwersji powyższego fragmentu na typ danych XML
  4. Użyj OUTER APPLY zastosować funkcję wartości w tabeli nodes() aby podzielić fragment XML na jego składowe znaczniki XML. Zwraca każdy tag XML w osobnym wierszu.
  5. Wyodrębnij tylko wartość ze znacznika XML za pomocą value() funkcji i zwraca wartość przy użyciu określonego typu danych.
  6. Dołącz przecinek po wyżej wymienionej wartości.
  7. Pamiętaj, że te wartości są zwracane w osobnych wierszach. Użycie DISTINCT słowo kluczowe usuwa teraz zduplikowane wiersze (tj. wartości).
  8. Użyj FOR XML PATH('') klauzula, aby połączyć wartości z wielu wierszy w jeden wiersz.

Zapytanie

Umieszczenie powyższego podejścia w formularzu zapytania:

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

Wkład i wynik

Biorąc pod uwagę dane wejściowe:

Powyższe zapytanie zwróci wynik:

Zwróć uwagę na końcowy przecinek na końcu. Zostawię to jako ćwiczenie, aby to usunąć.

EDYCJA:liczba duplikatów

OP poprosił w komentarzu „Jak uzyskać również liczbę duplikatów? w osobnej kolumnie

Najprostszym sposobem byłoby użycie powyższego zapytania, ale usunięcie ostatniej linii FOR XML PATH('') . Następnie zliczanie wszystkich wartości i odrębnych wartości zwracanych przez SELECT wyrażenie w powyższym zapytaniu (np. PivotedTable.PivotedColumn.value('.','nvarchar(max)') ). Różnica między liczbą wszystkich wartości a liczbą odrębnych wartości to liczba zduplikowanych wartości.

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) 

Dla tych samych danych wejściowych pokazanych powyżej dane wyjściowe tego zapytania to:

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


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Tworzenie tabeli SQL Server z C# datatable

  2. Czy lepiej wykonywać wiele poleceń sql przy jednym połączeniu, czy łączyć się ponownie za każdym razem?

  3. Scalanie danych z 2 tabel

  4. Z SPRAWDŹ OGRANICZENIE, a następnie SPRAWDŹ OGRANICZENIE vs. DODAJ OGRANICZENIE

  5. Wykonaj sp_msforeachdb w aplikacji Java