none
Apagar registros repetidos RRS feed

  • Pergunta

  • pessoal, eu tenho uma query que serve para apagar registros duplicados em minha tabela. ele faz da seguinte forma:

    digamos que eu tenha a tabela TABLE, com COD1 e COD2, desta forma:

    TABLE
    ______________
    COD1     COD2
    1             2
    1             3
    1             2
    2             1

    bom o script serve para ver se na tabela existem registros com os dois campos repetidos, no caso ele apagaria o seguinte regsitro: COD1 - 1  e  COD2 - 2, que se repetem duas vezes na tabela. entenderam? bom a minha query é assim:

    WITH T1 AS (
    SELECT ROW_NUMBER ( ) OVER (PARTITION BY TABLE.COD1, TABLE.COD2 ORDER BY TABLE.COD1) AS RNUM FROM TABLE
    ) DELETE FROM T1 WHERE RNUM > 1

    funciona beleza, mas agora preciso adaptar isso para o SQL 2000, já que não dá pra usar o ROW_NUMBER( ).

    alguém tem alguma idéia de como fazer?

    agradeço desde já...
    terça-feira, 13 de janeiro de 2009 16:09

Respostas

  • pessoal, eu fiquei remoendo esse problema agora e fiz um cursor pra resolver o problema...

    Declare @COD1 int, @COD2 int, @QTD numeric, @SQL varchar(1000)
    Declare Cur Cursor For Select COD1, COD2, Count(*) - 1 As QTD From TABLE Group By COD1, COD2 Having Count(*) > 1
    Open Cur
    Fetch Next From Cur Into @COD1, @COD2, @QTD
    While @@Fetch_Status = 0
    Begin
    Set @SQL = 'Delete Top (' + Cast(@QTD As varchar(10)) + ') From TABLE Where COD1 = ' + Cast(@COD1 As varchar(10)) + ' And COD2 = ' + Cast(@COD2 As varchar(10))
    Exec (@SQL)
    Fetch Next From Cur Into @COD1, @COD2, @QTD
    End
    Close Cur
    Deallocate Cur

    se alguém tiver uma solução melhor, por favor... obrigado...
    terça-feira, 13 de janeiro de 2009 17:41
  • Anderson,

     

    Cuidado em relação a permissão para utilizá-las vai depender da maneira que você deseja aplicar este tipo de funcionalidade, lógicamente uma variável do tipo table estará ocupando o espaço de memória do seu SQL Server, como também estará consumindo recursos do seu TempDB.

     

    É um tipo de dados especial que pode ser usado para armazenar um conjunto de resultados para processamento posterior. table é utilizado principalmente para o armazenamento temporário de um conjunto de linhas retornadas como o conjunto de resultados de uma função com valor de tabela.

     

    As consultas que modificam variáveis table não geram planos de execução de consulta paralelos. O desempenho pode ser afetado quando variáveis table muito grandes ou variáveis table em consultas complexas, forem modificadas. Nessas situações, considere o uso de tabelas temporárias em seu lugar.

    terça-feira, 13 de janeiro de 2009 19:01
  • Olá Anderson,

     

    Não há nenhum impeditivo para declarar variáveis do tipo table. Assim como as tabelas temporárias, qualquer usuário poderá criá-las. É exatamente como criar uma variável normal.

     

    [ ]s,

     

    Gustavo Maia Aguiar

    http://gustavomaiaaguiar.spaces.live.com

     

    terça-feira, 13 de janeiro de 2009 19:04

Todas as Respostas

  • pessoal, eu fiquei remoendo esse problema agora e fiz um cursor pra resolver o problema...

    Declare @COD1 int, @COD2 int, @QTD numeric, @SQL varchar(1000)
    Declare Cur Cursor For Select COD1, COD2, Count(*) - 1 As QTD From TABLE Group By COD1, COD2 Having Count(*) > 1
    Open Cur
    Fetch Next From Cur Into @COD1, @COD2, @QTD
    While @@Fetch_Status = 0
    Begin
    Set @SQL = 'Delete Top (' + Cast(@QTD As varchar(10)) + ') From TABLE Where COD1 = ' + Cast(@COD1 As varchar(10)) + ' And COD2 = ' + Cast(@COD2 As varchar(10))
    Exec (@SQL)
    Fetch Next From Cur Into @COD1, @COD2, @QTD
    End
    Close Cur
    Deallocate Cur

    se alguém tiver uma solução melhor, por favor... obrigado...
    terça-feira, 13 de janeiro de 2009 17:41
  • Boa Tarde,

     

    Se houver alguma outra coluna é possível fazer via um único comando de DELETE.

    Senão houver outra possibilidade é utilizar uma tabela temporária. Ex:

    Code Snippet

     

    declare @t table (cod1 int, cod2 int)

    insert into @t values (1,2)

    insert into @t values (1,3)

    insert into @t values (1,2)

    insert into @t values (2,1)

     

    -- Insere os registros duplicados distintamente em outro local

    select cod1, cod2 into #t from @t

    group by cod1, cod2

    having count(*) > 1

     

    -- Delete os registros duplicados (todos)

    delete from @t

    from @t as t

    inner join (

    select cod1, cod2 from @t

    group by cod1, cod2

    having count(*) > 1) as q

    on t.cod1 = q.cod1 and t.cod2 = q.cod2

     

    -- Reinsere os registros distintamente

    insert into @t (cod1, cod2)

    select cod1, cod2

    from #t

    select * from @t

     

    drop table #t

     

    [ ]s,

     

    Gustavo Maia Aguiar

    http://gustavomaiaaguiar.spaces.live.com

     

    terça-feira, 13 de janeiro de 2009 18:16
  • baseado na tua idéia, fiz da seguinte forma:

    Declare @TABELA table(COD1 int, COD2 int)
    Insert Into @TABELA(COD1, COD2) Select COD1, COD2 From TABLE Group By COD1, COD2
    Delete From TABLE
    Insert Into TABLE(COD1, COD2) Select COD1, COD2 From @TABELA
    GO

    funciona também
    terça-feira, 13 de janeiro de 2009 18:39
  • Gustavo, aproveitando, essas variáveis table, existe algum cuidado que devo ter em relação à permissões para usá-las? é como criar uma variável normal?
    terça-feira, 13 de janeiro de 2009 18:45
  • Anderson,

     

    Cuidado em relação a permissão para utilizá-las vai depender da maneira que você deseja aplicar este tipo de funcionalidade, lógicamente uma variável do tipo table estará ocupando o espaço de memória do seu SQL Server, como também estará consumindo recursos do seu TempDB.

     

    É um tipo de dados especial que pode ser usado para armazenar um conjunto de resultados para processamento posterior. table é utilizado principalmente para o armazenamento temporário de um conjunto de linhas retornadas como o conjunto de resultados de uma função com valor de tabela.

     

    As consultas que modificam variáveis table não geram planos de execução de consulta paralelos. O desempenho pode ser afetado quando variáveis table muito grandes ou variáveis table em consultas complexas, forem modificadas. Nessas situações, considere o uso de tabelas temporárias em seu lugar.

    terça-feira, 13 de janeiro de 2009 19:01
  • Olá Anderson,

     

    Não há nenhum impeditivo para declarar variáveis do tipo table. Assim como as tabelas temporárias, qualquer usuário poderá criá-las. É exatamente como criar uma variável normal.

     

    [ ]s,

     

    Gustavo Maia Aguiar

    http://gustavomaiaaguiar.spaces.live.com

     

    terça-feira, 13 de janeiro de 2009 19:04
  • Anderson,

     

    Obrigado pelo retorno.

     

    terça-feira, 13 de janeiro de 2009 19:12