ActiveDelphi - Índice do Fórum ActiveDelphi
.: O site do programador Delphi! :.
 
 FAQFAQ   PesquisarPesquisar   MembrosMembros   GruposGrupos   RegistrarRegistrar 
 PerfilPerfil   Entrar e ver Mensagens ParticularesEntrar e ver Mensagens Particulares   EntrarEntrar 

Fazer um select max no firebird?
Ir à página Anterior  1, 2, 3  Próximo
 
Novo Tópico   Responder Mensagem    ActiveDelphi - Índice do Fórum -> Banco de Dados
Exibir mensagem anterior :: Exibir próxima mensagem  
Autor Mensagem
adriano_servitec
Colaborador
Colaborador


Registrado: Sexta-Feira, 30 de Janeiro de 2004
Mensagens: 17618

MensagemEnviada: Qua Dez 05, 2012 10:43 am    Assunto: Responder com Citação

imex escreveu:
Experimente fazer um teste com a query abaixo para verificar o resultado:

Código:
SELECT FIRST 1 ( CAST(o.nrordemserv as INTEGER) + 1 ) as n_doc
FROM ordemserv as o
WHERE
    CAST(o.nrordemserv as INTEGER) > 50000 and
    not exists (select 1 from ordemserv as s
                where CAST(s.nrodermserv as INTEGER) = CAST(o.nrordemserv as INTEGER) + 1)
ORDER BY CAST(o.nrordemserv as INTEGER)


Espero que ajude.
Hi Imex, acho que assim não rola amigo, fica lento de +, chega a travar, o banco é um pouco grande.
_________________
Jogo seu smartphone? Acesse o link e confira.
https://play.google.com/store/apps/details?id=br.com.couldsys.rockdrum
https://play.google.com/store/apps/details?id=br.com.couldsys.drumsetfree
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
imex
Moderador
Moderador


Registrado: Sexta-Feira, 7 de Janeiro de 2011
Mensagens: 11666

MensagemEnviada: Qua Dez 05, 2012 11:21 am    Assunto: Responder com Citação

Acho que o que complica é o fato de o campo nrordemserv ser to tipo varchar.
Existe algum índice na tabela com o campo nrordemserv?

Experimente a query abaixo:

Código:
SELECT FIRST 1 ( CAST(o.nrordemserv as INTEGER) + 1 ) as n_doc
FROM ordemserv as o
WHERE
    o.nrordemserv > '50000' and
    substring(o.nrordemserv from 6 for 1) = '' and
    not exists (select 1 from ordemserv as s
                where s.nrordemserv = CAST(CAST(o.nrordemserv as INTEGER) + 1 as varchar(10)))
ORDER BY o.nrordemserv


Se essa query acima não retornar nada (quando não há códigos entre 50001 e 99999), teria que ser executa uma outra query alterando apenas parte da clausula Where para procurar entre 100000 e 999999:

Código:
WHERE
    o.nrordemserv >= '100000' and
    substring(o.nrordemserv from 7 for 1) = '' and


Acho que talvez melhore um pouco o desempenho desta forma, se existir um índice com o campo nrordemserv nesta tabela.

Espero que ajude.
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
adriano_servitec
Colaborador
Colaborador


Registrado: Sexta-Feira, 30 de Janeiro de 2004
Mensagens: 17618

MensagemEnviada: Qua Dez 05, 2012 1:42 pm    Assunto: Responder com Citação

imex escreveu:
Acho que o que complica é o fato de o campo nrordemserv ser to tipo varchar.
Existe algum índice na tabela com o campo nrordemserv?

Experimente a query abaixo:

Código:
SELECT FIRST 1 ( CAST(o.nrordemserv as INTEGER) + 1 ) as n_doc
FROM ordemserv as o
WHERE
    o.nrordemserv > '50000' and
    substring(o.nrordemserv from 6 for 1) = '' and
    not exists (select 1 from ordemserv as s
                where s.nrordemserv = CAST(CAST(o.nrordemserv as INTEGER) + 1 as varchar(10)))
ORDER BY o.nrordemserv


Se essa query acima não retornar nada (quando não há códigos entre 50001 e 99999), teria que ser executa uma outra query alterando apenas parte da clausula Where para procurar entre 100000 e 999999:

Código:
WHERE
    o.nrordemserv >= '100000' and
    substring(o.nrordemserv from 7 for 1) = '' and


Acho que talvez melhore um pouco o desempenho desta forma, se existir um índice com o campo nrordemserv nesta tabela.

Espero que ajude.
Então Imex, esta select ai retornou 5007, minha idéia é retornar de 50.000 acima, mais pelo menos ficou instantâneo o retorno.
_________________
Jogo seu smartphone? Acesse o link e confira.
https://play.google.com/store/apps/details?id=br.com.couldsys.rockdrum
https://play.google.com/store/apps/details?id=br.com.couldsys.drumsetfree
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
imex
Moderador
Moderador


Registrado: Sexta-Feira, 7 de Janeiro de 2011
Mensagens: 11666

MensagemEnviada: Qua Dez 05, 2012 2:00 pm    Assunto: Responder com Citação

Experimente alterar os parâmetros da função substring:

Código:
    substring(o.nrordemserv from 5 for 1) <> '' and


e para a segunda query:

Código:
    substring(o.nrordemserv from 6 for 1) <> '' and


Espero que ajude.
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
adriano_servitec
Colaborador
Colaborador


Registrado: Sexta-Feira, 30 de Janeiro de 2004
Mensagens: 17618

MensagemEnviada: Qua Dez 05, 2012 2:11 pm    Assunto: Responder com Citação

imex escreveu:
Experimente alterar os parâmetros da função substring:

Código:
    substring(o.nrordemserv from 5 for 1) <> '' and


e para a segunda query:

Código:
    substring(o.nrordemserv from 6 for 1) <> '' and


Espero que ajude.
Não entendi, desculpe, mais ja não esta assim?
Código:
substring(o.nrordemserv from 6 for 1) <> '' and

_________________
Jogo seu smartphone? Acesse o link e confira.
https://play.google.com/store/apps/details?id=br.com.couldsys.rockdrum
https://play.google.com/store/apps/details?id=br.com.couldsys.drumsetfree
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
adriano_servitec
Colaborador
Colaborador


Registrado: Sexta-Feira, 30 de Janeiro de 2004
Mensagens: 17618

MensagemEnviada: Qua Dez 05, 2012 2:15 pm    Assunto: Responder com Citação

Fiz assim

Código:
SELECT FIRST 1 ( CAST(o.nrordemserv as INTEGER) + 1 ) as n_doc
FROM ordemserv as o
WHERE
    o.nrordemserv > '50000' and
    substring(o.nrordemserv from 6 for 1) <> '' and
       not exists (select 1 from ordemserv as s
                where s.nrordemserv = CAST(CAST(o.nrordemserv as INTEGER) + 1 as varchar(10)))
ORDER BY o.nrordemserv


Parece que agora esta retornando acima de 50.000, mais parece que a select esta igual a anterior ?
_________________
Jogo seu smartphone? Acesse o link e confira.
https://play.google.com/store/apps/details?id=br.com.couldsys.rockdrum
https://play.google.com/store/apps/details?id=br.com.couldsys.drumsetfree
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
imex
Moderador
Moderador


Registrado: Sexta-Feira, 7 de Janeiro de 2011
Mensagens: 11666

MensagemEnviada: Qua Dez 05, 2012 2:31 pm    Assunto: Responder com Citação

A primeira query ficaria assim:

Código:
SELECT FIRST 1 ( CAST(o.nrordemserv as INTEGER) + 1 ) as n_doc
FROM ordemserv as o
WHERE
    o.nrordemserv > '50000' and
    substring(o.nrordemserv from 5 for 1) <> '' and
    not exists (select 1 from ordemserv as s
                where s.nrordemserv = CAST(CAST(o.nrordemserv as INTEGER) + 1 as varchar(10)))
ORDER BY o.nrordemserv


e a segunda assim:

Código:
SELECT FIRST 1 ( CAST(o.nrordemserv as INTEGER) + 1 ) as n_doc
FROM ordemserv as o
WHERE
    o.nrordemserv >= '100000' and
    substring(o.nrordemserv from 6 for 1) <> '' and
    not exists (select 1 from ordemserv as s
                where s.nrordemserv = CAST(CAST(o.nrordemserv as INTEGER) + 1 as varchar(10)))
ORDER BY o.nrordemserv


Espero que ajude.
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
adriano_servitec
Colaborador
Colaborador


Registrado: Sexta-Feira, 30 de Janeiro de 2004
Mensagens: 17618

MensagemEnviada: Qua Dez 05, 2012 2:44 pm    Assunto: Responder com Citação

imex escreveu:
A primeira query ficaria assim:

Código:
SELECT FIRST 1 ( CAST(o.nrordemserv as INTEGER) + 1 ) as n_doc
FROM ordemserv as o
WHERE
    o.nrordemserv > '50000' and
    substring(o.nrordemserv from 5 for 1) <and>= '100000' and
    substring(o.nrordemserv from 6 for 1) <> '' and
    not exists (select 1 from ordemserv as s
                where s.nrordemserv = CAST(CAST(o.nrordemserv as INTEGER) + 1 as varchar(10)))
ORDER BY o.nrordemserv


Espero que ajude.
Tem que rodar as duas sql?

Fiz o teste só com a qual eu postei e retornou 50002 que era o proximo depois do 50.000
_________________
Jogo seu smartphone? Acesse o link e confira.
https://play.google.com/store/apps/details?id=br.com.couldsys.rockdrum
https://play.google.com/store/apps/details?id=br.com.couldsys.drumsetfree
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
imex
Moderador
Moderador


Registrado: Sexta-Feira, 7 de Janeiro de 2011
Mensagens: 11666

MensagemEnviada: Qua Dez 05, 2012 2:57 pm    Assunto: Responder com Citação

Teria que rodar a primeira; se tiver algum código disponível entre 50.000 e 99.999 ela vai retornar o código, mas se não tiver ela não vai retornar nada, sendo que neste caso teria que rodar a segunda query para procurar algum código entre 100.000 e 999.999.
Acho que não tem como juntar as duas sem o Cast por causa da ordenação do campo varchar. E com o Cast ficou lento...
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
adriano_servitec
Colaborador
Colaborador


Registrado: Sexta-Feira, 30 de Janeiro de 2004
Mensagens: 17618

MensagemEnviada: Qua Dez 05, 2012 3:44 pm    Assunto: Responder com Citação

imex escreveu:
Teria que rodar a primeira; se tiver algum código disponível entre 50.000 e 99.999 ela vai retornar o código, mas se não tiver ela não vai retornar nada, sendo que neste caso teria que rodar a segunda query para procurar algum código entre 100.000 e 999.999.
Acho que não tem como juntar as duas sem o Cast por causa da ordenação do campo varchar. E com o Cast ficou lento...
Hum no caso então preciso criar duas funções, com result for = 0 executa a segunda function, é isso?
_________________
Jogo seu smartphone? Acesse o link e confira.
https://play.google.com/store/apps/details?id=br.com.couldsys.rockdrum
https://play.google.com/store/apps/details?id=br.com.couldsys.drumsetfree
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
imex
Moderador
Moderador


Registrado: Sexta-Feira, 7 de Janeiro de 2011
Mensagens: 11666

MensagemEnviada: Qua Dez 05, 2012 4:01 pm    Assunto: Responder com Citação

Acho que pode ficar tudo dentro da mesma função. Ex:

Código:
  with aqry do
  begin
    close;
    SQL.clear;
    SQL.Text := ' SELECT ( MAX( CAST(nrordemserv as INTEGER) ) + 1 )  as n_doc '+
                '   FROM ordemserv WHERE nrordemserv < 999999 ';
    Open;
    if FieldByName('n_doc').AsInteger = 999999 then
      begin
        // configura a query de 50.000 a 99.999
        Open;
        if IsEmpty then
          begin
            // configura a query de 100.000 a 999.999
            Open;
            if IsEmpty then
                Result := 0 // ou outro valor a retornar quando não encontrou código disponível
            else
                Result := FieldByName('n_doc').AsInteger;
          end
        else
            Result := FieldByName('n_doc').AsInteger;
      end
    else
        Result := FieldByName('n_doc').AsInteger;
  end;


Espero que ajude.
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
adriano_servitec
Colaborador
Colaborador


Registrado: Sexta-Feira, 30 de Janeiro de 2004
Mensagens: 17618

MensagemEnviada: Qua Dez 05, 2012 4:20 pm    Assunto: Responder com Citação

imex escreveu:
Acho que pode ficar tudo dentro da mesma função. Ex:

Código:
  with aqry do
  begin
    close;
    SQL.clear;
    SQL.Text := ' SELECT ( MAX( CAST(nrordemserv as INTEGER) ) + 1 )  as n_doc '+
                '   FROM ordemserv WHERE nrordemserv < 999999 ';
    Open;
    if FieldByName('n_doc').AsInteger = 999999 then
      begin
        // configura a query de 50.000 a 99.999
        Open;
        if IsEmpty then
          begin
            // configura a query de 100.000 a 999.999
            Open;
            if IsEmpty then
                Result := 0 // ou outro valor a retornar quando não encontrou código disponível
            else
                Result := FieldByName('n_doc').AsInteger;
          end
        else
            Result := FieldByName('n_doc').AsInteger;
      end
    else
        Result := FieldByName('n_doc').AsInteger;
  end;


Espero que ajude.
Peraí, agora que não entendi mesmo, o select não seria o outro que vc mostrou?

Fiquei confuso, primeiro vc diz pra rodar os dois selects, agora monta o select da forma do primeiro do post?

Obrigado Imex.
_________________
Jogo seu smartphone? Acesse o link e confira.
https://play.google.com/store/apps/details?id=br.com.couldsys.rockdrum
https://play.google.com/store/apps/details?id=br.com.couldsys.drumsetfree
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
imex
Moderador
Moderador


Registrado: Sexta-Feira, 7 de Janeiro de 2011
Mensagens: 11666

MensagemEnviada: Qua Dez 05, 2012 4:42 pm    Assunto: Responder com Citação

É que no post onde você reativou o tópico você disse:

Citação:
Quando chegar neste 999.999 buscar o proximo numero inferior a ele ...


então entendi que você quer

a) buscar o último código
b) se o último código for menor que 999.999 blz, mas se for igual a 999.999 buscar o primeiro disponível acima de 50.000
c) para buscar o primeiro disponível sugeri uma query para 50.001 a 99.999 e outra para 100.000 a 999.999; se a primeira já retornar um código blz, se não retornar é necessário partir para a outra

A não ser que você não queira mais buscar primeiro o último código; neste caso começaria pela query para 50.001 a 99.999. Blz?
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
adriano_servitec
Colaborador
Colaborador


Registrado: Sexta-Feira, 30 de Janeiro de 2004
Mensagens: 17618

MensagemEnviada: Qua Dez 05, 2012 6:22 pm    Assunto: Responder com Citação

imex escreveu:
É que no post onde você reativou o tópico você disse:

Citação:
Quando chegar neste 999.999 buscar o proximo numero inferior a ele ...


então entendi que você quer

a) buscar o último código
b) se o último código for menor que 999.999 blz, mas se for igual a 999.999 buscar o primeiro disponível acima de 50.000
c) para buscar o primeiro disponível sugeri uma query para 50.001 a 99.999 e outra para 100.000 a 999.999; se a primeira já retornar um código blz, se não retornar é necessário partir para a outra

A não ser que você não queira mais buscar primeiro o último código; neste caso começaria pela query para 50.001 a 99.999. Blz?
A sim agora que vi seus comentários
// configura a query de 50.000 a 99.999

Vou fazer aqui, valeu amigo
_________________
Jogo seu smartphone? Acesse o link e confira.
https://play.google.com/store/apps/details?id=br.com.couldsys.rockdrum
https://play.google.com/store/apps/details?id=br.com.couldsys.drumsetfree
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
adriano_servitec
Colaborador
Colaborador


Registrado: Sexta-Feira, 30 de Janeiro de 2004
Mensagens: 17618

MensagemEnviada: Qua Dez 05, 2012 9:21 pm    Assunto: Responder com Citação

adriano_servitec escreveu:
imex escreveu:
É que no post onde você reativou o tópico você disse:

Citação:
Quando chegar neste 999.999 buscar o proximo numero inferior a ele ...


então entendi que você quer

a) buscar o último código
b) se o último código for menor que 999.999 blz, mas se for igual a 999.999 buscar o primeiro disponível acima de 50.000
c) para buscar o primeiro disponível sugeri uma query para 50.001 a 99.999 e outra para 100.000 a 999.999; se a primeira já retornar um código blz, se não retornar é necessário partir para a outra

A não ser que você não queira mais buscar primeiro o último código; neste caso começaria pela query para 50.001 a 99.999. Blz?
A sim agora que vi seus comentários
// configura a query de 50.000 a 99.999

Vou fazer aqui, valeu amigo
Imex parece que deu certo, vou mandar para o setor de testes para ver se esta OK.

Obrigado amigo
_________________
Jogo seu smartphone? Acesse o link e confira.
https://play.google.com/store/apps/details?id=br.com.couldsys.rockdrum
https://play.google.com/store/apps/details?id=br.com.couldsys.drumsetfree
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
Mostrar os tópicos anteriores:   
Novo Tópico   Responder Mensagem    ActiveDelphi - Índice do Fórum -> Banco de Dados Todos os horários são GMT - 3 Horas
Ir à página Anterior  1, 2, 3  Próximo
Página 2 de 3

 
Ir para:  
Enviar Mensagens Novas: Proibido.
Responder Tópicos Proibido
Editar Mensagens: Proibido.
Excluir Mensagens: Proibido.
Votar em Enquetes: Proibido.


Powered by phpBB © 2001, 2005 phpBB Group
Traduzido por: Suporte phpBB