maomelov Posted September 27, 2012 at 11:14 PM Report #476862 Posted September 27, 2012 at 11:14 PM Boa Noite Precisava de escrever um query para determinar, para cada empregado da tabela EMP, quanto é que ele ganha a menos que o empregado que mais ganha. Por exemplo, se o empregado ganha 100 e o máximo salário é 1000, então o query deve listar 900. EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO 7369 SMITH CLERK 7902 1980-12-17 800 20 7499 ALLEN SALESMAN 7698 1981-02-20 1600 300 30 7521 WARD SALESMAN 7698 1981-02-22 1250 500 30 7566 JONES MANAGER 7839 1981-04-02 2975 20 7654 MARTIN SALESMAN 7698 1981-09-28 1250 1400 30 7698 BLAKE MANAGER 7839 1981-05-01 2850 30 7782 CLARK MANAGER 7839 1981-06-09 2450 10 7788 SCOTT ANALYST 7566 1982-12-09 3000 20 7839 KING PRESIDENT 1981-11-17 5000 10 7844 TURNER SALESMAN 7698 1981-09-08 1500 0 30 7876 ADAMS CLERK 7788 1983-01-12 1100 20 7900 JAMES CLERK 7698 1981-12-03 950 30 7902 FORD ANALYST 7566 1981-12-03 3000 20 7934 MILLER CLERK 7782 1982-01-23 1300 10 Penso que terei de usar uma função analitica, mas nao faço ideia como. Podem ajudar pf? obrigado
KTachyon Posted September 28, 2012 at 12:36 AM Report #476873 Posted September 28, 2012 at 12:36 AM Como não tenho praticamente nenhuma experiência em Oracle, não te posso ajudar com as funções analíticas. A minha sugestão seria criar uma stored function que obtém o max(sal) e que é chamada pela query para ser feita a subtracção. “There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult.” -- Tony Hoare
rumbafum Posted September 28, 2012 at 08:54 AM Report #476889 Posted September 28, 2012 at 08:54 AM assim à partida e de forma mais simples poderias usar um with. Não é a forma mais prática nem com melhor performance mas faz o trabalho. Não testei a query e remove as colunas que estiverem a mais with maxEmpVal as ( select * from ( select EMPNO, SAL as MAXSAL from EMP order by SAL desc) where rownum = 1 ) select cur.EMPNO, cur.SAL, mev.EMPNO, mev.MAXSAL, mev.MAXSAL - cur.SAL as SALDIF from EMP cur, maxEmpVal mev where cur.EMPNO <> mev.EMPNO
maomelov Posted September 28, 2012 at 03:44 PM Author Report #476939 Posted September 28, 2012 at 03:44 PM Como não tenho praticamente nenhuma experiência em Oracle, não te posso ajudar com as funções analíticas. A minha sugestão seria criar uma stored function que obtém o max(sal) e que é chamada pela query para ser feita a subtracção. Podes ajudar na query, tem erros, nao sei como resolver!!! SET SERVEROUTPUT ON DECLARE CURSOR C1 IS SELECT ENAME,SAL FROM EMP ORDER BY ENAME; VMAXSAL EMP.SAL%TYPE; RESULTADO EMP.SAL%TYPE; VEMP EMP%ROWTYPE; BEGIN OPEN C1; FETCH C1 INTO VEMP.ENAME, VEMP.SAL; CLOSE C1; SELECT MAX(SAL) INTO VMAXSAL FROM EMP; RESULTADO := (VMAXSAL)-(VEMP.SAL); DBMS_OUTPUT.PUT_LINE(VEMP.ENAME||-||RESULTADO); --DBMS_OUTPUT.PUT_LINE(VEMP.ENAME||-||VEMP.SAL); END; assim à partida e de forma mais simples poderias usar um with. Não é a forma mais prática nem com melhor performance mas faz o trabalho. Não testei a query e remove as colunas que estiverem a mais with maxEmpVal as ( select * from ( select EMPNO, SAL as MAXSAL from EMP order by SAL desc) where rownum = 1 ) select cur.EMPNO, cur.SAL, mev.EMPNO, mev.MAXSAL, mev.MAXSAL - cur.SAL as SALDIF from EMP cur, maxEmpVal mev where cur.EMPNO <> mev.EMPNO tentei fazer de outra forma mas nao está a funcionar, podes ajudar? SET SERVEROUTPUT ON DECLARE CURSOR C1 IS SELECT ENAME,SAL FROM EMP ORDER BY ENAME; VMAXSAL EMP.SAL%TYPE; RESULTADO EMP.SAL%TYPE; VEMP EMP%ROWTYPE; BEGIN OPEN C1; FETCH C1 INTO VEMP.ENAME, VEMP.SAL; CLOSE C1; SELECT MAX(SAL) INTO VMAXSAL FROM EMP; RESULTADO := (VMAXSAL)-(VEMP.SAL); DBMS_OUTPUT.PUT_LINE(VEMP.ENAME||-||RESULTADO); --DBMS_OUTPUT.PUT_LINE(VEMP.ENAME||-||VEMP.SAL); END;
rumbafum Posted September 28, 2012 at 05:38 PM Report #476963 Posted September 28, 2012 at 05:38 PM Não era mais fácil usar a query? esse procedure é para quê? Se é para usar cursor tens que fazer um loop sobre o cursor. Mas parece-me que o que quererias é uma função que te dá o valor do salário mais alto e usar essa função na query onde queres fazer diferenças. Posso-te dizer que esse método seria bem mais lento que usar o que te mostrei antes com o with (também pode ser uma inner query no where se preferires, o resultado é o mesmo só os planos de execução é que são diferentes dependendo da versão do Oracle)
maomelov Posted September 28, 2012 at 06:54 PM Author Report #476969 Posted September 28, 2012 at 06:54 PM Não era mais fácil usar a query? esse procedure é para quê? Se é para usar cursor tens que fazer um loop sobre o cursor. Mas parece-me que o que quererias é uma função que te dá o valor do salário mais alto e usar essa função na query onde queres fazer diferenças. Posso-te dizer que esse método seria bem mais lento que usar o que te mostrei antes com o with (também pode ser uma inner query no where se preferires, o resultado é o mesmo só os planos de execução é que são diferentes dependendo da versão do Oracle) O que eu precisava mesmo era de chegar ao resultado final usando a função first_value, especificamente. Podes ajudar nesse sentido?
rumbafum Posted September 28, 2012 at 09:30 PM Report #476978 Posted September 28, 2012 at 09:30 PM se o requisito é usar a função FIRST_VALUE podes simplificar a query que dei para: select EMPNO, SAL, FIRST_VALUE(SAL) over (order by SAL DESC ROWS UNBOUNDED PRECEDING) - SAL as SALDIF from EMP order by EMPNO As colunas do select EMPNO e SAL podem ser retiradas claro, bem como a ordenação pelo EMPNO
maomelov Posted September 28, 2012 at 09:36 PM Author Report #476979 Posted September 28, 2012 at 09:36 PM se o requisito é usar a função FIRST_VALUE podes simplificar a query que dei para: select EMPNO, SAL, FIRST_VALUE(SAL) over (order by SAL DESC ROWS UNBOUNDED PRECEDING) - SAL as SALDIF from EMP order by EMPNO As colunas do select EMPNO e SAL podem ser retiradas claro, bem como a ordenação pelo EMPNO Era exactamente isso!!! Já fiquei a perceber! Obrigado pela ajuda.
rumbafum Posted September 28, 2012 at 09:40 PM Report #476981 Posted September 28, 2012 at 09:40 PM Na boa 😉
jsWizard Posted October 23, 2012 at 03:53 PM Report #480107 Posted October 23, 2012 at 03:53 PM Parece-me que isto chega: select a.*, (max(a.sal) over ()) - a.sal diff_value from emp a order by sal desc; inté!
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now