none
Comparações RRS feed

  • Pergunta

  • Boa tarde,

      Galera, poderiam me ajudar a resolver um problema que já me acompanha a algum tempo?

      Tenho duas tabelas com campos de valores. Uma das tabelas possui valores positivos e a outra negativos.

       Em alguns casos, a tabela que possui valores positivos, possui mais registros com mesmo valor da tabela de valores negativos.

       A minha dúvida é como faço para que o sistema exclua a mesma quantidade de registros na tabela de valores negativos na de positivo.

    Ex:

    tabela A(valores positivos)

    ID      Valor

    1        12,30

    2       12,30

    3       14,00

    tabela B(valores negativos)

    id   valor1

    1   -0,90

    2   -34,00

    3   -12,30

    Reparem que acima só poderei excluir um valor na tabela A, (12,30)

    Sei que posso usar o ABS para transformar os valores negativos em positivos,  mas como excluir a mesma quantidade nas duas tabelas?

    Desde já agradeço.

    terça-feira, 7 de maio de 2013 18:46

Respostas

  • Bom dia,

    Experimente fazer um teste com o script abaixo:

    declare @TabelaA table
    (Valor money);
    
    insert into @TabelaA values 
    (12), (13), (12), (14);
    
    declare @TabelaB table
    (Valor money);
    
    insert into @TabelaB values 
    (-12), (-14);
    
    with
        CTE_N as
        (
            select Valor, COUNT(*) as Qtd
            from @TabelaB
            group by Valor
        ),
        
        CTE_P as
        (
            select Valor, ROW_NUMBER() OVER(PARTITION BY Valor ORDER BY Valor) as RowNum
            from @TabelaA
        ),
        
        CTE_D as
        (
            select p.*
            from CTE_P as p
            where p.RowNum <= (select n.Qtd from CTE_N as n where ABS(n.Valor) = p.Valor)
        )
        
        
    delete from CTE_D
    
    select * from @TabelaA

    Espero que ajude.


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

    • Marcado como Resposta jmarqDeveloper quarta-feira, 8 de maio de 2013 18:06
    quarta-feira, 8 de maio de 2013 14:36

Todas as Respostas

  • JmarqDeveloper,

    O que você poderia fazer é utilizar um Delete from em conjunto com um Join, veja se este exemplo abaixo ajuda:

    Create Table Positivos
     (Id Int,
      Valor Float)
    
    Create Table Negativos
     (Id Int,
      Valor Float)
          
    Insert Into Positivos Values(1, 12.30),(2,12.30),(3,14.00)
    
    Insert Into Negativos Values(1,-0.90),(2,-34.00),(3,-12.30)
    
    Delete from Positivos
    from Positivos P Inner Join Negativos N
                                                 On P.Valor = Abs(N.Valor)


    Pedro Antonio Galvão Junior [MVP | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados | SorBR.Net | Professor Universitário | MSIT.com]

    terça-feira, 7 de maio de 2013 19:08
  • Não deu certo. O uso do inner join fez com que apagasse todos os valores 12,30 positivos; só que deve sobrar um. Mesmo assim agradeço e aguardo mais sugestões.

    Obrigado

    terça-feira, 7 de maio de 2013 19:25
  • Bom não entendi 100% da sua dúvida mas , se for algo como excluir um valor uma unica vez mesmo que esse valor seja repetido várias vezes poderia fazer isso :

    DECLARE @TBL AS TABLE (ID INT NOT NULL IDENTITY(1,1) , VALOR DECIMAL(10,2))
    
    INSERT INTO @TBL(VALOR) VALUES(50.50),(50.50),(50.50),(30.10),(30.50)
    
    
    DELETE FROM  @TBL 
    
    WHERE ID = ( 
    SELECT MIN(ID) FROM @TBL
    		 WHERE VALOR IN
    				(
    				 SELECT VALOR FROM @TBL
    				 GROUP BY VALOR HAVING COUNT(VALOR) > 1
    				 )
     
     )
     
    
    SELECT * FROM @TBL

    Espero ter ajudado se foi útil marque como resposta.


    Davi Murilo Referência Principal : Jesus que ilumina minha mente.
    Referência Profissonal : http://www.tidm.com.br

    terça-feira, 7 de maio de 2013 19:47
  • Eu modifiquei o codigo anterior para permanecer penas 1 dos repetidos veja o codigo:

    DECLARE @TBL AS TABLE (ID INT NOT NULL IDENTITY(1,1) , VALOR DECIMAL(10,2))
    
    INSERT INTO @TBL(VALOR) VALUES(50.50),(50.50),(50.50),(30.10),(30.50)
    
    
    DELETE FROM  @TBL 
    
    WHERE ID IN ( 
    SELECT TOP(( SELECT COUNT(VALOR) AS TOTAL FROM @TBL
    				 GROUP BY VALOR HAVING COUNT(VALOR) > 1 ) - 1 ) ID FROM @TBL
    		
    		 WHERE VALOR IN
    				(
    				 SELECT VALOR FROM @TBL
    				 GROUP BY VALOR HAVING COUNT(VALOR) > 1
    				 )
     
     )
     
    
    SELECT * FROM @TBL

    Espero ter ajudado


    Davi Murilo Referência Principal : Jesus que ilumina minha mente.
    Referência Profissonal : http://www.tidm.com.br

    terça-feira, 7 de maio de 2013 20:01
  • E mais uma vez porém agora deixando o código mais limpo com CTE :

    DECLARE @TBL AS TABLE (ID INT NOT NULL IDENTITY(1,1) , VALOR DECIMAL(10,2))
    
    INSERT INTO @TBL(VALOR) VALUES(50.50),(50.50),(50.50),(30.10),(30.50)
    
    
    ;WITH GRUPO
    AS ( 
    	SELECT VALOR ,COUNT(VALOR) AS TOTAL FROM @TBL
    	GROUP BY VALOR HAVING COUNT(VALOR) > 1
     )
    
    DELETE FROM  @TBL 
    
    WHERE ID IN ( 
    SELECT TOP((SELECT TOTAL FROM GRUPO) - 1 ) ID FROM @TBL
    		
    		 WHERE VALOR IN
    				(
    				 SELECT VALOR FROM GRUPO
    				 )
     
     )
     
    
    SELECT * FROM @TBL

    Espero ter ajudado


    Davi Murilo Referência Principal : Jesus que ilumina minha mente.
    Referência Profissonal : http://www.tidm.com.br

    terça-feira, 7 de maio de 2013 20:05
  • O seu script é muito bom, mas ainda não me ajudou 100%, porque a comparação tem que ser realizada entre duas tabelas, uma que possui valores negativos e a outra positivos.

         Vamos dizer que eu tenha dois valores negativo em uma tabela e três positivos na outra. Vamos dizer que eu use o select<count> na tabela de valores negativos e com o resultado exclua o mesmo valor, porém positivo, na outra tabela, mas a mesma quantidade.

    TabelaA.valor             B.valor

    12,00                      - 12,00

    13,00                     

    12,00                    

    Tentei +- assim:

    declare @contador, @top

    select @top = count(valor) from B

    delete from A (select top(@top)* from A where A.valor = ABS(B.valor))

    -------

    Funcionou, mas quando tem mais valores negativos , a exclusão é realizada de forma errada pois exclui muitos valores, mesmo usando cursor.

    Utilizando Cursor , como faço para pegar dados linha a linha, já que o top não está funcionando?

    vlw rapaziada!
    quarta-feira, 8 de maio de 2013 13:50
  • Bom dia,

    Experimente fazer um teste com o script abaixo:

    declare @TabelaA table
    (Valor money);
    
    insert into @TabelaA values 
    (12), (13), (12), (14);
    
    declare @TabelaB table
    (Valor money);
    
    insert into @TabelaB values 
    (-12), (-14);
    
    with
        CTE_N as
        (
            select Valor, COUNT(*) as Qtd
            from @TabelaB
            group by Valor
        ),
        
        CTE_P as
        (
            select Valor, ROW_NUMBER() OVER(PARTITION BY Valor ORDER BY Valor) as RowNum
            from @TabelaA
        ),
        
        CTE_D as
        (
            select p.*
            from CTE_P as p
            where p.RowNum <= (select n.Qtd from CTE_N as n where ABS(n.Valor) = p.Valor)
        )
        
        
    delete from CTE_D
    
    select * from @TabelaA

    Espero que ajude.


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

    • Marcado como Resposta jmarqDeveloper quarta-feira, 8 de maio de 2013 18:06
    quarta-feira, 8 de maio de 2013 14:36
  • Perfeito!!!!

    Era isso mesmo que eu estava querendo.

    O interessante é que percebi e entendi a função Row_number.

    Obrigado , gapimex!




    quarta-feira, 8 de maio de 2013 18:11