Пример базы данных Oracle SQL - PullRequest
1 голос
/ 09 января 2012

Я пытаюсь изучить Oracle SQL с помощью базы данных. Я нашел где-то задачи, которые нужно выполнить. Структура базы данных предоставлена ​​Oracle:

CREATE TABLE EMP
(EMPNO NUMERIC(4) NOT NULL,
ENAME VARCHAR(10),
JOB VARCHAR(9),
MGR NUMERIC(4),
HIREDATE DATETIME,
SAL NUMERIC(7, 2),
COMM NUMERIC(7, 2),
DEPTNO NUMERIC(2))

INSERT INTO EMP VALUES
(7369, 'SMITH', 'CLERK', 7902, '17-DEC-1980', 800, NULL, 20)
INSERT INTO EMP VALUES
(7499, 'ALLEN', 'SALESMAN', 7698, '20-FEB-1981', 1600, 300, 30)
INSERT INTO EMP VALUES
(7521, 'WARD', 'SALESMAN', 7698, '22-FEB-1981', 1250, 500, 30)
INSERT INTO EMP VALUES
(7566, 'JONES', 'MANAGER', 7839, '2-APR-1981', 2975, NULL, 20)
INSERT INTO EMP VALUES
(7654, 'MARTIN', 'SALESMAN', 7698, '28-SEP-1981', 1250, 1400, 30)
INSERT INTO EMP VALUES
(7698, 'BLAKE', 'MANAGER', 7839, '1-MAY-1981', 2850, NULL, 30)
INSERT INTO EMP VALUES
(7782, 'CLARK', 'MANAGER', 7839, '9-JUN-1981', 2450, NULL, 10)
INSERT INTO EMP VALUES
(7788, 'SCOTT', 'ANALYST', 7566, '09-DEC-1982', 3000, NULL, 20)
INSERT INTO EMP VALUES
(7839, 'KING', 'PRESIDENT', NULL, '17-NOV-1981', 5000, NULL, 10)
INSERT INTO EMP VALUES
(7844, 'TURNER', 'SALESMAN', 7698, '8-SEP-1981', 1500, 0, 30)
INSERT INTO EMP VALUES
(7876, 'ADAMS', 'CLERK', 7788, '12-JAN-1983', 1100, NULL, 20)
INSERT INTO EMP VALUES
(7900, 'JAMES', 'CLERK', 7698, '3-DEC-1981', 950, NULL, 30)
INSERT INTO EMP VALUES
(7902, 'FORD', 'ANALYST', 7566, '3-DEC-1981', 3000, NULL, 20)
INSERT INTO EMP VALUES
(7934, 'MILLER', 'CLERK', 7782, '23-JAN-1982', 1300, NULL, 10)

CREATE TABLE DEPT
(DEPTNO NUMERIC(2),
DNAME VARCHAR(14),
LOC VARCHAR(13) )

INSERT INTO DEPT VALUES (10, 'ACCOUNTING', 'NEW YORK')
INSERT INTO DEPT VALUES (20, 'RESEARCH', 'DALLAS')
INSERT INTO DEPT VALUES (30, 'SALES', 'CHICAGO')
INSERT INTO DEPT VALUES (40, 'OPERATIONS', 'BOSTON')

CREATE TABLE BONUS
(ENAME VARCHAR(10),
JOB VARCHAR(9),
SAL NUMERIC,
COMM NUMERIC)

CREATE TABLE SALGRADE
(GRADE NUMERIC,
LOSAL NUMERIC,
HISAL NUMERIC)

INSERT INTO SALGRADE VALUES (1, 700, 1200)
INSERT INTO SALGRADE VALUES (2, 1201, 1400)
INSERT INTO SALGRADE VALUES (3, 1401, 2000)
INSERT INTO SALGRADE VALUES (4, 2001, 3000)
INSERT INTO SALGRADE VALUES (5, 3001, 9999)

Теперь я хотел бы выбрать сотрудников, которые больше всего зарабатывают в своем отделе и получают оценку.

Я написал что-то вроде этого:

select ename, salgrade.grade, dept.dname from emp, salgrade, dept
WHERE emp.sal BETWEEN salgrade.losal AND salgrade.hisal
AND emp.deptno = dept.deptno group by salgrade.grade,  dept.dname, emp.ename

Но это не работает должным образом. Выход:

ENAME    GRADE   DNAME
SMITH    1   RESEARCH
BLAKE    4   SALES
FORD     4   RESEARCH
KING     5   ACCOUNTING
SCOTT    4   RESEARCH
MILLER   2   ACCOUNTING
TURNER   3   SALES
WARD     2   SALES
MARTIN   2   SALES
ADAMS    1   RESEARCH
JONES    4   RESEARCH
JAMES    1   SALES
CLARK    4   ACCOUNTING
ALLEN    3   SALES

Примечание строки:

WARD 2 SALES
MARTIN 2 SALES

2 человека из того же отдела и salgrade.

Не могли бы вы указать мне мои ошибки?

Ответы [ 6 ]

1 голос
/ 09 января 2012

Вы не фильтруете свой запрос, поэтому у вас отображаются все сотрудники.

Это отфильтровывает сотрудников, которые зарабатывают меньше, чем максимум за свой отдел / класс:

SELECT ename, salgrade.grade, dept.dname
  FROM emp, salgrade, dept
 WHERE emp.sal BETWEEN salgrade.losal AND salgrade.hisal
   AND emp.deptno = dept.deptno
   AND emp.sal = (SELECT MAX(sal)
                    FROM emp emp_in, salgrade grade_in
                   WHERE emp_in.sal BETWEEN grade_in.losal AND grande_in.hisal
                     AND emp_in.deptno = emp.deptno
                     AND grade_in.losal = salgrade.losal)

Вы все равно найдете дубликаты, потому что, например, два человека в отделе продаж получают максимальную зарплату для 2-го класса (и Мартин, и Уорд получают 1250). Либо это приемлемо, либо вам нужны другие критерии, чтобы выбрать только один из них.

Вы можете использовать аналитическую функцию row_number, чтобы гарантировать, что класс / отдел возвращает только одну строку (обратите внимание, что Oracle выберет произвольно одну строку при наличии дубликатов):

SELECT * FROM (
  SELECT ename, salgrade.grade, dept.dname,
         row_number() OVER (PARTITION BY dept.deptno, salgrade.grade 
                            ORDER BY emp.sal DESC) rnk
    FROM emp, salgrade, dept
   WHERE emp.sal BETWEEN salgrade.losal AND salgrade.hisal
     AND emp.deptno = dept.deptno
) WHERE rnk = 1;

ENAME       GRADE DNAME          RNK
---------- ------ -------------- ---
MILLER          2 ACCOUNTING       1 
CLARK           4 ACCOUNTING       1 
KING            5 ACCOUNTING       1 
ADAMS           1 RESEARCH         1 
FORD            4 RESEARCH         1 
JAMES           1 SALES            1 
MARTIN          2 SALES            1 
ALLEN           3 SALES            1 
BLAKE           4 SALES            1 
1 голос
/ 09 января 2012

С вашим `выберите:

select ename, salgrade.grade, dept.dname from emp, salgrade, dept
WHERE emp.sal BETWEEN salgrade.losal AND salgrade.hisal
AND emp.deptno = dept.deptno group by salgrade.grade, dept.dname, emp.ename

когда вы group by salgrade.grade, dept.dname, emp.ename результаты будут сгруппированы в эти три значения. Вы также ставите результаты BETWEEN salgrade.losal AND salgrade.hisal, чтобы получить все employees, у которых зарплата в этом интервале. Это ничего не ограничивает тем, кто получил больше? И именно поэтому у вас есть WARD 2 SALES и MARTIN 2 SALES.

1 голос
/ 09 января 2012

Вы группируете по имени сотрудника, а также по отделу и уровню заработной платы.Это означает, что вы вернете строку для каждой комбинации имени сотрудника, отдела и уровня заработной платы в вашем наборе данных.

Чтобы гарантировать, что вы возвращаете только одну строку для отдела и класса зарплаты, вам необходимо удалить имя сотрудникаиз группы по предложению.Это позволит вам определить максимальную зарплату по классу и отделу, но не указывать, какие сотрудники имеют эту зарплату - для этого вам нужно снова присоединить результаты к таблице сотрудников, например:

select e.ename, s.grade, d.dname, e.salary
from (select max(emp.salary) max_salary, 
             salgrade.grade,
             emp.deptno 
      from emp, salgrade
      WHERE emp.sal BETWEEN salgrade.losal AND salgrade.hisal
      group by salgrade.grade, dept.dname) s
     join emp e on e.salary = s.max_salary
     join dept d on e.deptno = d.deptno

Обратите внимание, что если несколько сотрудников в одном и том же отделе получают одинаковую максимальную зарплату в пределах своей категории, тогда оба сотрудника будут возвращены - это должно произойти с FORD и SCOTT в RESEARCH.

0 голосов
/ 07 марта 2016

Снимок экрана ////// Попробуйте это

SELECT E.EMPNO, E.ENAME, E.JOB, D.DNAME, E.SAL, E.DEPTNO, S.GRADE 
FROM EMP E, SALGRADE S, DEPT D 
WHERE E.SAL IN (SELECT MAX(SAL) FROM EMP GROUP BY DEPTNO) 
AND E.SAL BETWEEN S.LOSAL AND S.HISAL 
AND E.DEPTNO = D.DEPTNO
ORDER BY E.SAL DESC
0 голосов
/ 16 января 2014

Когда я создавал это, я использовал этот формат, чтобы его было легче читать и изменять, для формата Oracle

CREATE TABLE EMP
    (EMP_NO NUMBER(4) NOT NULL  PRIMARY KEY,
      E_NAME VARCHAR2(10),
        JOB VARCHAR2(9),
          MGR NUMBER(4),
            HIRE_DATE DATE,
              SAL DECIMAL(7, 2),
                COMM DECIMAL(7, 2),
                  DEPT_NO NUMBER(2));

SELECT *
FROM EMP

INSERT INTO EMP 
    (EMP_NO, E_NAME, JOB, MGR, HIRE_DATE, SAL, COMM, DEPT_NO)
VALUES
    (7369, 'SMITH', 'CLERK', 7902, '17-DEC-1980', 800, NULL, 20);

INSERT INTO EMP 
    (EMP_NO, E_NAME, JOB, MGR, HIRE_DATE, SAL, COMM, DEPT_NO)
VALUES
    (7499, 'ALLEN', 'SALESMAN', 7698, '20-FEB-1981', 1600, 300, 30);

INSERT INTO EMP 
    (EMP_NO, E_NAME, JOB, MGR, HIRE_DATE, SAL, COMM, DEPT_NO)
VALUES
    (7521, 'WARD', 'SALESMAN', 7698, '22-FEB-1981', 1250, 500, 30);

INSERT INTO EMP 
    (EMP_NO, E_NAME, JOB, MGR, HIRE_DATE, SAL, COMM, DEPT_NO)
VALUES
    (7566, 'JONES', 'MANAGER', 7839, '02-APR-1981', 2975, NULL, 20);

INSERT INTO EMP 
    (EMP_NO, E_NAME, JOB, MGR, HIRE_DATE, SAL, COMM, DEPT_NO)
VALUES
    (7654, 'MARTIN', 'SALESMAN', 7698, '28-SEP-1981', 1250, 1400, 30);

INSERT INTO EMP 
    (EMP_NO, E_NAME, JOB, MGR, HIRE_DATE, SAL, COMM, DEPT_NO)
VALUES
    (7698, 'BLAKE', 'MANAGER', 7839, '01-MAY-1981', 2850, NULL, 30);

INSERT INTO EMP 
    (EMP_NO, E_NAME, JOB, MGR, HIRE_DATE, SAL, COMM, DEPT_NO)
VALUES
    (7782, 'CLARK', 'MANAGER', 7839, '09-JUN-1981', 2450, NULL, 10);

INSERT INTO EMP 
    (EMP_NO, E_NAME, JOB, MGR, HIRE_DATE, SAL, COMM, DEPT_NO)
VALUES
    (7788, 'SCOTT', 'ANALYST', 7566, '09-DEC-1982', 3000, NULL, 20);

INSERT INTO EMP 
    (EMP_NO, E_NAME, JOB, MGR, HIRE_DATE, SAL, COMM, DEPT_NO)
VALUES
    (7839, 'KING', 'PRESIDENT', NULL, '17-NOV-1981', 5000, NULL, 10);

INSERT INTO EMP 
    (EMP_NO, E_NAME, JOB, MGR, HIRE_DATE, SAL, COMM, DEPT_NO)
VALUES
    (7844, 'TURNER', 'SALESMAN', 7698, '08-SEP-1981', 1500, 0, 30);

INSERT INTO EMP 
    (EMP_NO, E_NAME, JOB, MGR, HIRE_DATE, SAL, COMM, DEPT_NO)
VALUES    
    (7876, 'ADAMS', 'CLERK', 7788, '12-JAN-1983', 1100, NULL, 20);

INSERT INTO EMP 
    (EMP_NO, E_NAME, JOB, MGR, HIRE_DATE, SAL, COMM, DEPT_NO)
VALUES
    (7900, 'JAMES', 'CLERK', 7698, '03-DEC-1981', 950, NULL, 30);

INSERT INTO EMP 
    (EMP_NO, E_NAME, JOB, MGR, HIRE_DATE, SAL, COMM, DEPT_NO)
VALUES
    (7902, 'FORD', 'ANALYST', 7566, '03-DEC-1981', 3000, NULL, 20);

INSERT INTO EMP 
    (EMP_NO, E_NAME, JOB, MGR, HIRE_DATE, SAL, COMM, DEPT_NO)
VALUES
    (7934, 'MILLER', 'CLERK', 7782, '23-JAN-1982', 1300, NULL, 10);

CREATE TABLE DEPT
    (DEPT_NO NUMERIC(2),
      D_NAME VARCHAR(14),
        LOC VARCHAR(13) );

INSERT INTO DEPT 
    (DEPT_NO, D_NAME, LOC)
VALUES 
    (10, 'ACCOUNTING', 'NEW YORK');

INSERT INTO DEPT 
    (DEPT_NO, D_NAME, LOC)
VALUES 
    (20, 'RESEARCH', 'DALLAS');

INSERT INTO DEPT 
    (DEPT_NO, D_NAME, LOC)
VALUES 
    (30, 'SALES', 'CHICAGO');

INSERT INTO DEPT 
    (DEPT_NO, D_NAME, LOC)
VALUES 
    (40, 'OPERATIONS', 'BOSTON');

CREATE TABLE BONUS
    (E_NAME VARCHAR(10),
      JOB VARCHAR(9),
        SAL NUMERIC,
          COMM NUMERIC);

CREATE TABLE SAL_GRADE
    (GRADE NUMERIC,
      LO_SAL NUMERIC,
        HI_SAL NUMERIC);

INSERT INTO SAL_GRADE 
    (GRADE, LO_SAL, HI_SAL)
VALUES 
    (1, 700, 1200);

INSERT INTO SAL_GRADE 
    (GRADE, LO_SAL, HI_SAL)
VALUES 
    (2, 1201, 1400);

INSERT INTO SAL_GRADE 
    (GRADE, LO_SAL, HI_SAL)
VALUES 
    (3, 1401, 2000);

INSERT INTO SAL_GRADE 
    (GRADE, LO_SAL, HI_SAL)
VALUES 
    (4, 2001, 3000);

INSERT INTO SAL_GRADE 
    (GRADE, LO_SAL, HI_SAL)
VALUES 
    (5, 3001, 9999);
0 голосов
/ 23 апреля 2013
SELECT  SUB2.ENAME , SUB2.DNAME , S.GRADE  ,SUB2.SAL  
FROM SALGRADE S,
(SELECT E.ENAME,E.SAL,D.DNAME
    FROM EMP E, DEPT D,  
        (SELECT DEPTNO, MAX(SAL) AS "MAX"
            FROM EMP
            GROUP BY DEPTNO) SUB1  
    WHERE E.SAL=SUB1.MAX
    AND E.DEPTNO=D.DEPTNO) SUB2

WHERE SUB2.SAL BETWEEN S.LOSAL AND S.HISAL
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...