none
Exclusão de registros repetidos e manter o mais atual RRS feed

  • Pergunta

  • Olá pessoal, tudo bem?

    Estou iniciando meus estudos com SQL e me deparei com a seguinte situação. 

    Nessa tabela existe vários registros repetidos, ao dar o SELECT total na tabela ela me retorna 15044 registros, e distintos da coluna 'studyId' só possuem 9569.

    Que tipo de procedimento eu devo realizar para excluir os registros repetidos e manter somente os mais atuais?

    Agradeço a atenção!

    terça-feira, 5 de setembro de 2017 22:03

Respostas

  • Hudson,

    Não havia percebido que estava faltando o From. Segue a query:

    with CTE_RN as
    (
        select
            *,
            ROW_NUMBER() OVER(PARTITION BY studyId, studyDate ORDER BY stuKey DESC) as RN
        from  [meddb].[dbo].[tblStudies]
    )
    
    select * from CTE_RN 
    where RN = 1

    E o Delete:

    with CTE_RN as
    (
        select
            *,
            ROW_NUMBER() OVER(PARTITION BY studyId, studyDate ORDER BY stuKey DESC) as RN
        from  [meddb].[dbo].[tblStudies]
    )
    
    delete from CTE_RN 
    where RN > 1

    Espero que ajude


    Assinatura: http://www.imoveisemexposicao.com.br

    quarta-feira, 6 de setembro de 2017 16:57

Todas as Respostas

  • Boa noite,

    Hudson, você quer que a query retorne apenas os registros mais recentes? Ou deseja realmente excluir os demais registros?

    Se for o primeiro caso experimente utilizar uma CTE com uma função de ranqueamento. Ex:

    with CTE_RN as
    (
        select
            *,
            ROW_NUMBER() OVER(PARTITION BY studyId ORDER BY stuKey DESC) as RN
    )
    
    select * from CTE_RN 
    where RN = 1

    Espero que ajude


    Assinatura: http://www.imoveisemexposicao.com.br

    terça-feira, 5 de setembro de 2017 23:46
  • Que tipo de banco de dados e esse ? e uma base relacional ou Data Mart (DW) ?? 

    se for um DW , vc precisa realmente saber se é necessário rodar um delete ,pois está tabela pode ser uma  Slowly changing dimension

    descartada essa possibilidade vc tem que saber qual registros vai ficar ou seja  

    estudyid = 19 existem dois, mas qual dos dois fica ??

    posta por favor o seguinte resultado 

    SELECT S.* FROM dbo.tblStudies S
    WHERE S.studyId= 19

    Wesley Neves - Brasilia-DF

     
    wesley.si.neves@gmail.com
    MTA-SQL Server
    MTA- Web Development
    Analista Desenvolvedor.NET
    Pós-Graduando em Banco de Dados 
    "Se a resposta for útil ou ajudar ,não esqueça de marcar"





    Wesley Neves

    quarta-feira, 6 de setembro de 2017 11:31
  • Olá gapimex.

    Na verdade queria realizar uma consulta dos IDs que estão repetidos na coluna 'studyKey' e manter apenas um registro do ID em questão. 

    Dei uma enxugada na query para te exemplificar melhor:

    SELECT [stuKey]
          ,[studyInstanceUID]
          ,[accessionNumber]
          ,[studyId]
          ,[studyDescription]
          ,[studyDate]
      FROM [meddb].[dbo].[tblStudies] where studyId = 23

    Os IDs 6 e 7 da coluna stuKey estão repetidos em relação à studyId, são esses que estou pretendendo eliminar, só deixar o 23 e o 10279


    • Editado Hudson Lima quarta-feira, 6 de setembro de 2017 12:51
    quarta-feira, 6 de setembro de 2017 12:48
  • Olá Wesley!

    Essa base é relacional, enxuguei a query para você poder entender o fato.

    SELECT [stuKey]
          ,[studyInstanceUID]
          ,[accessionNumber]
          ,[studyId]
          ,[studyDescription]
          ,[studyDate]
      FROM [meddb].[dbo].[tblStudies] where studyId = 23

    Como pode ver, os IDs 6 e 7 da coluna stuKey estão repetidos em relação à studyId, são esses que estou pretendendo eliminar, só deixar o 23 e o 10279.

    quarta-feira, 6 de setembro de 2017 12:50
  • Bom dia,

    Faça um teste em um ambiente de teste com esse script de delete

    delete from [meddb].[dbo].[tblStudies] 
    where [stuKey] not in (
    SELECT max([stuKey])
     FROM [meddb].[dbo].[tblStudies] 
    group by [studyId], [studyDate])

    se quiser verificar roda só o para você ver o que vai ficar:

    SELECT max([stuKey])
     FROM [meddb].[dbo].[tblStudies] 
    group by [studyId], [studyDate]

    quarta-feira, 6 de setembro de 2017 13:01
  • Hudson, experimente fazer uns testes dessa forma:

    with CTE_RN as
    (
        select
            *,
            ROW_NUMBER() OVER(PARTITION BY studyId, studyDate ORDER BY stuKey DESC) as RN
    )
    
    select * from CTE_RN 
    where RN = 1

    Espero que ajude


    Assinatura: http://www.imoveisemexposicao.com.br

    quarta-feira, 6 de setembro de 2017 13:21
  • Como pode ver, os IDs 6 e 7 da coluna stuKey estão repetidos em relação à studyId, são esses que estou pretendendo eliminar, só deixar o 23 e o 10279.

    por que  o 6 e 7 vão ser deletados e o 23 não ??

    vc deixando o 23 e o 10279 , ainda  ficará com dados repetidos   certo ??

    qual é a logica de deixar  23 e o 10279 ??

    Wesley Neves - Brasilia-DF

     
    wesley.si.neves@gmail.com
    MTA-SQL Server
    MTA- Web Development
    Analista Desenvolvedor.NET
    Pós-Graduando em Banco de Dados 
    "Se a resposta for útil ou ajudar ,não esqueça de marcar"





    Wesley Neves

    quarta-feira, 6 de setembro de 2017 13:46
  • Como pode ver, os IDs 6 e 7 da coluna stuKey estão repetidos em relação à studyId, são esses que estou pretendendo eliminar, só deixar o 23 e o 10279.

    por que  o 6 e 7 vão ser deletados e o 23 não ??

    vc deixando o 23 e o 10279 , ainda  ficará com dados repetidos   certo ??

    qual é a logica de deixar  23 e o 10279 ??

    Wesley Neves - Brasilia-DF

     
    wesley.si.neves@gmail.com
    MTA-SQL Server
    MTA- Web Development
    Analista Desenvolvedor.NET
    Pós-Graduando em Banco de Dados 
    "Se a resposta for útil ou ajudar ,não esqueça de marcar"





    Wesley Neves

    Pelo que entendi olhando o exemplo do nosso amigo, é que as datas são diferentes.

    [studyDate]

    quarta-feira, 6 de setembro de 2017 13:55
  • Entretando  stuKey 23,7,6 possuem a mesma data  
    [studyDate]

    Wesley Neves

    quarta-feira, 6 de setembro de 2017 14:28
  • Por isso que ele quer deixar o StuKey o maior possível
    quarta-feira, 6 de setembro de 2017 14:29
  • É por conta da data de criação, na coluna 'studyDate' tem um datetime. Os IDs 6,7 e 23 estão com a mesma data de criação, por isso que eu pretendo só manter o ID 23, já o 10279 é distinto entre os demais.
    quarta-feira, 6 de setembro de 2017 14:39
  • Hudson, 

    Verifique esse script 

    delete from [meddb].[dbo].[tblStudies] 
    where [stuKey] not in (
    SELECT max([stuKey])
     FROM [meddb].[dbo].[tblStudies] 
    group by [studyId], [studyDate])

    se quiser verificar roda só o para você ver o que vai ficar:

    SELECT max([stuKey])
     FROM [meddb].[dbo].[tblStudies] 
    group by [studyId], [studyDate]

    quarta-feira, 6 de setembro de 2017 14:42
  • No sentido de deixar o maior possível veja o exemplo abaixo 

    DECLARE @RegistrosADeletar TABLE
        (
          stuKey INT ,
          stuId INT ,
          StudentDate DATETIME
        );
    
    DECLARE @RegistrosDaTabela TABLE
        (
          stuKey INT ,
          stuId INT ,
          StudentDate DATETIME
        );
    
    DECLARE @date DATETIME  = DATEFROMPARTS(2013, 08, 13);
    INSERT  INTO @RegistrosDaTabela
            ( stuKey, stuId, StudentDate )
    VALUES  ( 6, 23, @date ),
            ( 7, 23, @date ),
            ( 23, 23, @date )	,
            ( 10279, 23, '2016-08-15' );	
    
    
    ;
    WITH    Dados
              AS ( SELECT   T.stuKey ,
                            T.stuId ,
                            T.StudentDate ,
                            Ordem = ROW_NUMBER() OVER ( PARTITION BY T.stuId ORDER BY T.stuKey DESC )
                   FROM     @RegistrosDaTabela AS T
                 )
        INSERT  INTO @RegistrosADeletar
                SELECT  R.stuKey ,
                        R.stuId ,
                        R.StudentDate
                FROM    Dados R
                WHERE   R.Ordem > 2;
    
    SELECT  RAD.stuKey ,
            RAD.stuId ,
            RAD.StudentDate
    FROM    @RegistrosADeletar AS RAD;

    Wesley Neves - Brasilia-DF

     
    wesley.si.neves@gmail.com
    MTA-SQL Server
    MTA- Web Development
    Analista Desenvolvedor.NET
    Pós-Graduando em Banco de Dados 
    "Se a resposta for útil ou ajudar ,não esqueça de marcar"





    Wesley Neves

    quarta-feira, 6 de setembro de 2017 15:24
  • Hudson, se a query que sugeri anteriormente retornar as linhas que devem ser mantidas você pode experimentar o comando abaixo para excluir as demais:

    with CTE_RN as
    (
        select
            *,
            ROW_NUMBER() OVER(PARTITION BY studyId, studyDate ORDER BY stuKey DESC) as RN
    )
    
    delete from CTE_RN 
    where RN > 1

    Espero que ajude


    Assinatura: http://www.imoveisemexposicao.com.br

    quarta-feira, 6 de setembro de 2017 15:36
  • Oi gapimex.

    A query retornou o seguinte erro:

    Msg 263, Level 16, State 1, Line 4
    Must specify table to select from.
    Msg 207, Level 16, State 1, Line 8
    Invalid column name 'studyId'.
    Msg 207, Level 16, State 1, Line 8
    Invalid column name 'studyDate'.
    Msg 207, Level 16, State 1, Line 8
    Invalid column name 'stuKey'.
    Msg 8155, Level 16, State 2, Line 4
    No column name was specified for column 1 of 'CTE_RN'.

    quarta-feira, 6 de setembro de 2017 16:35
  • Hudson,

    Não havia percebido que estava faltando o From. Segue a query:

    with CTE_RN as
    (
        select
            *,
            ROW_NUMBER() OVER(PARTITION BY studyId, studyDate ORDER BY stuKey DESC) as RN
        from  [meddb].[dbo].[tblStudies]
    )
    
    select * from CTE_RN 
    where RN = 1

    E o Delete:

    with CTE_RN as
    (
        select
            *,
            ROW_NUMBER() OVER(PARTITION BY studyId, studyDate ORDER BY stuKey DESC) as RN
        from  [meddb].[dbo].[tblStudies]
    )
    
    delete from CTE_RN 
    where RN > 1

    Espero que ajude


    Assinatura: http://www.imoveisemexposicao.com.br

    quarta-feira, 6 de setembro de 2017 16:57
  • Boa tarde,

    Por falta de retorno essa thread está sendo encerrada

    Se necessário, favor abrir uma nova thread.

    Atenciosamente,


    Filipe B de Castro

    Esse conteúdo é fornecido sem garantias de qualquer tipo, seja expressa ou implícita

    MSDN Community Support

    Por favor, lembre-se de Marcar como Resposta as postagens que resolveram o seu problema. Essa é uma maneira comum de reconhecer aqueles que o ajudaram e fazer com que seja mais fácil para os outros visitantes encontrarem a resolução mais tarde.

    segunda-feira, 11 de setembro de 2017 16:42
    Moderador