2016-09-09 1 views
1

В следующем примереКак найти дубликат текста в столбце и удалить дубликаты в SQL сервере

address: AUNDH AUNDH CAMP 

Я хочу, чтобы удалить дубликаты, и результат должен быть

address: AUNDH CAMP 

Как выполнить это в sql-сервере?

+0

См [здесь] (http://stackoverflow.com/questions/18710797/sql-find-duplicate-values-and-remove-in-a-field). Я не вижу в этом легкого решения. –

+0

Это одна строка с тремя значениями в столбце или тремя разными строками? – jarlh

+0

Какая версия SQL-Server? – Shnugo

ответ

1

Создав ниже функции, и может achive,

Create FUNCTION dbo.RemoveDuplicate 
    (
    @StringList VARCHAR(MAX), 
    @Delim CHAR 
    ) 
    RETURNS 
    VARCHAR(MAX) 
    AS 
    BEGIN 
    DECLARE @ParsedList TABLE 
    (
    Item VARCHAR(MAX) 
    ) 
     DECLARE @list1 VARCHAR(MAX), @Pos INT, @rList VARCHAR(MAX) 
     SET @StringList = LTRIM(RTRIM(@StringList)) + @Delim 
     SET @pos = CHARINDEX(@delim, @StringList, 1) 
     WHILE @pos > 0 
     BEGIN 
     SET @list1 = LTRIM(RTRIM(LEFT(@StringList, @pos - 1))) 
     IF @list1 <> '' 
     INSERT INTO @ParsedList VALUES (CAST(@list1 AS VARCHAR(MAX))) 
     SET @StringList = SUBSTRING(@StringList, @pos+1, LEN(@StringList)) 
     SET @pos = CHARINDEX(@delim, @StringList, 1) 
     END 
     SELECT @rlist = COALESCE(@[email protected],'') + item 
     FROM (SELECT DISTINCT Item FROM @ParsedList) t 
     RETURN @rlist 
    END 
    GO 

И вы можете выбрать его

Declare @address varchar(300)='AUNDH AUNDH CAMP' 
SELECT dbo.RemoveDuplicate(@address,',') 
0

Если вы используете SQL Server> 2016, то вы можете использовать STRING_SPLIT

Разделите значение столбца по пробелу и выберите отдельное значение столбца, а затем объедините и создайте строку столбца результата.

0

Остерегайтесь такого рода обработки в производственных базах данных. Существует много причин думать (двойное всегда неправильно, как обрабатывать знаки препинания, слова разделены только пробелом). Тем не менее, вы можете использовать рекурсию, как в следующем фрагменте:

DECLARE @word varchar(MAX) = 'AUNDH AUNDH CAMP'; 

WITH Splitter AS 
(
    SELECT 1 N, LEFT(@word,CHARINDEX(' ',@word,1)-1) Word, SUBSTRING(@word, CHARINDEX(' ', @word, 0)+1, LEN(@word)) Rest 
    UNION ALL 
    SELECT N+1 N, 
      CASE WHEN CHARINDEX(' ', Rest, 0)>0 THEN LEFT(Rest, CHARINDEX(' ', Rest, 0)-1) ELSE Rest END, 
      CASE WHEN CHARINDEX(' ', Rest, 0)>0 THEN SUBSTRING(Rest, CHARINDEX(' ', Rest, 0)+1, LEN(Rest)) ELSE NULL END 
    FROM Splitter 
    WHERE LEN(Rest)>0 
), Numbered AS 
(
    SELECT N, Word, ROW_NUMBER() OVER (PARTITION BY Word ORDER BY N) RowNum 
    FROM Splitter 
) 
SELECT STUFF((SELECT ' '+Word 
       FROM Numbered 
       WHERE RowNum=1 
       ORDER BY N 
       FOR XML PATH('')), 1, 1, '') NoDuplicates 

Вы можете встроить это в функции, если вы хотите.

0

Использование Числа таблицы:

create table #test 
(
id varchar(max) 
) 

insert into #test 
select 'a a b' 
union all 
select 'c c d' 

;with cte 
as 
(select *,dense_rank() over (order by id) as rownum 
from 
#test t 
cross apply 
(select * from [dbo].[SplitStrings_Numbers](t.id,' '))b 
) 
,finalresult 
as 
(select 
    (
select ''+ item from cte c1 where c1.rownum=c2.rownum 
group by item 
for xml path('') 
)as finalvalue 
from cte c2 
) 
select finalvalue from finalresult 
group by finalvalue 
0

Это, по существу, та же идея, что и в @ TheGameiswar отвечают только немного короче, ненужные шаги исключены.

create table #test 
(
id varchar(max) 
) 

insert into #test 
select 'a a b' 
union all 
select 'c c d'; 

select *, 
    stuff((
    select ' '+ item 
    from [dbo].[DelimitedSplit8K](t.id,' ') 
    group by item 
    for xml path('') 
),1,1,'') as finalvalue 
from #test t 

DelimitedSplit8K быстрая строка сплиттер от http://www.sqlservercentral.com/articles/Tally+Table/72993/. Вы можете использовать любой другой под рукой.

0
DECLARE @source TABLE 
(
    [str] VARCHAR(MAX) 
) 

INSERT INTO @source 
SELECT 'address: AUNDH AUNDH CAMP' 
UNION ALL 
SELECT 'address: AUNDH CAMP AUNDH' 
UNION ALL 
SELECT 'address: BBB AUNDH address:' 
UNION ALL 
SELECT 'address: BBB AUNDH CAMP' 

DECLARE @tbl AS TABLE 
(
    num INT, 
    [str] VARCHAR(MAX) 
) 

DECLARE @result AS TABLE 
(
    num INT, 
    n  SMALLINT, 
    [str] VARCHAR(MAX) 
) 

INSERT INTO @tbl 
SELECT ROW_NUMBER() OVER (ORDER BY [str]), [str] 
FROM @source 

DECLARE 
    @i INT = 0, 
    @max_i INT = (SELECT MAX([num]) FROM @tbl), 
    @str VARCHAR(MAX), 
    @n SMALLINT 

WHILE(@i < @max_i) 
BEGIN 

    SET @str = (SELECT [str] FROM @tbl WHERE [num] = @i + 1) 

    SET @n = 1 

    WHILE(CHARINDEX(' ', @str) <> 0) 
    BEGIN 

    INSERT INTO @result 
    SELECT num, @n, SUBSTRING(@str, 1, CHARINDEX(' ', @str) - 1) FROM @tbl WHERE [num] = @i + 1 

    SET @str = SUBSTRING(@str, CHARINDEX(' ', @str) + 1, LEN(@str)) 

    SET @n += 1 

    END 

    INSERT INTO @result 
    SELECT num, @n, @str FROM @tbl WHERE [num] = @i + 1 

    SET @i += 1 
END 

-- result 
SELECT SUBSTRING([str], 2, LEN([str])) AS [str] 
FROM (
     SELECT DISTINCT r_big.num, 
       (
        SELECT ' ' + [str] AS [text()] 
        FROM @result r_small 
        WHERE r_small.num = r_big.num 
        GROUP BY r_small.num, r_small.[str] 
        ORDER BY num, min(n) 
        FOR XML PATH('') 
       ) AS [str] 
     FROM @result r_big 
     )x 
Смежные вопросы