Oracle SQL示例数据库

时间:2012-01-09 13:55:56

标签: sql oracle

我正在尝试通过它提供的数据库来学习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)

现在我想选择在他们的部门和salgrade中获得最多收入的员工。

我写了类似这样的东西:

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

来自同一部门和salgrade的2人。

你能指出我的错误吗?

6 个答案:

答案 0 :(得分:1)

您按员工姓名,部门和工资等级进行分组。这意味着您将为数据集中的员工姓名,部门和薪资等级的每个组合返回一行。

为了确保每个部门和工资等级只返回一行,您需要从group by子句中删除员工姓名。这将使您能够找到每个年级和部门的最高工资,但不能找到哪个员工有该工资 - 为此,您需要再次将结果重新加入员工表,如下所示:

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。

答案 1 :(得分:1)

用你的`select:

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 SALESMARTIN 2 SALES

答案 2 :(得分:1)

您没有过滤查询,这就是您展示所有员工的原因。

这将过滤收入低于部门/等级最高的员工:

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年级的最高薪水(Martin和Ward都获得1250)。要么这是可以接受的,要么你需要一些其他标准来选择其中一个。

您可以使用row_number分析函数来确保grade / dept只返回一行(请注意,如果有重复项,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 

答案 3 :(得分:0)

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

答案 4 :(得分:0)

Screen Shot //////试试这个

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

答案 5 :(得分:-1)

当我创建这个时,我使用这种格式使其更容易阅读和修改它是针对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);