Oracle數據庫安裝的時候會自帶一個練習用數據庫(其中包含employee表,后來版本中此表改名為emp);
首先在安裝過程中應該有個選項“是否安裝實例表”(完全安裝模式下默認是選擇的),需要選擇才有此表;
此表歸屬于scott賬戶,scott用戶默認口令為tiger
如果發現scott賬戶已過期(Oracle 10g中經常發生),或口令不正確,可以通過以下方法進行設置
--賬戶解鎖
alter user scott account unlock;
--重設scott賬戶口令為tiger
alter user scott identified by tiger;
如果想通過這個例子練手,下面是對應的建表語句,讀者可以自行創建數據庫進行練習(特別是Mysql用戶)。對應的練習題,網上有很多,在這里博主總結了一些教材中的案例由于練習,如有錯誤請指出。
建表語句:
附:實例表建表語句(適用于Oracle)
SET TERMOUT ON
PROMPT Building demonstration tables. Please wait.
SET TERMOUT OFF DROP TABLE EMP;
DROP TABLE DEPT;
DROP TABLE BONUS;
DROP TABLE SALGRADE;
DROP TABLE DUMMY; CREATE TABLE EMP
(EMPNO NUMBER(4) NOT NULL,
ENAME VARCHAR2(10),
JOB VARCHAR2(9),
MGR NUMBER(4),
HIREDATE DATE,
SAL NUMBER(7, 2),
COMM NUMBER(7, 2),
DEPTNO NUMBER(2)); INSERT INTO EMP VALUES
(7369, 'SMITH', 'CLERK', 7902,
TO_DATE('17-DEC-1980', 'DD-MON-YYYY'), 800, NULL, 20);
INSERT INTO EMP VALUES
(7499, 'ALLEN', 'SALESMAN', 7698,
TO_DATE('20-FEB-1981', 'DD-MON-YYYY'), 1600, 300, 30);
INSERT INTO EMP VALUES
(7521, 'WARD', 'SALESMAN', 7698,
TO_DATE('22-FEB-1981', 'DD-MON-YYYY'), 1250, 500, 30);
INSERT INTO EMP VALUES
(7566, 'JONES', 'MANAGER', 7839,
TO_DATE('2-APR-1981', 'DD-MON-YYYY'), 2975, NULL, 20);
INSERT INTO EMP VALUES
(7654, 'MARTIN', 'SALESMAN', 7698,
TO_DATE('28-SEP-1981', 'DD-MON-YYYY'), 1250, 1400, 30);
INSERT INTO EMP VALUES
(7698, 'BLAKE', 'MANAGER', 7839,
TO_DATE('1-MAY-1981', 'DD-MON-YYYY'), 2850, NULL, 30);
INSERT INTO EMP VALUES
(7782, 'CLARK', 'MANAGER', 7839,
TO_DATE('9-JUN-1981', 'DD-MON-YYYY'), 2450, NULL, 10);
INSERT INTO EMP VALUES
(7788, 'SCOTT', 'ANALYST', 7566,
TO_DATE('09-DEC-1982', 'DD-MON-YYYY'), 3000, NULL, 20);
INSERT INTO EMP VALUES
(7839, 'KING', 'PRESIDENT', NULL,
TO_DATE('17-NOV-1981', 'DD-MON-YYYY'), 5000, NULL, 10);
INSERT INTO EMP VALUES
(7844, 'TURNER', 'SALESMAN', 7698,
TO_DATE('8-SEP-1981', 'DD-MON-YYYY'), 1500, 0, 30);
INSERT INTO EMP VALUES
(7876, 'ADAMS', 'CLERK', 7788,
TO_DATE('12-JAN-1983', 'DD-MON-YYYY'), 1100, NULL, 20);
INSERT INTO EMP VALUES
(7900, 'JAMES', 'CLERK', 7698,
TO_DATE('3-DEC-1981', 'DD-MON-YYYY'), 950, NULL, 30);
INSERT INTO EMP VALUES
(7902, 'FORD', 'ANALYST', 7566,
TO_DATE('3-DEC-1981', 'DD-MON-YYYY'), 3000, NULL, 20);
INSERT INTO EMP VALUES
(7934, 'MILLER', 'CLERK', 7782,
TO_DATE('23-JAN-1982', 'DD-MON-YYYY'), 1300, NULL, 10); CREATE TABLE DEPT
(DEPTNO NUMBER(2),
DNAME VARCHAR2(14),
LOC VARCHAR2(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 VARCHAR2(10),
JOB VARCHAR2(9),
SAL NUMBER,
COMM NUMBER); CREATE TABLE SALGRADE
(GRADE NUMBER,
LOSAL NUMBER,
HISAL NUMBER); 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); CREATE TABLE DUMMY
(DUMMY NUMBER); INSERT INTO DUMMY VALUES (0); COMMIT; SET TERMOUT ON
PROMPT Demonstration table build is complete. EXIT
實例建表語句(適用于MySQL)
DROP TABLE employee;
DROP TABLE dept;
DROP TABLE bonus;
DROP TABLE salgrade;
DROP TABLE dummy; CREATE TABLE employee
( employeeno DECIMAL(4) NOT NULL, ename VARCHAR(10), job VARCHAR(9), mgr DECIMAL(4), hiredate DATE, sal DECIMAL(7, 2), comm DECIMAL(7, 2), deptno DECIMAL(2)
); INSERT INTO employee VALUES
(7369, 'SMITH', 'CLERK', 7902, '1980-12-17', 800, NULL, 20);
INSERT INTO employee VALUES
(7499, 'ALLEN', 'SALESMAN', 7698,'1981-2-20', 1600, 300, 30);
INSERT INTO employee VALUES
(7521, 'WARD', 'SALESMAN', 7698, '1981-2-22', 1250, 500, 30);
INSERT INTO employee VALUES
(7566, 'JONES', 'MANAGER', 7839, '1981-4-2', 2975, NULL, 20);
INSERT INTO employee VALUES
(7654, 'MARTIN', 'SALESMAN', 7698, '1981-9-28', 1250, 1400, 30);
INSERT INTO employee VALUES
(7698, 'BLAKE', 'MANAGER', 7839, '1981-5-1', 2850, NULL, 30);
INSERT INTO employee VALUES
(7782, 'CLARK', 'MANAGER', 7839, '1981-7-9', 2450, NULL, 10);
INSERT INTO employee VALUES
(7788, 'SCOTT', 'ANALYST', 7566, '1982-12-9', 3000, NULL, 20);
INSERT INTO employee VALUES
(7839, 'KING', 'PRESIDENT', NULL, '1981-11-17', 5000, NULL, 10);
INSERT INTO employee VALUES
(7844, 'TURNER', 'SALESMAN', 7698, '1981-9-8', 1500, 0, 30);
INSERT INTO employee VALUES
(7876, 'ADAMS', 'CLERK', 7788, '1983-1-12', 1100, NULL, 20);
INSERT INTO employee VALUES
(7900, 'JAMES', 'CLERK', 7698, '1981-12-3', 950, NULL, 30);
INSERT INTO employee VALUES
(7902, 'FORD', 'ANALYST', 7566, '1981-12-3', 3000, NULL, 20);
INSERT INTO employee VALUES
(7934, 'MILLER', 'CLERK', 7782, '1982-1-23', 1300, NULL, 10); CREATE TABLE dept
(deptno DECIMAL(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 DECIMAL,
comm DECIMAL); CREATE TABLE salgrade
(grade DECIMAL,
losal DECIMAL,
hisal DECIMAL); 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); CREATE TABLE dummy
(dummy DECIMAL); INSERT INTO dummy VALUES (0);
查詢案例(MySQL版本)
查詢1985年12月31日之前入職的員工姓名及入職日期。(注意日期的寫法)
SELECT ename,hiredate FROM employee WHERE hiredate < '1985-12-31'查詢部門編號不在10部門的員工姓名、部門編號。(這里的!=也可寫作<>)
SELECT ename,deptno FROM employee WHERE deptno!=10;查詢入職日期在82年至85年的員工姓名,入職日期.
SELECT ename,hiredate FROM employee WHERE hiredate BETWEEN '1982-1-01' AND '1985-12-31'查詢部門編號為10或者20的員工姓名,部門編號。
SELECT ename,deptno
from employee
WHERE deptno=10 OR deptno=20;查詢經理編號為7902 7566 7788的員工姓名,經理編號。#注意是圓括號
SELECT ENAme,mgr
FROM employee
WHERE mgr IN (7902,7566,7788)查詢員工姓名以W開頭的員工姓名。
SELECT ename
from employee
WHERE ename LIKE 'W%'查詢員工姓名倒數第2個字符為T的員工姓名。
SELECT ename
FROM employee
WHERE ename LIke '%T_'查詢獎金為空的員工姓名,獎金。
SELECT ename
from employee
WHERE comm IS NULL查詢部門在10或者20,并且工資在3000到5000之間的員工姓名、部門、工資。
#注意邏輯運算符的優先級not>and>or,其次根據中文中的邏輯詞來寫。
SELECT ename,deptno,sal
from employee
WHERE (3000<=sal and sal<=5000)and(deptno=10 or deptno=20)查詢入職日期在81年,并且職位不是SALES開頭的員工姓名、入職日期、職位。
#注意對于字符串的比較不能采用運算符如!=等,需要用Like關鍵字等
SELECT ename,hiredate,job
from employee
where (hiredate BETWEEN '1981-1-01' AND '1981-12-31')and (job not LIKE 'SALES%')查詢工資在2000-3000之間,部門不在10號的員工姓名,部門編號,工資,并按照部門升序 并按照部門升序,工資降序排序。
SELECT ename , deptno,sal
from employee
WHERE (sal BETWEEN 2000 and 3000) and (deptno!=10)
ORDER BY deptno asc, sal DESC寫一個查詢,顯示所有員工姓名,部門編號,部門名稱。
#N張表至少要N-1個連接條件
SELECT ename,employee.deptno,dname
from dept, employee
where dept.deptno=employee.deptno;寫一個查詢,顯示所有工作在CHICAGO并且獎金不為空的員工姓名,工作地點,獎金
select ename,loc,comm
from employee,dept
WHERE employee.deptno=dept.deptno and ((loc='CHICAGO') and (comm is not NULL))查詢每個員工的姓名和直接上級姓名?
SELECT A.ename worker,B.ename boss
FROM employee A INNER JOIN employee B
ON A.mgr=B.employeeno查詢所有工作在NEW YORK和CHICAGO的員工姓名,員工編號,以及他們的經理姓名,經理編號。
#from什么join什么的,可以看做是一張表(其實就是一張復雜的表)。下面接著用正常的語法就可以了。
SELECT A.ename workName,A.employeeno workNum,B.ename bossName,B.employeeno BossNum,loc
from employee A
JOIN employee B
ON A.mgr=B.employeeno
JOIN dept C
on A.deptno=C.deptno
where loc IN ('NEW YORK','CHICAGO')查詢所有員工編號,姓名,部門名稱,包括沒有部門的員工也要顯示出來。
SELECT A.ename ,A.employeeno,B.dname
FROM employee A
LEFT JOIN dept B
ON A.deptno=B.deptno;創建一個員工表和部門表的交叉連接。
SELECT count(*)
from employee A
CROSS JOIN dept B使用USING子句,顯示工作在CHICAGO的員工姓名,部門名稱,工作地點
#using可以作為一個連接條件使用(直接將兩張表的公有屬性聲明在using中)
SELECT ename,dname,loc
from employee A
join dept B
USING (deptno)
WHERE B.loc='CHICAGO'使用ON子句,顯示工作在CHICAGO的員工姓名,部門名稱,工作地點,薪資等級
SELECT ename,dname,loc,grade
from employee A
join dept B
on A.deptno=B.deptno
join salgrade C
WHERE A.sal BETWEEN C.losal and C.hisal;使用左連接,查詢每個員工的姓名 查詢每個員工的姓名,經理姓名,沒有經理的King也要顯示出來。
SELECT A.ename worker,B.ename boss
from employee A
LEFT JOIN employee B
on A.mgr=B.employeeno查詢每個部門的部門編號,部門名稱,部門人數,最高工資,最低工資,工資總和,平均工資。
#注意聲明你是以那張表的deptno作為分組的條件的(表不同,結果也不同)
SELECT employee.deptno,dname,count(DISTINCT employeeno),MAX(sal),MIN(sal),SUM(sal),AVG(sal)
from employee,dept
GROUP BY employee.deptno查詢每個經理所管理的人數,經理編號,經理姓名,要求包括沒有經理的人員信息。
SELECT count(DISTINCT A.employeeno),B.ename,B.employeeno
from employee A
LEFT JOIN employee B
on A.mgr=B.employeeno
GROUP BY A.mgr#不能在 WHERE子句中限制組,可以通過 HAVING 子句限制組(經典錯題)、
#原因:根據sql執行順序,先從where中得到限制條件,然后才執行goupBy語句,之后才執行having語句
如果再where中直接進行一個限制組的操作,那么后續的group將沒有任何意義(畢竟都是分區排序先分區再排序)
1 SELECT deptno, max(sal)
2 FROM emp
3 WHERE max(sal) > 2900
4 GROUP BY deptno;
*
ERROR at line 3:
ORA-00934: group function is not allowed here
*查詢部門人數大于2的部門編號,部門名稱,部門人數。
SELECT B.deptno,dname,COUNT(DISTINCT employeeno)
from dept A,employee B
where A.deptno=B.deptno
GROUP BY B.deptno
HAVING count(DISTINCT employeeno)>2查詢部門平均工資大于2000,且人數大于2的部門編號,部門名稱,部門人數,部門平均工資
,并按照部門人數升序排序。
SELECT B.deptno,dname,COUNT(DISTINCT employeeno),AVG(sal)
from dept A,employee B
where A.deptno=B.deptno
GROUP BY B.deptno
HAVING count(DISTINCT employeeno)>2 and AVG(sal)>2000
ORDER BY count(DISTINCT employeeno) ASC查詢工資比Jones工資高的員工信息?
SELECT *
from employee
WHERE sal >(SELECT sal
from employee
WHERE ename='Jones')查詢工資最低的員工姓名?
SELECT ename
from employee
WHERE sal in (SELECT min(sal)
from employee)查詢入職日期最早的員工姓名,入職日期(分成兩步查詢,第一步查詢基本屬性,第二步查詢最早入職的日期。子查詢結果對應的行就是主查詢需要的數據)
SELECT ename, hiredate
from employee
where hiredate=
(SELECT min(hiredate)
from employee)查詢工資比SMITH工資高并且工作地點在CHICAGO的員工姓名,工資,部門名稱
SELECT ename,sal,dname
from employee A,dept B
WHERE A.deptno=B.deptno
and sal >(SELECT sal
from employee
WHERE ename='SMITH' )AND loc ='CHICAGO'查詢部門人數大于所有部門平均人數的的部門編號,部門名稱,部門人數(重點看,一定要注意表的連接條件)
SELECT A.deptno,dname,count(DISTINCT employeeno)
from employee A,dept B
WHERE A.deptno=B.deptno
GROUP BY A.deptno
HAVING COUNT(employeeno) >
(SELECT count(ename)/count(DISTINCT deptno) from employee)查詢入職日期比10部門任意一個員工晚的員工姓名、入職日期,不包括10部門員工
SELECT ename,hiredate,deptno
from employee
WHERE hiredate >ANY(SELECT hiredate
from employee
WHERE deptno=10 )
AND deptno!=10查詢入職日期比10部門所有員工晚的員工姓名、入職日期,不包括10部門員工
SELECT ename,hiredate,deptno
from employee
WHERE hiredate > all(SELECT hiredate
from employee
WHERE deptno=10 ) AND deptno!=10查詢職位及經理和10部門任意一個員工職位及經理相同的員工姓名,職位,不包括10部門員工
#注意可以多屬性匹配
SELECT ename, job
FROM employee
WHERE (job ,mgr) in (SELECT job,mgr
FROM employee
WHERE deptno=10) AND deptno !=10向部門表新增一個部門,部門編號為50,部門名稱為HR,工作地點為SY。
INSERT INTO dept
VALUES(50,'HR','SY')把員工編號為7782的部門編號修改為20
UPDATE emp
SET deptno = 20
WHERE empno = 7782;刪除職位是CLERK的員工記錄
DELETE FROM emp
WHERE job = 'CLERK'; INSERT into manegers
SELECT * from employee WHERE job ='MANAGER'
總結
SQL對于大數據來說非常重要,所以這項技能一定要精通。后續會再回顧下SQL,然后把一些重要的知識點總結出來。