Pular para o conteúdo
  • Este tópico contém 1 resposta, 2 vozes e foi atualizado pela última vez 8 anos atrás por Avatar photoJosé Laurindo Chiappa.
Visualizando 2 posts - 1 até 2 (de 2 do total)
  • Autor
    Posts
  • #108490
    Avatar de cristiancristian
    Participante

      Bom dia pessoal!
      Sou novo na parte de sintaxe SQL e preciso de um auxílio.
      Estou utilizando Oracle e estou com o seguinte problema:
      Preciso selecionar somente os pacientes (PAC.PAC_NOME) que fizeram respectivamente exames nas categorias C e E ( CTF.CTF_CATEG in ( ‘C’,’E’ ) ).
      Ocorre que o select está trazendo os pacientes que fizeram C e E mas também trás os que fizeram somente C e somente E. Como faço uma condição para trazer os pacientes que fizeram C e E respectivamente dentro da data informada?
      Segue o código que eu fiz:

      SELECT PAC.PAC_NOME,
      SMK.SMK_NOME,
      SUM ( SMM.SMM_QT ),
      CTF.CTF_CATEG
      FROM PAC, SMM, SMK, CTF, CNV CV, STR, ESP, OSM, ESM, PSV
      WHERE ( SMM.SMM_SFAT <> ‘C’ ) AND
      ( OSM.OSM_SERIE = SMM.SMM_OSM_SERIE ) AND
      ( OSM.OSM_NUM = SMM.SMM_OSM ) AND
      ( ( CV.CNV_COD = NVL ( SMM.SMM_CNV_COD, OSM.OSM_CNV ) ) ) AND
      ( STR.STR_COD = SMM.SMM_STR ) AND
      ( SMK.SMK_TIPO = SMM.SMM_TPCOD ) AND
      ( SMK.SMK_COD = SMM.SMM_COD ) AND
      ( SMK.SMK_TIPO = CTF.CTF_TIPO ) AND
      ( SMK.SMK_CTF = CTF.CTF_COD ) AND
      ( OSM.OSM_PAC = PAC.PAC_REG ) AND
      ( PSV.PSV_COD = SMM.SMM_MED ) AND
      ( ESM.ESM_MED = PSV.PSV_COD ) AND
      ( ESP.ESP_COD = ESM.ESM_ESP ) AND
      ( ESM.ESM_DEFAULT = ‘S’ ) AND
      ( CV.CNV_COD not in ( ‘ICB’,’44’ ) ) AND
      ( STR.STR_NOME not in ( ‘ICB’,’CEC’ ) ) AND
      ( CTF.CTF_CATEG in ( ‘C’,’E’ ) ) AND
      ( ESP.ESP_COD <> ‘ICB’ ) AND
      ( SMM.SMM_VLR > 0 ) AND
      ( SMM.SMM_COD not in ( ‘1AUX’,’2AUX’,’3AUX’ ) ) AND
      ( ( OSM.OSM_DTHR >= to_date ( ’01/10/2016 00:00′, ‘dd/mm/yyyy hh24:mi’ ) AND
      OSM.OSM_DTHR < to_date ( '27/10/2016 00:00', 'dd/mm/yyyy hh24:mi' ) ) ) GROUP BY PAC.PAC_NOME, SMK.SMK_NOME, CTF.CTF_CATEG ORDER BY PAC.PAC_NOME ASC

      #108495
      Avatar photoJosé Laurindo Chiappa
      Moderador

        Bem, seguinte : antes de palpitar , primeiro eu AVISO que tudo o que eu vou falar aqui é simplesmente provinha de conceito – de forma alguma estou preocupado com perfcormance, facilidade de manutenção, best practices, nadica, ok ?? Assim, Não Assuma que a resposta é Lei, e não saia usando sem alterações ANTES de entender os conceitos, yep ??? E outra coisa, o que vou mostra é ** UMA ** das maneiras, com certeza tem N outras …

        Muito bem : sim, corretamente vc indicou que vc está filtrando registros/linhas da tabela que ** OU ** possuem valor ‘C’ na coluna CTF_CATEG ** OU ** possuem valor ‘E’ – realmente é exatamente o que se obtém com :

        CTF.CTF_CATEG in ( ‘C’,’E’ )

        esse IN significa isso…. O que ocorre aí pelo que entendi é que agora vc quer estabelecer uma filtragem de dados ** ENTRE REGISTROS ** , ie, se vc tiver uma situação tipo :

        PAC_NOME SMK_NOME CATEG
        ——– ——– —–
        JOAO PULMO C
        JOSE PNEUMO C
        JOSE PNEUMO E

        no exemplo acima vc desejaria, logicamente falando, estabelecer uma validação INTER REGISTROS, ie, ‘transformar’ as duas linhas do JOSE em uma só, para que aí vc possa comparar dados – num RDBMS vc compara dados EM UM REGISTRO contra OUTRO REGISTRO apenas (ou OUTROS, via SUB-QUERY ou UNION)…

        Num caso desses, entre as N possibilidades pra se fazer isso (dá um look no manual Oracle de SQL para Analytics, UNION, JOINs, entre outros) eu sugiro vc criar para cada paciente uma coluna de ** SOMA ** não geral mas apenas dos registros do tipo C e uma outra Soma apenas dos pacientes com tipo E, depois vc filtra apenas onde coluna de soma C é igual a coluna de soma E….
        Essa soma “não-geral” vc faz com a função CASE… Como vc não nos dá um caso reproduzível (ie, com CREATE TABLES ** E ** com INSERTs pra gente botar dados nas tabelas) vou exemplificar com uma tabela de exemplo do Oracle, use uma lógica similar na sua query…
        No exemplo, tenho a seguinte tabela :

        SYSTEM:@XE:SQL>select * from scott.emp;

        EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
        ———- ———- ——— ———- ——— ———- ———- ———-
        7369 SMITH CLERK 7902 17-DEC-80 800 20
        7499 ALLEN SALESMAN 7698 20-FEB-81 1600 300 30
        7521 WARD SALESMAN 7698 22-FEB-81 1250 500 30
        7566 JONES MANAGER 7839 02-APR-81 2975 20
        7654 MARTIN SALESMAN 7698 28-SEP-81 1250 1400 30
        7698 BLAKE MANAGER 7839 01-MAY-81 2850 30
        7782 CLARK MANAGER 7839 09-JUN-81 2450 10
        7788 SCOTT ANALYST 7566 19-APR-87 3000 20
        7839 KING PRESIDENT 17-NOV-81 5000 10
        7844 TURNER SALESMAN 7698 08-SEP-81 1500 0 30
        7876 ADAMS CLERK 7788 23-MAY-87 1100 20
        7900 JAMES CLERK 7698 03-DEC-81 950 30
        7902 FORD ANALYST 7566 03-DEC-81 3000 20
        7934 MILLER CLERK 7782 23-JAN-82 1300 10

        14 rows selected.

        ==> Vou ter uma Condição de Filtro que só me traz DEPTNO in (10, 20) :

        SYSTEM:@XE:SQL>select deptno, empno, sal from scott.emp where deptno in (10,20);

        DEPTNO EMPNO SAL
        ———- ———- ———-
        20 7369 800
        20 7566 2975
        10 7782 2450
        20 7788 3000
        10 7839 5000
        20 7876 1100
        20 7902 3000
        10 7934 1300

        8 rows selected.

        ==> Digamos que quero fazer um SUM de Salário pro Departamento 10 e um SUM de salário pro Departamento 20 – primeira coisa, pra ‘transformar’ os N registros de cada departamento numa linha só E dazer essa linha ter uma Soma, eu TENHO que AGRUPAR os registros, usarei o GROUP BY aqui pra isso (veja no manual Oracle de SQL mais refs sobre Agrupamento, Funçoes de SOma e Contagem e cláusula GROUP BY)….
        veja também que há OUTRAS maneiras mas eu vou usar a técnica de FROM QUERY, ie, vou fazer o meu SELECT com GROUP BY ler os dados da minha query anterior, colocando ela numa cláusula de FROM. Fica assim :

        SYSTEM:@XE:SQL>select deptno, sum(case when deptno=10 then sal else 0 end) SOMA_DEPT10,
        2 sum(case when deptno=20 then sal else 0 end) SOMA_DEPTO20
        3 FROM (
        4 select deptno, empno, sal from scott.emp where deptno in (10,20)
        5 )
        6* GROUP BY deptno;

        ==> O resultado é o que espero :

        DEPTNO SOMA_DEPT10 SOMA_DEPTO20
        ———- ———– ————
        20 0 10875
        10 8750 0

        SYSTEM:@XE:SQL>

        ==> Eu ** acho ** que vc pode usar esse tipo de Técnica pra fazer teu resultset ter, para cada linha final, uma coluna com o nome do paciente, uma com o exame , uma com a soma de exames para tipo C e uma com a soma de exames para tipo E – aí SIM, a informação estando na mesma linha, vc pode a usar num WHERE, tipo :

        SELECT colunasdesejadas FROM (queriesquetrazempaciente, exame, soma de tipo C e soma de tipo E)
        WHERE colunasomadotipoC > 0
        AND colunasomadotipoE > 0;

        okdoc ?? Tenta aí aplicar esse tipo de técnica, e se não conseguir mostra o que vc tentou, manda os CREATE TABLEs e uns INSERTs pros dados que a gente pode tentar dar um exemplo mais concreto, com os teus dados…

        Abraços,

        José Laurindo Chiappa

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