Přístup
Následující přístup lze použít k deduplikaci odděleného seznamu hodnot.
- Použijte
REPLACE()
funkce pro převod různých oddělovačů na stejný oddělovač. - Použijte
REPLACE()
funkce pro vložení uzavíracích a otevíracích značek XML k vytvoření fragmentu XML - Použijte
CAST(expr AS XML)
funkce pro převod výše uvedeného fragmentu na datový typ XML - Použijte
OUTER APPLY
pro použití tabulkové funkcenodes()
rozdělit fragment XML do jeho základních značek XML. To vrátí každou značku XML na samostatném řádku. - Extrahujte pouze hodnotu ze značky XML pomocí
value()
a vrátí hodnotu pomocí zadaného datového typu. - Za výše uvedenou hodnotu připojte čárku.
- 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). - 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