Exercícios Práticos de SQL: Joins, Agrupamento e Permissões

Classificado em Inglês

Escrito em em português com um tamanho de 9,59 KB

Exercícios de INNER JOIN e Junções SQL

  1. 1. Mostrar todos os funcionários, com o seu nome, a data de admissão com o formato DD/MM/YYYY (exemplo: 01/01/1981), o salário e o nome do departamento no qual trabalham, mas somente para funcionários cujo nome começa com a letra “A”.

    SELECT ENAME, SAL, TO_CHAR(HIREDATE, 'DD/MM/YYYY') FROM EMP WHERE SUBSTR(ENAME, 1, 1) = 'A';
  2. 2. Listar o nome do departamento e a quantidade de funcionários em cada departamento, o valor total de salários de cada departamento. Atenção: use JOIN e GROUP BY na mesma consulta para resolver esta questão.

    SELECT ENAME, HIREDATE, SAL, D.DNAME FROM EMP E JOIN DEPT D ON E.DEPTNO = D.DEPTNO GROUP BY NAME;
  3. 3. Executar a mesma consulta elaborada para resolver a questão anterior, com a diferença de mostrar apenas os departamentos com mais de 3 funcionários.

    SELECT DNAME, COUNT(ENAME), SUM(SAL) FROM EMP E JOIN DEPT D ON E.DEPTNO = D.DEPTNO HAVING COUNT(ENAME) > 3 GROUP BY DNAME;
  4. 4. Crie uma consulta para exibir o nome do funcionário, o nome do departamento e a localização do departamento de todos os funcionários que recebem uma comissão (coluna da comissão é diferente de nulo).

    SELECT E.ENAME, D.DNAME, D.LOC FROM EMP E INNER JOIN DEPT D ON E.DEPTNO = D.DEPTNO WHERE E.COMM IS NOT NULL;
  5. 5. Listar todos os empregados com o seu nome e código junto com o nome de seu gerente (usar JOIN com auto-relacionamento da tabela EMP relacionando-se com a própria tabela EMP) e liste também os empregados que não têm chefe nesta mesma consulta.

    SELECT E.EMPNO, E.ENAME, F.ENAME AS GERENTE FROM EMP E LEFT JOIN EMP F ON E.MGR = F.EMPNO;
  6. 6. Insira um novo departamento na tabela DEPT, com DEPTNO = 90, DNAME = 'NOVO_DEPT' e LOC = 'BOSTON'. Após esta inclusão, crie uma consulta para exibir o nome do funcionário, o número e o nome do departamento de todos os funcionários e também liste os dados do departamento que não tem funcionário na mesma consulta.

    INSERT INTO DEPT (DEPTNO, DNAME, LOC) VALUES (90, 'NOVO_DEPT', 'BOSTON');
    SELECT E.EMPNO, D.DEPTNO, D.DNAME FROM EMP E RIGHT JOIN DEPT D ON E.DEPTNO = D.DEPTNO;
  7. 7. Apresente em uma única consulta SQL a quantidade de vendas (uma venda é uma linha da tabela ORD), por nome do cliente e também por nome do funcionário que atende ao cliente.

    SELECT COUNT(TOTAL), NAME, ENAME FROM ORD O JOIN CUSTOMER C ON O.CUSTID = C.CUSTID JOIN EMP ON RAPID = EMPNO GROUP BY NAME, ENAME;

Funções de Agregação e GROUP BY

  1. 1. Exibir qual é a média salarial dos funcionários.

    SELECT AVG(SAL) FROM EMP;
  2. 2. Liste o menor e o maior salário de cada tipo de cargo.

    SELECT MAX(SAL), MIN(SAL), JOB FROM EMP GROUP BY JOB;
  3. 3. Exiba o salário mais alto, mais baixo, total e média de todos os funcionários. Denomine as colunas como Máximo, Mínimo, Valor total e Média.

    SELECT SUM(SAL) AS TOTAL, AVG(SAL) AS MEDIA, MAX(SAL) AS MAXIMA, MIN(SAL) AS MINIMA FROM EMP;
  4. 4. Crie uma consulta para exibir o cargo e a quantidade de pessoas em cada função.

    SELECT JOB, COUNT(ENAME) AS TOTAL FROM EMP GROUP BY JOB;
  5. 5. Exiba por número do gerente (coluna MGR), qual é o salário do funcionário com o menor pagamento sob sua supervisão. Excluir os funcionários que não possuem gerentes.

    SELECT MGR, MIN(SAL) FROM EMP WHERE MGR IS NOT NULL GROUP BY MGR;
  6. Crie uma consulta que apresente o maior, o menor e a média do salário por departamento.

    SELECT DEPTNO, MIN(SAL), MAX(SAL), TRUNC(AVG(SAL)) FROM EMP GROUP BY DEPTNO;
  7. 6. Descubra os departamentos que possuem acima de três empregados e mostre apenas o código do departamento e a soma total dos salários por departamento.

    SELECT DEPTNO, TRUNC(SUM(SAL)) AS TOTAL FROM EMP HAVING COUNT(ENAME) > 3 GROUP BY DEPTNO;

Subconsultas (Subqueries) e UNION

  1. 1. Exibir o nome do responsável por FORD, ou seja, quem o coordena.

    SELECT MGR.ENAME FROM EMP E INNER JOIN EMP MGRR ON E.MGR = MGR.EMPNO WHERE E.ENAME = 'FORD';
  2. 2. Crie uma consulta para exibir o nome e a data de admissão dos funcionários do mesmo departamento do “SCOTT”. Não deve aparecer o funcionário “SCOTT”.

    SELECT ENAME, HIREDATE FROM EMP WHERE DEPTNO IN (SELECT DEPTNO FROM DEPT A INNER JOIN EMP B ON A.DEPTNO = B.DEPTNO WHERE B.ENAME = 'SCOTT') AND ENAME <> 'SCOTT';
  3. 3. Apresente o nome e o departamento do funcionário com o maior salário.

    SELECT A.ENAME, B.DNAME FROM EMP A INNER JOIN DEPT B ON A.DEPTNO = B.DEPTNO WHERE A.SAL IN (SELECT MAX(SAL) FROM EMP);
  4. 4. Liste os funcionários com função "CLERK" que recebem acima da média.

    SELECT A.ENAME, A.JOB FROM EMP A WHERE A.SAL > (SELECT AVG(SAL) FROM EMP) AND A.JOB = 'CLERK';
  5. 5. Crie uma consulta para exibir o número de pessoas com o mesmo cargo (use o campo JOB).

    SELECT JOB, COUNT(JOB) FROM EMP A GROUP BY JOB;
  6. 6. Liste a média de salários dos funcionários do gerente “BLAKE”.

    SELECT AVG(A.SAL) FROM EMP A INNER JOIN EMP B ON A.MGR = B.EMPNO WHERE B.ENAME = 'BLAKE';
  7. 7. Utilizando UNION e não subquery, apresente uma consulta que liste todos os dados dos funcionários, mas somente funcionários com cargo = 'CLERK' e 'ANALYST'.

    SELECT * FROM EMP WHERE JOB = 'CLERK' UNION SELECT * FROM EMP WHERE JOB = 'ANALYST';
  8. 8. O DBA precisa controlar o crescimento das informações contidas em cada tabela. Deste modo, é necessário executar uma única instrução que apresente o nome da tabela (lembre-se: você pode criar uma coluna dentro do comando SELECT com o nome de cada tabela: Emp, Dept, Customer, Ord, Item, Product) e a quantidade de registros de cada tabela.

    SELECT 'EMP' AS TABELA, COUNT(*) FROM EMP UNION SELECT 'DEPT', COUNT(*) FROM DEPT UNION SELECT 'CUSTOMER', COUNT(*) FROM CUSTOMER UNION SELECT 'ORD', COUNT(*) FROM ORD UNION SELECT 'ITEM', COUNT(*) FROM ITE UNION SELECT 'PRODUCT', COUNT(*) FROM PRODUCT;
  9. 9. Crie uma tabela chamada ORD_HISTORICO com os pedidos (tabela ORD) anteriores ao ano de 1987.

    CREATE TABLE ORD_HISTORICO AS SELECT * FROM ORD WHERE TO_CHAR(ORDERDATE, 'YYYY') <= 1987;
  10. 10. Crie outra tabela chamada ORD_ATUAL com os pedidos (tabela ORD) posteriores ao ano de 1986.

    CREATE TABLE ORD_ATUAL AS SELECT * FROM ORD WHERE TO_CHAR(ORDERDATE, 'YYYY') >= 1986;
  11. 11. Apresente uma consulta única que mostre todos os pedidos utilizando as duas tabelas criadas nos exercícios anteriores.

    SELECT * FROM ORD_ATUAL UNION SELECT * FROM ORD_HISTORICO;
  12. 12. Apresente a união das tabelas PRODUCT e ITEM, mas somente da coluna PRODID de ambas, e mostre os valores repetidos de código do produto.

    SELECT PRODID FROM PRODUCT UNION SELECT PRODID FROM ITEM;

Controle de Acesso: GRANT e REVOKE

  1. 1. Garanta o privilégio de atualização de sua tabela DEPT para outro usuário, permitindo que ele passe o privilégio para demais usuários. Realize o teste com outro usuário.

    GRANT UPDATE ON EMP TO AL290077 WITH GRANT OPTION;
  2. 2. Adicione o privilégio de SELECT para a tabela EMP a outro usuário. Realize o teste.

    GRANT SELECT ON EMP TO AL290077 WITH GRANT OPTION;
  3. 3. Solicite a outro usuário executar a instrução de insert. Deve apresentar erro.

    GRANT INSERT ON EMP TO AL290077 WITH GRANT OPTION;
  4. 4. Resolva o problema no exercício anterior para permitir a inclusão de novos registros na sua tabela a partir de outro usuário. Execute novamente o item 3.

    GRANT INSERT ON EMP TO AL290077 WITH GRANT OPTION;
  5. 6. Resolva o problema no exercício anterior para permitir a inclusão de novos registros na sua tabela a partir de outro usuário. Execute novamente o item 4.

    GRANT DELETE ON EMP TO AL290077 WITH GRANT OPTION;
  6. 7. Solicite ao usuário visualizar quais os privilégios ele possui para cada objeto.

    SELECT GRANTOR, TABLE_NAME, PRIVILEGE FROM USER_TAB_PRIVS_RECD;
  7. 8. Remova todos os privilégios associados ao usuário.

    REVOKE ALL ON EMP FROM AL290077;

Entradas relacionadas: