- Este tópico contém 1 resposta, 2 vozes e foi atualizado pela última vez 8 anos atrás por José Laurindo Chiappa.
-
AutorPosts
-
28 de outubro de 2016 às 7:43 pm #108490cristianParticipante
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 ASC28 de outubro de 2016 às 11:12 pm #108495José Laurindo ChiappaModeradorBem, 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 Eno 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 1014 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 13008 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 0SYSTEM:@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
-
AutorPosts
- Você deve fazer login para responder a este tópico.