Clipper On Line • Ver Tópico - Como filtrar muitos registros? Dúvida

Como filtrar muitos registros? Dúvida

Projeto Harbour - Compilador de código aberto compatível com o Clipper.

Moderador: Moderadores

 

Como filtrar muitos registros? Dúvida

Mensagempor fladimir » 09 Fev 2018 17:20

Pessoal deu um branco aki, se alguém puder ajudar, seguinte...

Tenho uma situação q surgiu q tenho uma tabela Mestre q tem o cabecalho com dados como NrInterno e DataLanc, ai tenho uma tabela filha q tem os registros vinculados a esta tabela Mestre.
Dentro desta tabela filha cada registro tem um campo chamado DtViagem

Preciso criar uma consulta q retorne uma filtragem da seguinte maneira, informo o periodo da viagem exemplo 01/01/2018 até 31/01/2018, blz
Ai o q tiver de viagens nessa tabela filha preciso pegar os respectivos registros vinculados da tabela Mestre

Comecei a montar o seguinte código

Pega viagens:
      
      Itens->( DBEVAL( { || AADD( aViagens, { Itens->NrInterno, Itens->DataLanc } )   },; // Bloco While
                              { || Itens->DtViagem >= dt1 .and. Itens->DtViagem <= dt2 } ; // Bloco For
                            );
                    )

Ai a partir desse Array pensei em montar ou um Indice ou um Filter, MAS O X DA QUESTAO ESTA AKI.... pode ficar gigante o negocio...

alguém teria uma ideia sobre o assunto?
Sun Tzu há mais de três mil anos cita nas epígrafes de seu livro “A Arte da Guerra“:

“Concentre-se nos pontos fortes, reconheça as fraquezas, agarre as oportunidades e proteja-se contra as ameaças”.
“Se não é vantajoso, nunca envie suas tropas; se não lhe rende ganhos, nunca utilize seus homens; se não é uma situação perigosa, nunca lute uma batalha precipitada”
.


Até 2017    Desktop Console [ Legado ] Harbour | MinGW | DBF | CDX | FastReport | MySQL


Novos Projetos:

   Desktop Visual           Windev Desktop
   Celular Android/iOS   Windev Mobile
   WEB                            Windev Web


Sejamos gratos a Deus.
Avatar de usuário

fladimir
Colaborador

Colaborador
 
Mensagens: 2434
Data de registro: 15 Nov 2006 19:21
Curtiu: 28 vezes
Mens.Curtidas: 157 vezes

Como filtrar muitos registros? Dúvida

Mensagempor asimoes » 10 Fev 2018 10:52

Fladimir,

Beleza ?

Informa qual é a estrutura das duas tabelas, mestre e detalhe

A detalhe tem NrInterno e DataLanc e a detalhe ? tem os mesmos campos ? acho que vai ter que ter uma chave nessa consulta talvez o NrInterno

Só uma ideia: corrige ai se eu não entendi direito

Estou supondo que a chave de ligação entre as duas tabelas seja o NrInterno, se for isso eu criaria um indice com NrInterno + DtViagem

DO WHILE MESTRE->NrInterno =  nNumero .AND. ! MESTRE->( Eof() )

   aViagens := {}
   
   DETALHE->( DbSeek( Str( MESTRE->NrInterno )  +  DTOS( dt1 ) ) )
   
   DO WHILE DETALHE->NrInterno = nNumero .AND. FILHA->DtViagem <= dt1 .AND. ! FILHA->( Eof() )
      AADD( aViagens, { MESTRE->NrInterno, MESTRE->DataLanc } )
      DETALHE->( DbSkip() )
   ENDDO
   
   MESTRE->( DbSkip() )
   
ENDDO   
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar de usuário

asimoes
Colaborador

Colaborador
 
Mensagens: 4919
Data de registro: 26 Abr 2007 16:48
Cidade/Estado: RIO DE JANEIRO-RJ
Curtiu: 341 vezes
Mens.Curtidas: 258 vezes

Como filtrar muitos registros? Dúvida

Mensagempor fladimir » 10 Fev 2018 11:34

A chave é NrInterno + DTOS(DataLanc)
Esses campos tem nas 2 tabelas

Montar o Array eu consegui...

Minha preocupação é se fizer via Indice será q da certo tipo pq o FOR pode ter muitos campos tipo

Vou escrever a grosso modo só pra transmitir a ideia q estou preocupado se não terá problemas.

Tipo:
cFiltro := ""
For nI:=1 to Len(aViagens)
     If nI >1
      cFiltro += ".OR."
    endif
    cFiltro += [ "(Mestre->NrLanc == "] + aViagens[nI,1] + [" .and. DTOS(Mestre->DataLanc) == "] + DTOS(aViagens[nI,2] + [")]
NEXT
bFiltro := &( ' { || ' + cFiltro + ' }' )
INDEX ...... FOR EVAL(bFILTRO)


Imaginemos q achou 30 viagens Ok... ai como filtrar isso na tabela Mestre, se eu monto um FOR NEXT pra criar um FILTRO e depois passar como INDEX KEY TAG TEMP TO IDX FOR EVAL( bFiltro ) pode ficar muito extenso, será q tem limite isso?
Sun Tzu há mais de três mil anos cita nas epígrafes de seu livro “A Arte da Guerra“:

“Concentre-se nos pontos fortes, reconheça as fraquezas, agarre as oportunidades e proteja-se contra as ameaças”.
“Se não é vantajoso, nunca envie suas tropas; se não lhe rende ganhos, nunca utilize seus homens; se não é uma situação perigosa, nunca lute uma batalha precipitada”
.


Até 2017    Desktop Console [ Legado ] Harbour | MinGW | DBF | CDX | FastReport | MySQL


Novos Projetos:

   Desktop Visual           Windev Desktop
   Celular Android/iOS   Windev Mobile
   WEB                            Windev Web


Sejamos gratos a Deus.
Avatar de usuário

fladimir
Colaborador

Colaborador
 
Mensagens: 2434
Data de registro: 15 Nov 2006 19:21
Curtiu: 28 vezes
Mens.Curtidas: 157 vezes

Como filtrar muitos registros? Dúvida

Mensagempor dbdc5554 » 10 Fev 2018 12:23

ja usei MUITAS condicoes dentro de FOR

acredito NAo ter limite porque é uma Logica ao montar o indice

tipo if ignore else selecione

e pelo que eu VI

MELHOR filtrar do que ignorar registro em um LOOP

Paiva
dbdc5554
Usuário Nível 3

Usuário Nível 3
 
Mensagens: 149
Data de registro: 03 Dez 2012 07:49
Cidade/Estado: uberlandia-MG
Curtiu: 0 vez
Mens.Curtidas: 1 vez

Como filtrar muitos registros? Dúvida

Mensagempor fladimir » 10 Fev 2018 15:02

Blz pessoal, obrigado.
Sun Tzu há mais de três mil anos cita nas epígrafes de seu livro “A Arte da Guerra“:

“Concentre-se nos pontos fortes, reconheça as fraquezas, agarre as oportunidades e proteja-se contra as ameaças”.
“Se não é vantajoso, nunca envie suas tropas; se não lhe rende ganhos, nunca utilize seus homens; se não é uma situação perigosa, nunca lute uma batalha precipitada”
.


Até 2017    Desktop Console [ Legado ] Harbour | MinGW | DBF | CDX | FastReport | MySQL


Novos Projetos:

   Desktop Visual           Windev Desktop
   Celular Android/iOS   Windev Mobile
   WEB                            Windev Web


Sejamos gratos a Deus.
Avatar de usuário

fladimir
Colaborador

Colaborador
 
Mensagens: 2434
Data de registro: 15 Nov 2006 19:21
Curtiu: 28 vezes
Mens.Curtidas: 157 vezes

Como filtrar muitos registros? Dúvida

Mensagempor Eolo » 10 Fev 2018 15:40

Fladimir, dá uma olhada no ORDSCOPE().

Se a tabela filha está indexada (CDX) por data (dtviagem), é só fazer o seguinte:
odscope(0,ctod("01/01/2018")) // início
odscope(1,ctod("31/12/2018")) // fim
go top

Feito isso, se vc der um browse no DBF, vão aparecer somente os registros que estejam dentro do escopo desejado. Os demais registros continuam lá, mas "invisíveis". GO TOP vai pra 01-jan e GO BOTT vai pra 31-dez.

Tá feito o filtro. Agora é só buscar o resto na tabela pai.

Pra remover o filtro:
odscope(0,nil)
odscope(1,nil)
go top

Mais importante: a filtragem é instantânea.
Avatar de usuário

Eolo
Colaborador

Colaborador
 
Mensagens: 1134
Data de registro: 08 Dez 2005 17:24
Cidade/Estado: São Paulo - SP
Curtiu: 0 vez
Mens.Curtidas: 41 vezes

Como filtrar muitos registros? Dúvida

Mensagempor asimoes » 10 Fev 2018 18:13

Pra não ficar um filtro monstro eu pensaria em algo assim

cFiltro := [ Mestre->NrLanc >= ] + aViagens[1,1] + [ .AND. Mestre->NrLanc <= ] + aViagens[Len(aViagens),1] + [ .AND. ]
cFiltro += [ DTOS(Mestre->DataLanc) ] >= DTOS(aViagens[1,2]) [ .AND. DTOS(Mestre->DataLanc) <= ] + aViagens[Len(aViagens),2]
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar de usuário

asimoes
Colaborador

Colaborador
 
Mensagens: 4919
Data de registro: 26 Abr 2007 16:48
Cidade/Estado: RIO DE JANEIRO-RJ
Curtiu: 341 vezes
Mens.Curtidas: 258 vezes

Como filtrar muitos registros? Dúvida

Mensagempor Eolo » 10 Fev 2018 18:23

Simões, o Ordscope faz isso tudo. Instantâneo.
Eu usei por muito tempo (uma fantástica dica do Sygecom).

O que o Ordscope faz é simplesmente "setar" o TOP e o BOTT como o início e o fim de um escopo, instantaneamente, sem criação de índices adicionais ou pesquisas ou etc. Só os registros que interessam ficam visíveis (filtrados). Instantâneo.

Você já experimentou?
Avatar de usuário

Eolo
Colaborador

Colaborador
 
Mensagens: 1134
Data de registro: 08 Dez 2005 17:24
Cidade/Estado: São Paulo - SP
Curtiu: 0 vez
Mens.Curtidas: 41 vezes

Como filtrar muitos registros? Dúvida

Mensagempor Eolo » 10 Fev 2018 19:01

Eu usei isso bastante, num programa de mercado.

Um exemplo: o cadastro de produtos tinha vários índices, um deles por SETOR. O cliente dava um browse nos produtos, escolhia um dos Setores (tipo Laticínios, Carnes, Padaria), o browse na hora mostrava só os produtos do setor escohido. Instantâneo.

Se o objetivo era corrigir em 5% os preços somente daquele Setor, era só fazer GO TOP, DO WHILE !EOF(), REPL PRECO WITH ROUND(PRECO*1.05,2)... Feito. Se era pra imprimir as etiquetas de gôndola do setor, feito.

E esse "filtro" não é um monstro, nada a ver com SET FILTER, por exemplo, ou índices temporários ou o que for. O Ordscope simplesmente fecha o foco (BOF/EOF) sobre o que interessa dentro de um CDX. Instantâneo.
Avatar de usuário

Eolo
Colaborador

Colaborador
 
Mensagens: 1134
Data de registro: 08 Dez 2005 17:24
Cidade/Estado: São Paulo - SP
Curtiu: 0 vez
Mens.Curtidas: 41 vezes

Como filtrar muitos registros? Dúvida

Mensagempor JoséQuintas » 10 Fev 2018 19:38

Exato.
Se a tabela vai ficar monstruosa, melhor existir um índice por data, nem que seja necessário criar um arquivo temporário depois pra ordenar.
Pode usar o SET SCOPE, ou até o SEEK Dtos( dDataIni ) SOFTSEEK
Se tiver que processar todos os registros sempre, vai ser demorado, então melhor já ter o índice criado e fazer parte do banco de dados.

Isso vale pra NTX, CDX, MySQL, etc.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18013
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1206 vezes

Como filtrar muitos registros? Dúvida

Mensagempor fladimir » 10 Fev 2018 19:45

Valeu pessoal pelas ideias, vou bolar algo aki... agradeço.
Sun Tzu há mais de três mil anos cita nas epígrafes de seu livro “A Arte da Guerra“:

“Concentre-se nos pontos fortes, reconheça as fraquezas, agarre as oportunidades e proteja-se contra as ameaças”.
“Se não é vantajoso, nunca envie suas tropas; se não lhe rende ganhos, nunca utilize seus homens; se não é uma situação perigosa, nunca lute uma batalha precipitada”
.


Até 2017    Desktop Console [ Legado ] Harbour | MinGW | DBF | CDX | FastReport | MySQL


Novos Projetos:

   Desktop Visual           Windev Desktop
   Celular Android/iOS   Windev Mobile
   WEB                            Windev Web


Sejamos gratos a Deus.
Avatar de usuário

fladimir
Colaborador

Colaborador
 
Mensagens: 2434
Data de registro: 15 Nov 2006 19:21
Curtiu: 28 vezes
Mens.Curtidas: 157 vezes

Q

Mensagempor Eolo » 10 Fev 2018 20:40

Se a tabela vai ficar monstruosa, melhor existir um índice por data, nem que seja necessário criar um arquivo temporário depois pra ordenar.
Pode usar o SET SCOPE, ou até o SEEK Dtos( dDataIni ) SOFTSEEK
Se tiver que processar todos os registros sempre, vai ser demorado, então melhor já ter o índice criado e fazer parte do banco de dados.

Isso vale pra NTX, CDX, MySQL, etc.

Bem lembrado, José!

Fladimir, é fundamental ter índices criados.

Sem um índice, nem OrdScope nem Seek funcionam, talvez nem o Soft Seek. Precisa ter isso em mente.
Sem índice, um browse vai mostrar os dados na ordem em que foram criados.
Totalmente sem sentido, cara.
E criar índices temporários, no run time, com um imenso data base, pode ser improdutivo.
Tem que ficar ligado nisso.
Avatar de usuário

Eolo
Colaborador

Colaborador
 
Mensagens: 1134
Data de registro: 08 Dez 2005 17:24
Cidade/Estado: São Paulo - SP
Curtiu: 0 vez
Mens.Curtidas: 41 vezes

Como filtrar muitos registros? Dúvida

Mensagempor rubens » 12 Fev 2018 16:20

Fladimir,

Com o Ordscope() você ainda pode aplicar um SetFilter depois que ainda vai ficar muito rápido...
Se não satisfazer as condições que precisa... Filtra com Ordscope(), cria uma tabela na memória e joga os dados filtrados nela.. Daí pode criar índices na memória também... ou filtrar com setfilter. Tudo extremamente rápido...
Depois que aprendi usar tabela e índice na memória nunca mais usei vetores/matrizes...
é mais fácil ordenar a tabela do que vetores/matrizes...

Rubens
"Eu e minha casa servimos ao Senhor e você ???"
Avatar de usuário

rubens
Colaborador

Colaborador
 
Mensagens: 1518
Data de registro: 16 Ago 2003 09:05
Cidade/Estado: Nova Xavantina - MT
Curtiu: 77 vezes
Mens.Curtidas: 104 vezes

Como filtrar muitos registros? Dúvida

Mensagempor fladimir » 12 Fev 2018 18:13

Legal Rubens, obrigado pela dica.
Sun Tzu há mais de três mil anos cita nas epígrafes de seu livro “A Arte da Guerra“:

“Concentre-se nos pontos fortes, reconheça as fraquezas, agarre as oportunidades e proteja-se contra as ameaças”.
“Se não é vantajoso, nunca envie suas tropas; se não lhe rende ganhos, nunca utilize seus homens; se não é uma situação perigosa, nunca lute uma batalha precipitada”
.


Até 2017    Desktop Console [ Legado ] Harbour | MinGW | DBF | CDX | FastReport | MySQL


Novos Projetos:

   Desktop Visual           Windev Desktop
   Celular Android/iOS   Windev Mobile
   WEB                            Windev Web


Sejamos gratos a Deus.
Avatar de usuário

fladimir
Colaborador

Colaborador
 
Mensagens: 2434
Data de registro: 15 Nov 2006 19:21
Curtiu: 28 vezes
Mens.Curtidas: 157 vezes




Retornar para Harbour

Quem está online

Usuários vendo este fórum: Google [Bot] e 6 visitantes


Ola Amigo, espero que meu site e forum tem lhe beneficiado, com exemplos e dicas de programacao.
Entao divulgue o link da Doacao abaixo para seus amigos e redes sociais ou faça uma doacao para o site forum...
MUITO OBRIGADO PELA SUA DOACAO!
Faça uma doação para o forum
cron
v
Olá visitante, seja bem-vindo ao Fórum Clipper On Line!
Efetue o seu login ou faça o seu Registro