none
Criar Procedure Buscar Próximo Registro até o chegar o ultimo Registro e depois Retorna ao Primeiro RRS feed

  • Pergunta

  • Boa tarde a Todos,

    Tenho que criar uma procedure aonde tenho que percorrer os registros de uma tabela, tenho duas tabelas TbdMotorista e TbdServico

    No caso eu vou adicionando os motoristas na TbdServico por ordem de cadastro da tabela TbdMotorista e dependendo do seu Status, se o próximo motorista estiver inativo pula para o próximo que estiver ativo.

    No caso tenho 150 registros eu gostaria que quando chegasse no ultimo registro voltasse para o primeiro registro , tentei algumas coisas mais não obtive sucesso.

    A ideia que eu tenho seria essa:

    TbdServico

    id_Motorista

    1

    2

    18

    .

     150

    1

    2

    18

    .

    .

    150

    Assim por diante!

    Tentei o seguinte esquema e consegui o buscar próximo registro!

    ;with 
    TbdSeq as (
    SELECT id_Motorista,
           row_number() over (order by id_Motorista) as Seq
      from TbdMotorista where cd_StatusMotorista <> 1
    )
    SELECT T1.id_Motorista , T2.id_Motorista
      from TbdSeq as T1 inner join
           TbdSeq as T2 on T1.Seq = T2.Seq-1;

    Desde já Muito Obrigado!

    segunda-feira, 6 de outubro de 2014 20:53

Respostas

  • Você quer que seja retornado apenas o id do próximo motorista?

    Experimente fazer um teste:

    declare @TbdMotorista table
    (id_Motorista int, nm_Motorista varchar(40), cd_StatusMotorista int);
    
    insert into @TbdMotorista values
    (5, 'Marcio', 0),
    (6, 'Luiz', 0),
    (7, 'Robson', 0),
    (8, 'Carlos', 1);
    
    declare @TbdChapaVazio table
    (id_ChapaVazio int, id_MotoristaVazio int);
    
    insert into @TbdChapaVazio values
    (1, 5),
    (2, 6),
    (3, 7),
    (4, null),
    (5, null),
    (6, null),
    (7, null),
    (8, null),
    (9, null),
    (10, null);
    
    declare @TbdServico table
    (id_Servico int, id_ChapaVazio int);
    
    insert into @TbdServico values
    (10, 1);
    
    select
        coalesce
            ((select top(1) c.id_MotoristaVazio
              from @TbdChapaVazio as c
              inner join @TbdMotorista as m
                  on m.id_Motorista = c.id_MotoristaVazio
              where
                  c.id_MotoristaVazio is not null and
                  c.id_ChapaVazio > (select top(1) s.id_ChapaVazio
                                     from @TbdServico as s
                                     order by s.id_Servico desc) and
                  m.cd_StatusMotorista <> 1),
             (select top(1) c.id_MotoristaVazio
              from @TbdChapaVazio as c
              where
                  c.id_MotoristaVazio is not null)) as id_Motorista;
    

    Espero que ajude.


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

    terça-feira, 7 de outubro de 2014 17:59
  • Fiz os testes e obtive o resultado desejado:

    declare @TbdMotorista table
    (id_Motorista int, nm_Motorista varchar(40), cd_StatusMotorista int);
    
    insert into @TbdMotorista values
    (5, 'Marcio', 0),
    (6, 'Luiz', 0),
    (7, 'Robson', 0),
    (8, 'Carlos', 1);
    
    declare @TbdChapaVazio table
    (id_ChapaVazio int, id_MotoristaVazio int);
    
    insert into @TbdChapaVazio values
    (1, 5),
    (2, 6),
    (3, 7),
    (4, null),
    (5, null),
    (6, null),
    (7, null),
    (8, null),
    (9, null),
    (10, null);
    
    declare @TbdServico table
    (id_Servico int, id_ChapaVazio int);
    
    insert into @TbdServico values
    (10, 1),
    (11, 2);
    
    select
        coalesce
            ((select top(1) c.id_MotoristaVazio
              from @TbdChapaVazio as c
              inner join @TbdMotorista as m
                  on m.id_Motorista = c.id_MotoristaVazio
              where
                  c.id_MotoristaVazio is not null and
                  c.id_ChapaVazio > (select top(1) s.id_ChapaVazio
                                     from @TbdServico as s
                                     order by s.id_Servico desc) and
                  m.cd_StatusMotorista <> 1),
             (select top(1) c.id_MotoristaVazio
              from @TbdChapaVazio as c
              where
                  c.id_MotoristaVazio is not null)) as id_Motorista;

    O script acima retornou o id_motorista 7.

    Espero que ajude.


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

    terça-feira, 7 de outubro de 2014 19:53
  • Valeu pelo Suporte Gapimex,

    Descobri o problema, não estava no seu script e sim que eu inseri os dados manualmente direto na TbdServico e no caso eu coloquei o mesmo id_ChapaVazio nos id_Motoristas por isso estava me retornando o ultimo valor inserido da TbsServico.

    Outra coisa eu não posto com muita frequência e no caso eu tenho que marcar a resposta como útil, eu marco uma ou as que achei útil? 

    Desde já Muito Obrigado!

    terça-feira, 7 de outubro de 2014 20:23

Todas as Respostas

  • Boa noite,

    Marcio, não consegui entender a sua questão. Acho melhor você postar uma pequena amostra de dados das 2 tabelas e o respectivo resultado esperado para facilitar o entendimento.


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

    segunda-feira, 6 de outubro de 2014 21:54
  • Bom dia Gapimex,

    Obrigado pelo retorno!

    No caso estou desenvolvendo uma aplicação aonde tenho que escalar motoristas que estão com seu status ativo, e que tenha um numero de serviço para ser escalado, esse numero de serviço  fica na TbdChapa, essa tabela tem disponível 150 números de chapas, o que pode ocorrer, ter menos motoristas para o numero de chapas disponíveis ou ter mais motoristas do que numero de chapas disponíveis esperando que uma chapa fique disponível.

    O que eu preciso é criar uma procedure que busque o próximo motorista que vai ser escalado para o serviço e seja inserido na TbdServico.

    Tipo a ideia seria assim, o motorista 1 com numero de chapa 1 e com seu status ativo e quando executo a procedure traga esse motorista, quando executo a procedure novamente traria o motorista 2 com a chapa 2 e com o status do motorista ativo, suponho que o motorista 3 da chapa 3 e com seu status inativo então pularia para o motorista 4 da chapa 4 e seu status ativo.

    Quando o ultimo motorista exemplo: motorista 150 da chapa 150 e seu status ativo for inserido na TbdServico o proximo motorista a ser escalado seria o motorista 1 da chapa e seu status ativo!

    Segue uma amostra dos dados 

    TbdMotorista

    TbdChapaVazio


    terça-feira, 7 de outubro de 2014 13:06
  • Segue o restante dos dados

    TbdServico

    Desde já Muito Obrigado!

    terça-feira, 7 de outubro de 2014 13:07
  • Marcio, não sei se entendi corretamente, mas experimente fazer um teste com o script abaixo:

    declare @TbdMotorista table
    (id_Motorista int, nm_Motorista varchar(40), cd_StatusMotorista int);
    
    insert into @TbdMotorista values
    (5, 'Marcio', 0),
    (6, 'Luiz', 0),
    (7, 'Robson', 0),
    (8, 'Carlos', 1);
    
    declare @TbdChapaVazio table
    (id_ChapaVazio int, id_MotoristaVazio int);
    
    insert into @TbdChapaVazio values
    (1, 5),
    (2, 6),
    (3, 7),
    (4, null),
    (5, null),
    (6, null),
    (7, null),
    (8, null),
    (9, null),
    (10, null);
    
    declare @QtdMotoristas int;
    set @QtdMotoristas = (select COUNT(*) from @TbdMotorista where cd_StatusMotorista <> 1);
    
    with
        CTE_M as
        (
            select
                *,
                ROW_NUMBER() OVER(ORDER BY id_Motorista) as RN_Motorista
            from @TbdMotorista
            where
                cd_StatusMotorista <> 1
        ),
        
        CTE_C as
        (
            select
                *,
                ROW_NUMBER() OVER(ORDER BY id_ChapaVazio) as RN_ChapaVazio
            from @TbdChapaVazio
            where
                id_MotoristaVazio is null
        )
    
    select
        *
    from CTE_C as c
    inner join CTE_M as m
        on 
            (m.RN_Motorista = c.RN_ChapaVazio % @QtdMotoristas) or
            (m.RN_Motorista = @QtdMotoristas and c.RN_ChapaVazio % @QtdMotoristas = 0)
    order by
        id_ChapaVazio

    Espero que ajude.


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

    terça-feira, 7 de outubro de 2014 14:51
  • Obrigado pelo Retorno Gapimex,

    Testei mais não me atendeu ("Mas esse script eu vou usar em outra coisa nesse projeto (rs)") oque eu preciso é tipo na TbdServico

    Eu tenho cadastrado um motorista que realizou o serviço 

    Eu preciso que o próximo motorista seja o id_ChapaVazio seja 2 do motorista ativo, caso o motorista do id_ChapaVazio = 2 esteja inativo ou o id_ChapaVazio não pertencesse a nenhum motorista então, pularia para o próximo Motorista do id_ChapaVazio = 3 do Motorista ativo.

    Ai me mostraria só o id _Motorista!

    id_Motorista = 7

    No caso TbdChapaVazio teria 150 registros quando rodasse todos os registro voltaria para o primeiro!

    Muito Obrigado pelo retorno!

     

    terça-feira, 7 de outubro de 2014 15:58
  • Você quer que seja retornado apenas o id do próximo motorista?

    Experimente fazer um teste:

    declare @TbdMotorista table
    (id_Motorista int, nm_Motorista varchar(40), cd_StatusMotorista int);
    
    insert into @TbdMotorista values
    (5, 'Marcio', 0),
    (6, 'Luiz', 0),
    (7, 'Robson', 0),
    (8, 'Carlos', 1);
    
    declare @TbdChapaVazio table
    (id_ChapaVazio int, id_MotoristaVazio int);
    
    insert into @TbdChapaVazio values
    (1, 5),
    (2, 6),
    (3, 7),
    (4, null),
    (5, null),
    (6, null),
    (7, null),
    (8, null),
    (9, null),
    (10, null);
    
    declare @TbdServico table
    (id_Servico int, id_ChapaVazio int);
    
    insert into @TbdServico values
    (10, 1);
    
    select
        coalesce
            ((select top(1) c.id_MotoristaVazio
              from @TbdChapaVazio as c
              inner join @TbdMotorista as m
                  on m.id_Motorista = c.id_MotoristaVazio
              where
                  c.id_MotoristaVazio is not null and
                  c.id_ChapaVazio > (select top(1) s.id_ChapaVazio
                                     from @TbdServico as s
                                     order by s.id_Servico desc) and
                  m.cd_StatusMotorista <> 1),
             (select top(1) c.id_MotoristaVazio
              from @TbdChapaVazio as c
              where
                  c.id_MotoristaVazio is not null)) as id_Motorista;
    

    Espero que ajude.


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

    terça-feira, 7 de outubro de 2014 17:59
  • Obrigado Gapimex,

    Só falta um detalhe que eu não consegui achar o problema, inseri um serviço na TbdServiço com o próximo Motorista do id_Motorista = 6, realizai a consulta novamente e o correto seria mostrar o próximo id_motorista = 7 mais esta aparecendo o id_motorista = 6.

    No caso os id_Motorista 5,6,7 estão todos ativos mais quando eu inativo o id_Motorista = 6 ele pula para o id_Motorista = 7.

    De resto está do jeito que eu queria!

    Muito obrigado!

    terça-feira, 7 de outubro de 2014 19:32
  • Fiz os testes e obtive o resultado desejado:

    declare @TbdMotorista table
    (id_Motorista int, nm_Motorista varchar(40), cd_StatusMotorista int);
    
    insert into @TbdMotorista values
    (5, 'Marcio', 0),
    (6, 'Luiz', 0),
    (7, 'Robson', 0),
    (8, 'Carlos', 1);
    
    declare @TbdChapaVazio table
    (id_ChapaVazio int, id_MotoristaVazio int);
    
    insert into @TbdChapaVazio values
    (1, 5),
    (2, 6),
    (3, 7),
    (4, null),
    (5, null),
    (6, null),
    (7, null),
    (8, null),
    (9, null),
    (10, null);
    
    declare @TbdServico table
    (id_Servico int, id_ChapaVazio int);
    
    insert into @TbdServico values
    (10, 1),
    (11, 2);
    
    select
        coalesce
            ((select top(1) c.id_MotoristaVazio
              from @TbdChapaVazio as c
              inner join @TbdMotorista as m
                  on m.id_Motorista = c.id_MotoristaVazio
              where
                  c.id_MotoristaVazio is not null and
                  c.id_ChapaVazio > (select top(1) s.id_ChapaVazio
                                     from @TbdServico as s
                                     order by s.id_Servico desc) and
                  m.cd_StatusMotorista <> 1),
             (select top(1) c.id_MotoristaVazio
              from @TbdChapaVazio as c
              where
                  c.id_MotoristaVazio is not null)) as id_Motorista;

    O script acima retornou o id_motorista 7.

    Espero que ajude.


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

    terça-feira, 7 de outubro de 2014 19:53
  • Valeu pelo Suporte Gapimex,

    Descobri o problema, não estava no seu script e sim que eu inseri os dados manualmente direto na TbdServico e no caso eu coloquei o mesmo id_ChapaVazio nos id_Motoristas por isso estava me retornando o ultimo valor inserido da TbsServico.

    Outra coisa eu não posto com muita frequência e no caso eu tenho que marcar a resposta como útil, eu marco uma ou as que achei útil? 

    Desde já Muito Obrigado!

    terça-feira, 7 de outubro de 2014 20:23
  • Que bom que ajudou. Sobre marcar a resposta, fica a seu critério, mas pelo menos nesse caso acredito que uma delas foi a principal.

    Abs


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

    terça-feira, 7 de outubro de 2014 21:06