Como filtrar muitos registros? Dúvida

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

Moderador: Moderadores

Avatar do usuário
fladimir
Colaborador
Colaborador
Mensagens: 2445
Registrado em: 15 Nov 2006 20:21

Como filtrar muitos registros? Dúvida

Mensagem por fladimir »

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:

Código: Selecionar todos

		
		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 do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

Como filtrar muitos registros? Dúvida

Mensagem por asimoes »

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

Código: Selecionar todos

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 do usuário
fladimir
Colaborador
Colaborador
Mensagens: 2445
Registrado em: 15 Nov 2006 20:21

Como filtrar muitos registros? Dúvida

Mensagem por fladimir »

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:

Código: Selecionar todos

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.
dbdc5554
Usuário Nível 3
Usuário Nível 3
Mensagens: 149
Registrado em: 03 Dez 2012 08:49
Localização: uberlandia-MG

Como filtrar muitos registros? Dúvida

Mensagem por dbdc5554 »

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
Avatar do usuário
fladimir
Colaborador
Colaborador
Mensagens: 2445
Registrado em: 15 Nov 2006 20:21

Como filtrar muitos registros? Dúvida

Mensagem por fladimir »

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 do usuário
Eolo
Colaborador
Colaborador
Mensagens: 1134
Registrado em: 08 Dez 2005 18:24
Localização: São Paulo - SP

Como filtrar muitos registros? Dúvida

Mensagem por Eolo »

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 do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

Como filtrar muitos registros? Dúvida

Mensagem por asimoes »

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

Código: Selecionar todos

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 do usuário
Eolo
Colaborador
Colaborador
Mensagens: 1134
Registrado em: 08 Dez 2005 18:24
Localização: São Paulo - SP

Como filtrar muitos registros? Dúvida

Mensagem por Eolo »

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 do usuário
Eolo
Colaborador
Colaborador
Mensagens: 1134
Registrado em: 08 Dez 2005 18:24
Localização: São Paulo - SP

Como filtrar muitos registros? Dúvida

Mensagem por Eolo »

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 do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Como filtrar muitos registros? Dúvida

Mensagem por JoséQuintas »

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 mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"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 do usuário
fladimir
Colaborador
Colaborador
Mensagens: 2445
Registrado em: 15 Nov 2006 20:21

Como filtrar muitos registros? Dúvida

Mensagem por fladimir »

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 do usuário
Eolo
Colaborador
Colaborador
Mensagens: 1134
Registrado em: 08 Dez 2005 18:24
Localização: São Paulo - SP

Q

Mensagem por Eolo »

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 do usuário
rubens
Colaborador
Colaborador
Mensagens: 1520
Registrado em: 16 Ago 2003 09:05
Localização: Nova Xavantina - MT

Como filtrar muitos registros? Dúvida

Mensagem por rubens »

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 do usuário
fladimir
Colaborador
Colaborador
Mensagens: 2445
Registrado em: 15 Nov 2006 20:21

Como filtrar muitos registros? Dúvida

Mensagem por fladimir »

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.
Responder