Ir para conteúdo
Fórum Script Brasil
  • 0

Algoritmo: filtrar valores duplicados


Duduh_Capixaba

Pergunta

Fala galera!

Estou tentando preencher os dados de uma tabela baseado nos dados de outra. Sendo que na tabela T1 eu possuo vários dados duplicados, e na tabela T2 esses dados são a chave primária, portanto, não podem se repetir.

Exemplo de estrutura da tabela T1 (cada "|" significa um registro diferente):

c | b | a | a | c | d | e | b | b | a

Com esses dados em T1, estou tentando fazer com que a tabela T2 fique assim:

c | b | a | d | e

Já tentei montar meu algoritmo de várias formas, com matrizes e tudo, mas não consegui chegar numa lógica que funcionasse :S Peço ajuda.

Editado por Duduh_Capixaba
Link para o comentário
Compartilhar em outros sites

11 respostass a esta questão

Posts Recomendados

  • 0

Oi 'Duduh_Capixaba' !

A grosso modo seria assim:

declarar chaveanterior;
inicializar chaveanterior com 0 ou "";
Ordenar T1 pela chave desejada;
Posicionar T1 no primeiro registro;
Enquanto not T1.EOF faça
begin
   Se T1.chave <> chaveanterior então
   begin
      chaveanterior := T1.chave
      grava em T2 Registro de T1;
   end;
   Leia proximo registro de T1;
end;

Link para o comentário
Compartilhar em outros sites

  • 0

Me corrijam se eu estiver errado (e posso estar) :unsure:

Mas, baseado no comentário: "(...) Sendo que na tabela T1 eu possuo vários dados duplicados, e na tabela T2 esses dados são a chave primária, portanto, não podem se repetir."

não seria o caso de usar uma query com uma instrução SQL parecida com isto:

select distinct Campo
from T1
que retorna apenas uma ocorrência de Campo na tabela T1 e assim, minimiza a pesquisa na tabela T2. Ou ainda:
select distinct Campo
from T1 where not exists(select Campo from T2 where T1.Campo = T2.Campo)

que deve retornar exatamente os campos da tabela T1 que ainda não existem na tabela T2.

Duduh_Capixaba, com este outro comentário:

Exemplo de estrutura da tabela T1 (cada "|" significa um campo diferente):

você sugere estar falando dos campos (colunas) na estrutura da sua tabela T1.

Mas, se o objetivo era falar de um determinado campo da estrutura da tabela (coluna), que se repete em várias linhas (registros), talvez ficasse melhor deixar claro de que: "|" significa um registro diferente, assim não fica dúvidas sobre o que você está falando.

Abraços

Link para o comentário
Compartilhar em outros sites

  • 0

Correto meu amigo Micheus, cada "|" significa um registro diferente, e não um campo diferente como eu citei. Me desculpem pela falta de atenção no post, já consertei.

Quanto à sua resposta, ainda não testei o filtro SQL que você sugeriu. Vou fazer uns testes e qualquer novidade posto aqui, apesar de já ter resolvido meu problema com o comando "Locate". Obrigado!

--------------------------------------EDIÇÃO--------------------------------------

Perfeito Micheus, o código SQL realmente funciona! Só que eu não tinha explicado ainda, que além disso, eu preciso somar em cada registro da tabela T1, um campo com um valor real. A estrutura real de T1, seria essa (agora, cada "|" representa uma coluna, onde PK é uma chave primária qualquer):

PK | CFOP | VRTOTAL

01 | 5929 | 280,88

02 | 5102 | 420,00

03 | 5102 | 32,90

04 | 5929 | 336,50

05 | 1102 | 150,00

06 | 2303 | 867,37

07 | 1102 | 213,00

08 | 2102 | 690,00

Então na tabela T2 eu teria como resultado (onde CFOP é a chave primária):

CFOP | VRTOTAL

1102 | 363,00

2102 | 690,00

2303 | 867,37

5102 | 452,90

5929 | 617,38

Ou seja, tenho que ler T1 registro por registro, inserindo e editando à medida que encontro um CFOP. Esse é o código que estou usando:

begin
  .
  .
  .
  while not T1.Eof do begin
    if T2.Locate('CFOP', T1.FieldValues['CFOP'], []) then begin
      T2.Edit;
    end

    else begin
      T2.Insert;
      T2.FieldByName('CFOP').Value := T1.FieldValues['CFOP'];
    end;

    T2VRTOTAL.Value  := T2VRTOTAL.Value  + T1VRTOTAL.Value;
    T2BASEICMS.Value := T2BASEICMS.Value + T1BASEICMS.Value;
    T2VRICMS.Value   := T2VRICMS.Value   + T1VRICMS.Value;
    T2ISENTAS.Value  := T2ISENTAS.Value  + T1ISENTAS.Value;
    T2OUTRAS.Value   := T2OUTRAS.Value   + T1OUTRAS.Value;

    T2.Post;
    T1.Next;
  end;
  .
  .
  .
end;

Me desculpem por não ter postado todo o problema antes, pensei que iria ficar um post muito grande, mas acabei fugindo do problema real. Mas tudo resolvido. Se alguém tiver uma outra sugestão para o meu código acima, fique a vontade. Obrigado, abraço!

Editado por Duduh_Capixaba
Link para o comentário
Compartilhar em outros sites

  • 0
Me desculpem por não ter postado todo o problema antes, pensei que iria ficar um post muito grande, mas acabei fugindo do problema real.

Realmente é sempre bom postar a dúvida com seus detalhes relevantes - evita que fiquemos "falando" de algo que não é correto, podendo até confundir a quem pergunta.

Duduh_Capixaba, só uma ressalva quanto a este tipo de procedimento: Voce tem algum meio de prevenir que a informação seja processada mais que uma vez? Do contrário, poderá gerar resultados indesejados, já que sempre é adicionado o valor da tabela T1 para a T2.

Abraços

Link para o comentário
Compartilhar em outros sites

  • 0

Não, o código principal é esse mesmo que postei. Acompanhei o processo pelo "Step Over" e o resultado é sempre correto. Com o "Locate" eu tenho apenas duas possibilidades, ou ele encontra o valor de T1 em T2 ou não, claro! Se ele não encontra, eu crio o CFOP e somo os valores. Se encontra, então eu apenas somo os valores, pois o CFOP já foi criado... É batata! :) Dá certinho.

Mas creio que existam outros modos de se fazer isso. Ainda sou iniciante em programação e conheço poucos comandos e procedimentos. Abraço!

Link para o comentário
Compartilhar em outros sites

  • 0
Se ele não encontra, eu crio o CFOP e somo os valores. Se encontra, então eu apenas somo os valores, pois o CFOP já foi criado...

acho que não consegui deixar claro o comentário. Vamos supor que você faça este processo através do click de um botão. Então, usando o exemplo que você mesmo deu, e partindo desta premissa de que se houver a informação, você soma o valor:

T1

PK | CFOP | VRTOTAL

01 | 5929 | 280,88

02 | 5102 | 420,00

03 | 5102 | 32,90

04 | 5929 | 336,50

05 | 1102 | 150,00

06 | 2303 | 867,37

07 | 1102 | 213,00

08 | 2102 | 690,00

Então na tabela T2 eu teria como resultado (onde CFOP é a chave primária):

CFOP | VRTOTAL

1102 | 363,00

2102 | 690,00

2303 | 867,37

5102 | 452,90

5929 | 617,38

Daí, o procedimento é executado uma outra vez (é clicado no botão de novo)

Então na tabela T2 o resultado passaria a ser:

CFOP | VRTOTAL

1102 | 726,00

2102 | 1.380,00

2303 | 1.734,74

5102 | 905,80

5929 | 1.234,76

É a este tipo de possibilidade a que me referia.

Abraços

Link para o comentário
Compartilhar em outros sites

  • 0

Ah sim, hehe, agora entendi :P Não, na verdade eu sempre limpo a tabela T2 antes de preenchê-la. Antes do código que eu deixei acima, vem esse código:

begin
  .
  .
  .
  ADOQuery.SQL.Add('DELETE FROM SINCFOP');
  ADOQuery.ExecSQL;
  ADOQuery.SQL.Clear;
  .
  .
  .
end;

Porque na verdade, isso é pra gerar um resumo de vendas por CFOP, tipo como um relatório, e eu exibo o resultado em um grid, pro usuário ter noção de suas vendas ^^ É uma tabela temporária, seus valores nunca acumulam.

Editado por Duduh_Capixaba
Link para o comentário
Compartilhar em outros sites

  • 0
Não, na verdade eu sempre limpo a tabela T2 antes de preenchê-la.

Foi o que suspeitei. De novo, você deixou informação faltando.

Então segue a sugestão que evitei de passar lá no início, por não ter certeza do que você realmente queria:

select CFOP, sum(VRTOTAL) as VRTOTAL
from T1 group by CFOP
isto resulta em todos os CFOP somados de acordo com seu código, podendo ser inseridas as linhas resultantes na tabela T2 diretamente. Talvez você possa ainda, fazer de uma só vez (eu nunca testei usando group by):
select CFOP, sum(VRTOTAL) as VRTOTAL INTO T2 from T1
group by CFOP

talvez seja necessário executar o DROP table T2, no lugar do seu DELETE from

Tenho certeza que o colega Denis Courcy, já lhe teria sugerido algo parecido se você não tivesse omitido tantos detalhes. <_<

Abraços

Link para o comentário
Compartilhar em outros sites

  • 0

Pois é... É porque sempre tento entender o funcionamento dos comandos e a lógica antes de expôr o meu código. Mas nesse caso só atrapalhou.

O seu código acima também funcionou, e ficou muito mais rápido! Vou usar ele. Obrigado mais uma vez. Abraço!

Editado por Duduh_Capixaba
Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,3k
    • Posts
      652,2k
×
×
  • Criar Novo...