none
Exclusão de registros duplicados RRS feed

  • Pergunta

  • Boa Tarde amigos!!!

     

    gostaria de saber uma maneira eficiente de se excluir registros duplicados em uma tabela, ou seja, se existe um registro duplicado duas vezes ou seja, dois registros com o mesmo ID por exemplo, excluir apenas um deles. como posso fazer isso de forma eficiente?

     

    Muito Obrigado

    quinta-feira, 27 de março de 2008 19:50

Todas as Respostas

  • Boa Noite,

     

    Você pode copiar os registros para uma tabela de forma distinta, excluir os registros da tabela principal e posteriormente repopulá-la. Ex:

     

    Code Snippet

    CREATE TABLE #tbl (CODIGO INT, NOME VARCHAR(200))

    INSERT INTO #tbl VALUES (1, 'Cliente 1')

    INSERT INTO #tbl VALUES (1, 'Cliente 1')

    INSERT INTO #tbl VALUES (2, 'Cliente 2')

    INSERT INTO #tbl VALUES (2, 'Cliente 2')

    INSERT INTO #tbl VALUES (2, 'Cliente 2')

     

    SELECT DISTINCT CODIGO, NOME INTO #tbl2 FROM #tbl

     

    DELETE FROM #tbl

     

    INSERT INTO #tbl SELECT CODIGO, NOME FROM #tbl2

     

    DROP TABLE #tbl2

     

    SELECT CODIGO, NOME FROM #tbl

     

    DROP TABLE #tbl

     

     

    Essa é uma técnica simples, mas em algumas situações infactível (nem sempre é possível excluir todos os registros da

    tabela). Outra sugestão é:

     

    Code Snippet

    CREATE TABLE #tbl (CODIGO INT, NOME VARCHAR(200))

    INSERT INTO #tbl VALUES (1, 'Cliente 1')

    INSERT INTO #tbl VALUES (1, 'Cliente 1')

    INSERT INTO #tbl VALUES (2, 'Cliente 2')

    INSERT INTO #tbl VALUES (2, 'Cliente 2')

    INSERT INTO #tbl VALUES (2, 'Cliente 2')

     

    ALTER TABLE #tbl ADD CriterioDesempate INT IDENTITY(1,1)

     

    SELECT * FROM #tbl

     

    SELECT CODIGO, NOME, MIN(CriterioDesempate) AS DESEMPATE

    FROM #tbl

    GROUP BY CODIGO, NOME

     

    DELETE FROM #tbl

    WHERE

    NOT EXISTS (

    SELECT CODIGO, NOME, DESEMPATE FROM

    (

    SELECT CODIGO, NOME, MIN(CriterioDesempate) AS DESEMPATE

    FROM #tbl

    GROUP BY CODIGO, NOME) AS SUBQ

    WHERE #tbl.CODIGO = SUBQ.CODIGO AND #tbl.CriterioDesempate = SUBQ.DESEMPATE)

     

    SELECT * FROM #tbl

     

    ALTER TABLE #tbl DROP COLUMN CriterioDesempate

     

    SELECT * FROM #tbl

     

    DROP TABLE #tbl

     

     

    Observe que nessa solução, eu adicionei um critério de desempate (os que os teóricos chamam de Tiebreaker). Isso foi necessário para decidir que linha deveria ficar na tabela. Normalmente você não precisará criar esse tipo de critério, pois, provavelmente uma coluna na tabela deverá servir como critério de desempate (tiebreaker). Afinal se duas linhas são exatamente iguais há algo errado.

     

    [ ]s,

     

    Gustavo

    quinta-feira, 27 de março de 2008 22:36
  • Olá Bruno,

     

    Uma outra alternativa é vc utilizar o scripts baixo. Neste exemplo, "unico" é a coluna da sua tabela cujo valor deve ser único.

     

    */ Este script permite localizar e excluir registros duplicados em uma tabela*/

     

    -- Passo1: Verifica os registros duplicados
    select unico,count(*)as vezes from TTT group by unico having count(unico)>1

     

    --Passo 2: Pega o id máximo para cada registro duplicado
    select max(id)as idmaximo,unico from TTT group by unico having count(unico)>1

     

    --Passo 3: Exclui os registros duplicadfos
    DELETE FROM
     p1
    --SELECT *
    FROM
     TTT  p1
    INNER JOIN
     (
      SELECT
       max(id)as id,unico
      FROM
       TTT
      GROUP BY
       unico
      HAVING
       COUNT(*) > 1
     ) p2
     ON(p1.unico = p2.unico
     AND p1.id <> p2.id)

     

    um abraço

    Nilton Pinheiro

    www.mcdbabrasil.com.br

     


     

     

    sábado, 29 de março de 2008 01:09
  • Nilton, não conseguir rodar o passo 3 para exclusão dos registros.

    Dá uma erro na linha:

    ERRO:  erro de sintaxe em ou próximo a "FROM"
    LINE 4: FROM

     

    Alguma sugestão?

    segunda-feira, 26 de setembro de 2011 16:54
  • vinicius

    testa com CTE e Rown_number (sql 2005 ou superior)

    Declare @tbTEste as table (id int, nome varchar(20))
    insert into @tbTEste values (1,'C3Po')
    insert into @tbTEste values (2,'R2D2')
    insert into @tbTEste values (3,'YODA')
    insert into @tbTEste values (4,'YODA')
    
    ;with cte_teste
    as
    (
    select *, ROW_NUMBER() over (partition by nome order by nome) numerador from @tbTEste
    )
    delete from cte_teste where numerador >1
    
    select * from @tbTEste
    



    Att.
    Marcelo Fernandes

    MCP, MCDBA, MCSA, MCTS.
    Se útil, classifique!!!
    Me siga no twitter: @marcelodba

    segunda-feira, 26 de setembro de 2011 17:34