Pular para o conteúdo
Visualizando 10 posts - 1 até 10 (de 10 do total)
  • Autor
    Posts
  • #96035
    luan
    Participante

      Boa noite galera, meu primeiro post aqui, estou com uma duvida que não achei ainda uma solução, sou meio iniciante em PL/SQL, trabalho mais com desenvolvimento java…

      Vamos lá, a dúvida é a seguinte:
      tenho a seguinte query:

      SELECT DISTINCT A.DTAGENDA
      FROM AGENDA_DETAIL A
      JOIN AGENDA_DADO B ON ( A.IDAGENDADADO = B.IDAGENDADADO )
      JOIN AGENDA_SALA C ON ( B.IDSALA = C.IDSALA )
      WHERE A.FLAG = ‘DISPONIVEL’ AND
      A.STATUS = ‘ATIVADO’ AND
      C.IDPRESTADORDETAIL = 1421 AND
      B.IDMEDICOESPECIALIDADE = 400 AND
      B.IDTUSS IN(2810,2825);

      por exemplo nesse caso, a consulta me retorna o dia 20/09/2010, mas para esse dia eu tenho apenas disponível agenda para o código 2810 mas não para o 2825.
      precisava retornar os dias apenas que tenha agenda disponivel para os 2 codigos no mesmo dia e não apenas para um ou outro.

      Não sei se consegui explicar direito.

      Muito obrigado galera, grande abraço!

      #96036
      burga
      Participante

        Existem várias maneiras diferentes de se fazer isto, segue três delas:

        SELECT DISTINCT DTAGENDA
        FROM (
        SELECT A.DTAGENDA
        FROM AGENDA_DETAIL A
        JOIN AGENDA_DADO B ON ( A.IDAGENDADADO = B.IDAGENDADADO )
        JOIN AGENDA_SALA C ON ( B.IDSALA = C.IDSALA )
        WHERE A.FLAG = 'DISPONIVEL' AND
        A.STATUS = 'ATIVADO' AND
        C.IDPRESTADORDETAIL = 1421 AND
        B.IDMEDICOESPECIALIDADE = 400 AND
        B.IDTUSS = 2810

        INTERSECT

        SELECT A.DTAGENDA
        FROM AGENDA_DETAIL A
        JOIN AGENDA_DADO B ON ( A.IDAGENDADADO = B.IDAGENDADADO )
        JOIN AGENDA_SALA C ON ( B.IDSALA = C.IDSALA )
        WHERE A.FLAG = 'DISPONIVEL' AND
        A.STATUS = 'ATIVADO' AND
        C.IDPRESTADORDETAIL = 1421 AND
        B.IDMEDICOESPECIALIDADE = 400 AND
        B.IDTUSS = 2825);

        ou

        SELECT DISTINCT A.DTAGENDA
        FROM AGENDA_DETAIL A
        WHERE EXISTS (
        SELECT 1
        FROM AGENDA_DETAIL D
        JOIN AGENDA_DADO B ON ( D.IDAGENDADADO = B.IDAGENDADADO )
        JOIN AGENDA_SALA C ON ( B.IDSALA = C.IDSALA )
        WHERE A.FLAG = 'DISPONIVEL' AND
        D.STATUS = 'ATIVADO' AND
        C.IDPRESTADORDETAIL = 1421 AND
        B.IDMEDICOESPECIALIDADE = 400 AND
        B.IDTUSS = 2810 AND
        A.DTAGENDA = D.DTAGENDA)
        AND EXISTS (
        SELECT 1
        FROM AGENDA_DETAIL D
        JOIN AGENDA_DADO B ON ( D.IDAGENDADADO = B.IDAGENDADADO )
        JOIN AGENDA_SALA C ON ( B.IDSALA = C.IDSALA )
        WHERE A.FLAG = 'DISPONIVEL' AND
        D.STATUS = 'ATIVADO' AND
        C.IDPRESTADORDETAIL = 1421 AND
        B.IDMEDICOESPECIALIDADE = 400 AND
        B.IDTUSS = 2825 AND
        A.DTAGENDA = D.DTAGENDA);

        ou

        SELECT DTAGENDA
        FROM (
        SELECT DISTINCT A.DTAGENDA, B.IDTUSS
        FROM AGENDA_DETAIL A
        JOIN AGENDA_DADO B ON ( A.IDAGENDADADO = B.IDAGENDADADO )
        JOIN AGENDA_SALA C ON ( B.IDSALA = C.IDSALA )
        WHERE A.FLAG = 'DISPONIVEL' AND
        A.STATUS = 'ATIVADO' AND
        C.IDPRESTADORDETAIL = 1421 AND
        B.IDMEDICOESPECIALIDADE = 400 AND
        (B.IDTUSS = 2810 OR B.IDTUSS = 2825))
        GROUP BY DTAGENDA
        HAVING COUNT(*) > 1;

        Não sei qual tem o pior custo, todas parecem ter um desempenho bem baixo… 😆

        #96040
        luan
        Participante

          Boa noite, opa valeu Burga, amanha no trampo eu testo e posto os resultados!

          Muito Obrigado

          Abraços

          #96042
          luan
          Participante

            Bom dia galera, valeu Burga, optei pela terceira opção que teve um desempenho melhor…
            A princípio o custo ficou em 11380, mas depois de criar 1 index o custo caiu para 11 executado em 0,37400001 segundos ..

            Muito obrigado

            Abraços!

            #96044
            jspaulonci
            Participante

              Parabens Burga

              #96055
              luan
              Participante

                Boa tarde galera, surgiu uma outra dúvida que talvez seja util para outros usuários também, seguinte eu preciso gerar um ‘ where ‘ dinamicamente..

                procedure finddiaslivres(
                P_IDPRESTADORDETAIL IN PRESTADOR_DETAIL.IDDETAIL%TYPE,
                P_IDMEDICOESPECIALIDADE IN AGENDA_DADO.IDMEDICOESPECIALIDADE%TYPE,
                P_ESPECIALIDADE IN AGENDA_DADO.IDMEDICOESPECIALIDADE%TYPE,
                P_ARRAYIDTUSS IN NUMBER_ARRAY,
                P_CURSOR OUT NOCOPY TYPES.REF_CURSOR)AS

                V_CONTADOR NUMBER := 0;
                V_I NUMBER := 0;
                V_QUERYCOMPL VARCHAR2(100);

                BEGIN

                V_CONTADOR := P_ARRAYIDTUSS.COUNT;

                WHILE ( V_I V_I ) THEN
                V_QUERYCOMPL := V_QUERYCOMPL || ‘ OR B.IDTUSS =’;
                END IF;
                END LOOP;

                IF ( P_IDPRESTADORDETAIL > 0 AND P_IDMEDICOESPECIALIDADE > 0 ) THEN

                OPEN P_CURSOR FOR
                  SELECT DTAGENDA
                    FROM (
                      SELECT DISTINCT A.DTAGENDA, B.IDTUSS
                      FROM AGENDA_DETAIL A
                        JOIN AGENDA_DADO B ON ( A.IDAGENDADADO = B.IDAGENDADADO )
                        JOIN AGENDA_SALA C ON ( B.IDSALA = C.IDSALA )
                      WHERE A.FLAG = 'DISPONIVEL' AND
                        A.STATUS = 'ATIVADO' AND
                        C.IDPRESTADORDETAIL = 1421 AND
                        B.IDMEDICOESPECIALIDADE = 400 AND
                        B.IDTUSS = V_QUERYCOMPL)
                    GROUP BY DTAGENDA
                    HAVING COUNT(*) > 1; 
                

                os idtuss eu enviei para procedure como array pois não sei a quantidade que será escolhida pelo usuário, mas acontece o seguinte, quando eu itero ele e vou concatenando os OR B.IDTUSS + a posição no array que seria outro numero, quando a query é executada da o erro:
                ORA-01722: número inválido.
                Creio que seja porque a variavel v_querycompl é um varchar, e o B.IDTUSS seria um number, mas nesse caso como eu faria para gerar isso dinamicamente?

                Muito obrigado novamente…

                #96056
                burga
                Participante

                  Na verdade você deve montar a consulta inteira dentro do V_QUERYCOMPL, como um varchar2 e depois chamá-la no OPEN P_CURSOR FOR:

                  OPEN P_CURSOR FOR V_QUERYCOMPL;
                  LOOP
                  FETCH P_CURSOR INTO ...;
                  EXIT WHEN P_CURSOR%NOTFOUND;
                  -- seu processamento
                  END LOOP;

                  #96058
                  luan
                  Participante

                    Obrigado novamente Burga, vc é fera, que bom ter o privilégio de participar de um forum com experts como esse….

                    Agora está 100% Smile, valeu mesmo…

                    Abraços!

                    #96062
                    burga
                    Participante

                      Só lembrando que SQL dinâmico é quase um sinônimo de performance ruim, pois na maioria das vezes o Oracle vai ter que executar o hard parsing do seu SQL dinâmico, então é sempre bom (se possível) tentar evitar seu uso.

                      Outra coisa, eu não prestei muita atenção no seu código e foquei mais na solução do erro, agora que vi melhor, percebi que a consulta que você está gerando é a mesma do começo do tópico, então já vou apontar dois problemas no código que você postou, um de semântica e outro de lógica:

                      OPEN P_CURSOR FOR
                      SELECT DTAGENDA
                      FROM (
                      SELECT DISTINCT A.DTAGENDA, B.IDTUSS
                      FROM AGENDA_DETAIL A
                      JOIN AGENDA_DADO B ON ( A.IDAGENDADADO = B.IDAGENDADADO )
                      JOIN AGENDA_SALA C ON ( B.IDSALA = C.IDSALA )
                      WHERE A.FLAG = ‘DISPONIVEL’ AND
                      A.STATUS = ‘ATIVADO’ AND
                      C.IDPRESTADORDETAIL = 1421 AND
                      B.IDMEDICOESPECIALIDADE = 400 AND
                      B.IDTUSS = V_QUERYCOMPL)
                      GROUP BY DTAGENDA
                      HAVING COUNT(*) > 1;

                      Um dos problemas é que você não colocou as condições com B.IDTUSS entre parênteses, sem isso a consulta não vai ser executada da forma que você deseja, uma forma simples de resolver isto é usar o IN ao invés de vários OR (ex.: B.IDTUSS IN (codigo1[,codigoN…]) )…

                      Outro problema é o HAVING COUNT() > 1, este caso serve apenas para quando você procura datas que possuem em dois IDTUSS, caso sejam três IDTUSS então deve ser HAVING COUNT() > 2, e para N IDTUSS diferentes seria HAVING COUNT(*) > (N-1);

                      #96103
                      luan
                      Participante

                        Perfeito burga, corrigi os problemas.
                        E muito obrigado novamente!!!!

                        Abs bom dia!

                      Visualizando 10 posts - 1 até 10 (de 10 do total)
                      • Você deve fazer login para responder a este tópico.