Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

премахване на дубликати от запетая или низ на оператор на конвейер

Подход

Следният подход може да се използва за премахване на дублиране на ограничен списък от стойности.

  1. Използвайте REPLACE() функция за преобразуване на различни разделители в един и същ разделител.
  2. Използвайте REPLACE() функция за инжектиране на XML затварящи и отварящи тагове за създаване на XML фрагмент
  3. Използвайте CAST(expr AS XML) функция за преобразуване на горния фрагмент в XML тип данни
  4. Използвайте OUTER APPLY за да приложите функцията с таблични стойности nodes() за да разделите XML фрагмента на съставните му XML тагове. Това връща всеки XML таг на отделен ред.
  5. Извлечете само стойността от XML тага с помощта на value() функция и връща стойността, използвайки посочения тип данни.
  6. Добавете запетая след горепосочената стойност.
  7. Имайте предвид, че тези стойности се връщат на отделни редове. Използването на DISTINCT ключовата дума вече премахва дублиращи се редове (т.е. стойности).
  8. Използвайте FOR XML PATH('') клауза за свързване на стойностите в множество редове в един ред.

Запитване

Поставяне на горния подход във формуляр за заявка:

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

Вход и резултат

Предвид входа:

Горната заявка ще върне резултата:

Обърнете внимание на запетаята в края. Ще ви оставя като упражнение да премахнете това.

РЕДАКТИРАНЕ:Брой дубликати

OP поиска в коментар „как да получа и броя на дубликатите? в отделна колона ".

Най-лесният начин би бил да използвате горната заявка, но да премахнете последния ред FOR XML PATH('') . След това преброяване на всички стойности и различни стойности, върнати от SELECT израз в горната заявка (т.е. PivotedTable.PivotedColumn.value('.','nvarchar(max)') ). Разликата между броя на всички стойности и броя на отделните стойности е броят на дублиращите се стойности.

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) 

За същия вход, показан по-горе, резултатът от тази заявка е:

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. TSQL Комбиниране на множество редове в един ред

  2. Избор на първи ред за група

  3. Избягвайте NULL колони, като използвате DEFAULT Empty String

  4. Как да проверите дължината на низа и след това да изберете подниз в Sql Server

  5. CONVERT() от дата/час към примери за низове в SQL Server