Oracle+11g+笔记(1)-SQL语言基础
1、SQL语言基础
1.1 SQL语言的功能
-
数据定义功能:
DDL(CREATE、DROP、ALERT)
。 -
数据查询功能:
DQL(Select)
。 -
数据操作功能:
DML(INDERT、UPDATE、DELETE)
。 -
数据控制功能:
DCL(GRANT、REVOKE、COMMIT、ROLLBACK)
1.2 SQL语言的编写功能
-
SQL
关键字不区分大小写。 -
对象名和列名不区分大小写。
-
字符值和日期值区分大小写。
-
SQL
语句可以放在一行上也可以放在多行上。 -
在
SQL*Plus
中的SQL语句要以分号结束。
1.3 数据定义DDL(CREATE、DROP、ALERT)
1.3.1 CREATE
1、创建表
CREATE TABLE <表名> (<列名><数据类型>[列级完整性约束条件]
[,<列名><数据类型>[列级完整性约束条件]]...
[,<表级完整性约束条件>]);
create table IT_EMPLOYEES
(
EMPLOYEE_ID NUMBER(6) not null unique,
FIRST_NAME VARCHAR2(20),
LAST_NAME VARCHAR2(25) not null,
EMAIL VARCHAR2(25),
PHONE_NUMBER VARCHAR2(20),
JOB_ID VARCHAR2(10),
SALARY NUMBER(8,2),
MANAGER_ID NUMBER(6)
);
2、创建视图
CREATE VIEW <视图名>[(<列名>[,<列名>]...)]
AS<子查询>
[WITH CHECK OPTION]
WITH CHECK OPTION
表示对视图进行UPDATE
、INSERT
和 DELETE
操作时,要保证更新、插入或删除的行满足视
图定义中的谓词条件(即子查询中的条件表达式)。
create view prog_employees
as
select employee_id,first_name,last_name,email,phone_number,salary,manager_id
from it_employees
where job_id = 'IT_PROG';
create view prog_employees_1
as
select employee_id,first_name,last_name,email,phone_number,salary,manager_id
from it_employees
where job_id = 'IT_PROG'
with check option;
PROG_EMPLOYEES
视图时加上了WITH CHECK OPTION
子句,以后对该视图进行插入、修改和删除操作时,DBMS
会自动加上条件 JOB_ID='IT_PROG'
。
3、建立索引
CREATE [UNIQUE][CLUSTER]INDEX<索引名>
ON<表名>(<列名>[<次序>][,<列名>[<次序>]]...);
CREATE INDEX IT_LASTNAME ON IT_EMPLOYEES(LAST_NAME);
1.3.2 DROP
1、删除表
DROP TABLE<表名>;
DROP TABLE IT_EMPLOYEES;
2、删除视图
DROP VIEW <视图名>;
drop view prog_employees;
3、删除索引
DROP INDEX <索引名>;
DROP INDEX IT_LASTNAME;
1.3.3 ALTER
ALTER TABLE<表名>
[ADD<新列名><数据类型>[完整性约束]]
[DROP<完整性约束名>]
[MODIFY<列名><数据类型>];
# 新增列
ALTER TABLE IT_EMPLOYEES ADD BIRTH_DATE DATE;
# 修改列的数据类型
ALTER TABLE IT_EMPLOYEES MODIFY MANAGER_ID NUMBER(8);
# 删除约束
ALTER TABLE IT_EMPLOYEES DROP UNIQUE(EMPLOYEE_ID);
1.4 数据查询
SELECT [ALL|DISTINCT] TOP n[PERCENT] WITH TIES select_list
[INTO[new_table_name]]
[FROM{table_name|view_name}[(optimizer_hints)]
[,{table_name2|view_name2}[(optimizer_hints)]
[...,table_name16|view_name16][(optimizer hints)]]]
[WHERE clause]
[GROUP BY clause]
[HAVING clause]
[ORDER BY clause]
[COMPUTE clause]
[FOR BROWSE]
# 107行数据
select * from hr.employees;
1、使用 FROM子句指定表
[FROM{table_name|view_name}[(optimizer_hints)]
[,{table_name2|view_name2}[(optimizer_hints)]
[...,table_name16|view_name16][(optimizer_hints)]]]
# 25行数据
SELECT * FROM HR.COUNTRIES;
COUNTRY_ID|COUNTRY_NAME |REGION_ID|
----------+------------------------+---------+
AR |Argentina | 2|
AU |Australia | 3|
BE |Belgium | 1|
BR |Brazil | 2|
CA |Canada | 2|
CH |Switzerland | 1|
CN |China | 3|
DE |Germany | 1|
DK |Denmark | 1|
EG |Egypt | 4|
FR |France | 1|
IL |Israel | 4|
IN |India | 3|
IT |Italy | 1|
JP |Japan | 3|
KW |Kuwait | 4|
ML |Malaysia | 3|
MX |Mexico | 2|
NG |Nigeria | 4|
NL |Netherlands | 1|
SG |Singapore | 3|
UK |United Kingdom | 1|
US |United States of America| 2|
ZM |Zambia | 4|
ZW |Zimbabwe | 4|
# 27行数据
SELECT * FROM HR.DEPARTMENTS;
DEPARTMENT_ID|DEPARTMENT_NAME |MANAGER_ID|LOCATION_ID|
-------------+--------------------+----------+-----------+
10|Administration | 200| 1700|
20|Marketing | 201| 1800|
30|Purchasing | 114| 1700|
40|Human Resources | 203| 2400|
50|Shipping | 121| 1500|
60|IT | 103| 1400|
70|Public Relations | 204| 2700|
80|Sales | 145| 2500|
90|Executive | 100| 1700|
100|Finance | 108| 1700|
110|Accounting | 205| 1700|
120|Treasury | | 1700|
130|Corporate Tax | | 1700|
140|Control And Credit | | 1700|
150|Shareholder Services| | 1700|
160|Benefits | | 1700|
170|Manufacturing | | 1700|
180|Construction | | 1700|
190|Contracting | | 1700|
200|Operations | | 1700|
210|IT Support | | 1700|
220|NOC | | 1700|
230|IT Helpdesk | | 1700|
240|Government Sales | | 1700|
250|Retail Sales | | 1700|
260|Recruiting | | 1700|
270|Payroll | | 1700|
# 可以在FROM子句中指定多个表,每个表使用逗号(,)
# 进行两个表的笛卡尔积
# 行数(25*27=675)
SELECT * FROM HR.COUNTRIES,HR.DEPARTMENTS;
2、使用 SELECT指定列
SELECT column_name_1,...,colunm_name_n
FROM table_name_1,...,table_name_n
SELECT REGION_ID,COUNTRY_NAME FROM HR.COUNTRIES;
REGION_ID|COUNTRY_NAME |
---------+------------------------+
2|Argentina |
3|Australia |
1|Belgium |
2|Brazil |
2|Canada |
1|Switzerland |
3|China |
1|Germany |
1|Denmark |
4|Egypt |
1|France |
4|Israel |
3|India |
1|Italy |
3|Japan |
4|Kuwait |
3|Malaysia |
2|Mexico |
4|Nigeria |
1|Netherlands |
3|Singapore |
1|United Kingdom |
2|United States of America|
4|Zambia |
4|Zimbabwe |
3、算术表达式
select employee_id,first_name,last_name,salary,salary*(1+0.1) from hr.employees;
EMPLOYEE_ID|FIRST_NAME |LAST_NAME |SALARY|SALARY*(1+0.1)|
-----------+-----------+-----------+------+--------------+
198|Donald |OConnell | 2600| 2860|
199|Douglas |Grant | 2600| 2860|
200|Jennifer |Whalen | 4400| 4840|
201|Michael |Hartstein | 13000| 14300|
202|Pat |Fay | 6000| 6600|
203|Susan |Mavris | 6500| 7150|
204|Hermann |Baer | 10000| 11000|
205|Shelley |Higgins | 12008| 13208.8|
206|William |Gietz | 8300| 9130|
select employee_id,first_name,last_name,salary,salary*(1+0.1) new_salary from hr.employees;
EMPLOYEE_ID|FIRST_NAME |LAST_NAME |SALARY|NEW_SALARY|
-----------+-----------+-----------+------+----------+
198|Donald |OConnell | 2600| 2860|
199|Douglas |Grant | 2600| 2860|
200|Jennifer |Whalen | 4400| 4840|
201|Michael |Hartstein | 13000| 14300|
202|Pat |Fay | 6000| 6600|
203|Susan |Mavris | 6500| 7150|
204|Hermann |Baer | 10000| 11000|
205|Shelley |Higgins | 12008| 13208.8|
206|William |Gietz | 8300| 9130|
4、DISTINCT关键字
select distinct department_id from hr.employees;
DEPARTMENT_ID|
-------------+
100|
30|
|
20|
70|
90|
110|
50|
40|
80|
10|
60|
5、WHERE子句
SELECT column_list FROM table_name WHERE conditional_expression;
条件表达式
A=B
、A>B
、A<B
、A!=B或A<>B
、A LIKE B
、NOT <条件表达式>
。
select employee_id,first_name,last_name from hr.employees where first_name like 'B%';
EMPLOYEE_ID|FIRST_NAME|LAST_NAME|
-----------+----------+---------+
104|Bruce |Ernst |
193|Britney |Everett |
连接运算符
AND
、OR
。
select employee_id,first_name,last_name,salary from hr.employees where department_id=60 and salary>2000;
EMPLOYEE_ID|FIRST_NAME|LAST_NAME|SALARY|
-----------+----------+---------+------+
103|Alexander |Hunold | 9000|
104|Bruce |Ernst | 6000|
105|David |Austin | 4800|
106|Valli |Pataballa| 4800|
107|Diana |Lorentz | 4200|
select employee_id,first_name,last_name,department_id from hr.employees
where department_id=60 or department_id=30;
EMPLOYEE_ID|FIRST_NAME|LAST_NAME |DEPARTMENT_ID|
-----------+----------+----------+-------------+
114|Den |Raphaely | 30|
115|Alexander |Khoo | 30|
116|Shelli |Baida | 30|
117|Sigal |Tobias | 30|
118|Guy |Himuro | 30|
119|Karen |Colmenares| 30|
103|Alexander |Hunold | 60|
104|Bruce |Ernst | 60|
105|David |Austin | 60|
106|Valli |Pataballa | 60|
107|Diana |Lorentz | 60|
select employee_id,first_name,last_name,department_id from hr.employees
where (department_id=60) or (department_id=30);
NULL值
insert into hr.departments(department_id,department_name,manager_id) values(300,'TT',NULL);
# 错误用法
# 查询到的数据为空
select department_id,department_name,manager_id from hr.departments where manager_id=NULL;
select department_id,department_name,manager_id from hr.departments where manager_id IS NULL;
DEPARTMENT_ID|DEPARTMENT_NAME |MANAGER_ID|
-------------+--------------------+----------+
120|Treasury | |
130|Corporate Tax | |
140|Control And Credit | |
150|Shareholder Services| |
160|Benefits | |
170|Manufacturing | |
180|Construction | |
190|Contracting | |
200|Operations | |
210|IT Support | |
220|NOC | |
230|IT Helpdesk | |
240|Government Sales | |
250|Retail Sales | |
260|Recruiting | |
270|Payroll | |
300|TT | |
6、order by子句
SELECT column_list FROM table_name ORDER BY[(order by_expression[ASCIDESC])...]
select employee_id,first_name,last_name,salary from hr.employees
where salary>2000 order by salary;
EMPLOYEE_ID|FIRST_NAME |LAST_NAME |SALARY|
-----------+-----------+-----------+------+
132|TJ |Olson | 2100|
136|Hazel |Philtanker | 2200|
128|Steven |Markle | 2200|
127|James |Landry | 2400|
135|Ki |Gee | 2400|
191|Randall |Perkins | 2500|
119|Karen |Colmenares | 2500|
140|Joshua |Patel | 2500|
144|Peter |Vargas | 2500|
182|Martha |Sullivan | 2500|
131|James |Marlow | 2500|
198|Donald |OConnell | 2600|
199|Douglas |Grant | 2600|
118|Guy |Himuro | 2600|
select employee_id,first_name,last_name,salary from hr.employees
where salary>2000 order by salary desc;
EMPLOYEE_ID|FIRST_NAME |LAST_NAME |SALARY|
-----------+-----------+-----------+------+
100|Steven |King | 24000|
101|Neena |Kochhar | 17000|
102|Lex |De Haan | 17000|
145|John |Russell | 14000|
146|Karen |Partners | 13500|
201|Michael |Hartstein | 13000|
205|Shelley |Higgins | 12008|
108|Nancy |Greenberg | 12008|
147|Alberto |Errazuriz | 12000|
168|Lisa |Ozer | 11500|
148|Gerald |Cambrault | 11000|
174|Ellen |Abel | 11000|
select last_name,job_id,salary from hr.employees where salary>2000
order by job_id,salary desc;
LAST_NAME |JOB_ID |SALARY|
-----------+----------+------+
Gietz |AC_ACCOUNT| 8300|
Higgins |AC_MGR | 12008|
Whalen |AD_ASST | 4400|
King |AD_PRES | 24000|
De Haan |AD_VP | 17000|
Kochhar |AD_VP | 17000|
Faviet |FI_ACCOUNT| 9000|
Chen |FI_ACCOUNT| 8200|
Urman |FI_ACCOUNT| 7800|
Sciarra |FI_ACCOUNT| 7700|
Popp |FI_ACCOUNT| 6900|
Greenberg |FI_MGR | 12008|
7、group by子句
select job_id,salary from hr.employees order by job_id;
JOB_ID |SALARY|
----------+------+
AC_ACCOUNT| 8300|
AC_MGR | 12008|
AD_ASST | 4400|
AD_PRES | 24000|
AD_VP | 17000|
AD_VP | 17000|
FI_ACCOUNT| 7700|
FI_ACCOUNT| 8200|
FI_ACCOUNT| 6900|
FI_ACCOUNT| 7800|
FI_ACCOUNT| 9000|
COUNT
、MIN
、MAX
、SUM
、AVG
。
select job_id,avg(salary),sum(salary),max(salary),count(job_id) from hr.employees
group by job_id;
JOB_ID |AVG(SALARY)|SUM(SALARY)|MAX(SALARY)|COUNT(JOB_ID)|
----------+-----------+-----------+-----------+-------------+
AC_MGR | 12008| 12008| 12008| 1|
AC_ACCOUNT| 8300| 8300| 8300| 1|
IT_PROG | 5760| 28800| 9000| 5|
ST_MAN | 7280| 36400| 8200| 5|
AD_ASST | 4400| 4400| 4400| 1|
PU_MAN | 11000| 11000| 11000| 1|
SH_CLERK | 3215| 64300| 4200| 20|
AD_VP | 17000| 34000| 17000| 2|
FI_ACCOUNT| 7920| 39600| 9000| 5|
MK_MAN | 13000| 13000| 13000| 1|
PR_REP | 10000| 10000| 10000| 1|
FI_MGR | 12008| 12008| 12008| 1|
PU_CLERK | 2780| 13900| 3100| 5|
SA_MAN | 12200| 61000| 14000| 5|
MK_REP | 6000| 6000| 6000| 1|
AD_PRES | 24000| 24000| 24000| 1|
SA_REP | 8350| 250500| 11500| 30|
HR_REP | 6500| 6500| 6500| 1|
ST_CLERK | 2785| 55700| 3600| 20|
# 该语句是错误的,salary必须group by
select job_id,salary,avg(salary),sum(salary),max(salary),count(*)
from hr.employees group by job_id;
select department_id,job_id,avg(salary),sum(salary),max(salary),count(*) from hr.employees group by department_id,job_id;
DEPARTMENT_ID|JOB_ID |AVG(SALARY) |SUM(SALARY)|MAX(SALARY)|COUNT(*)|
-------------+----------+-----------------------------------------+-----------+-----------+--------+
110|AC_ACCOUNT| 8300| 8300| 8300| 1|
90|AD_VP | 17000| 34000| 17000| 2|
50|ST_CLERK | 2785| 55700| 3600| 20|
80|SA_REP |8396.551724137931034482758620689655172414| 243500| 11500| 29|
110|AC_MGR | 12008| 12008| 12008| 1|
50|ST_MAN | 7280| 36400| 8200| 5|
80|SA_MAN | 12200| 61000| 14000| 5|
50|SH_CLERK | 3215| 64300| 4200| 20|
20|MK_MAN | 13000| 13000| 13000| 1|
90|AD_PRES | 24000| 24000| 24000| 1|
60|IT_PROG | 5760| 28800| 9000| 5|
100|FI_MGR | 12008| 12008| 12008| 1|
30|PU_CLERK | 2780| 13900| 3100| 5|
100|FI_ACCOUNT| 7920| 39600| 9000| 5|
70|PR_REP | 10000| 10000| 10000| 1|
|SA_REP | 7000| 7000| 7000| 1|
10|AD_ASST | 4400| 4400| 4400| 1|
20|MK_REP | 6000| 6000| 6000| 1|
40|HR_REP | 6500| 6500| 6500| 1|
30|PU_MAN | 11000| 11000| 11000| 1|
# GROUP BY子句将使用ROLLUP运算符汇总JOB_ID列
select job_id,avg(salary),sum(salary),max(salary),count(*)
from hr.employees group by rollup(job_id);
JOB_ID |AVG(SALARY) |SUM(SALARY)|MAX(SALARY)|COUNT(*)|
----------+-----------------------------------------+-----------+-----------+--------+
AC_ACCOUNT| 8300| 8300| 8300| 1|
AC_MGR | 12008| 12008| 12008| 1|
AD_ASST | 4400| 4400| 4400| 1|
AD_PRES | 24000| 24000| 24000| 1|
AD_VP | 17000| 34000| 17000| 2|
FI_ACCOUNT| 7920| 39600| 9000| 5|
FI_MGR | 12008| 12008| 12008| 1|
HR_REP | 6500| 6500| 6500| 1|
IT_PROG | 5760| 28800| 9000| 5|
MK_MAN | 13000| 13000| 13000| 1|
MK_REP | 6000| 6000| 6000| 1|
PR_REP | 10000| 10000| 10000| 1|
PU_CLERK | 2780| 13900| 3100| 5|
PU_MAN | 11000| 11000| 11000| 1|
SA_MAN | 12200| 61000| 14000| 5|
SA_REP | 8350| 250500| 11500| 30|
SH_CLERK | 3215| 64300| 4200| 20|
ST_CLERK | 2785| 55700| 3600| 20|
ST_MAN | 7280| 36400| 8200| 5|
|6461.831775700934579439252336448598130841| 691416| 24000| 107|
8、HAVING子句
select job_id,avg(salary),sum(salary),max(salary),count(*)
from hr.employees group by job_id having avg(salary)>10000;
JOB_ID |AVG(SALARY)|SUM(SALARY)|MAX(SALARY)|COUNT(*)|
-------+-----------+-----------+-----------+--------+
AC_MGR | 12008| 12008| 12008| 1|
PU_MAN | 11000| 11000| 11000| 1|
AD_VP | 17000| 34000| 17000| 2|
MK_MAN | 13000| 13000| 13000| 1|
FI_MGR | 12008| 12008| 12008| 1|
SA_MAN | 12200| 61000| 14000| 5|
AD_PRES| 24000| 24000| 24000| 1|
9、多表连接查询
1、简单连接
# 笛卡尔积
select employee_id,last_name,department_name from hr.employees,hr.departments;
EMPLOYEE_ID|LAST_NAME |DEPARTMENT_NAME |
-----------+-----------+----------------+
198|OConnell |Administration |
199|Grant |Administration |
200|Whalen |Administration |
201|Hartstein |Administration |
202|Fay |Administration |
203|Mavris |Administration |
SELECT
语句的WHERE
子句提供了这个连接条件,可以有效避免笛卡尔积的出现。使用WHERE
子句限定时,只有第
一个表中的列与第二个表中相应列相互匹配后才会在结果集中显示,这是连接查询中最常用的形式。
select employee_id,last_name,department_name from hr.employees,hr.departments where hr.employees.department_id = hr.departments.department_id;
select employee_id,last_name,department_name from hr.employees,hr.departments
where hr.employees.department_id = hr.departments.department_id
and hr.departments.department_name = 'Shipping';
EMPLOYEE_ID|LAST_NAME |DEPARTMENT_NAME|
-----------+-----------+---------------+
198|OConnell |Shipping |
199|Grant |Shipping |
120|Weiss |Shipping |
121|Fripp |Shipping |
122|Kaufling |Shipping |
123|Vollman |Shipping |
124|Mourgos |Shipping |
125|Nayer |Shipping |
126|Mikkilineni|Shipping |
127|Landry |Shipping |
128|Markle |Shipping |
129|Bissot |Shipping |
130|Atkinson |Shipping |
131|Marlow |Shipping |
132|Olson |Shipping |
133|Mallin |Shipping |
134|Rogers |Shipping |
135|Gee |Shipping |
136|Philtanker |Shipping |
137|Ladwig |Shipping |
138|Stiles |Shipping |
139|Seo |Shipping |
140|Patel |Shipping |
141|Rajs |Shipping |
142|Davies |Shipping |
143|Matos |Shipping |
144|Vargas |Shipping |
180|Taylor |Shipping |
181|Fleaur |Shipping |
182|Sullivan |Shipping |
183|Geoni |Shipping |
184|Sarchand |Shipping |
185|Bull |Shipping |
186|Dellinger |Shipping |
187|Cabrio |Shipping |
188|Chung |Shipping |
189|Dilly |Shipping |
190|Gates |Shipping |
191|Perkins |Shipping |
192|Bell |Shipping |
193|Everett |Shipping |
194|McCain |Shipping |
195|Jones |Shipping |
196|Walsh |Shipping |
197|Feeney |Shipping |
select em.employee_id,em.last_name,dep.department_name from hr.employees em,hr.departments dep where em.department_id = dep.department_id
and dep.department_name='Shipping';
注意:如果为表指定了别名,那么语句中的所有子句都必须使用别名,而不允许再使用实际的表名。
# 会报错
select hr.employees.employee_id,hr.employees.last_name,dep.department_name
from hr.employees em,hr.departments dep
where em.department_id = dep.department_id
and dep.department_name = 'Shipping';
JOIN连接
FROM join_tablel join_type join_table2 [ON(join_condition)]
内连接
select em.employee_id,em.last_name,dep.department_name
from hr.employees em inner join hr.departments dep
on em.department_id = dep.department_id
where em.job_id = 'AD_ASST';
EMPLOYEE_ID|LAST_NAME|DEPARTMENT_NAME|
-----------+---------+---------------+
200|Whalen |Administration |
select em.employee_id,em.last_name,dep.department_name,j.job_title
from hr.employees em inner join hr.jobs j
on em.job_id = j.job_id
inner join hr.departments dep
on em.department_id = dep.department_id
where em.job_id = 'IT_PROG';
EMPLOYEE_ID|LAST_NAME|DEPARTMENT_NAME|JOB_TITLE |
-----------+---------+---------------+----------+
107|Lorentz |IT |Programmer|
106|Pataballa|IT |Programmer|
105|Austin |IT |Programmer|
104|Ernst |IT |Programmer|
103|Hunold |IT |Programmer|
自然连接
select em.employee_id,em.first_name,em.last_name,dep.department_name
from hr.employees em natural join hr.departments dep
where dep.department_name = 'Sales';
EMPLOYEE_ID|FIRST_NAME |LAST_NAME|DEPARTMENT_NAME|
-----------+-----------+---------+---------------+
150|Peter |Tucker |Sales |
151|David |Bernstein|Sales |
152|Peter |Hall |Sales |
153|Christopher|Olsen |Sales |
154|Nanette |Cambrault|Sales |
155|Oliver |Tuvault |Sales |
外连接
外连接分为左外连接(LEFT OUTER JOIN
或LEFT JOIN
)、右外连接(RIGHT OUTER JOIN
或RIGHT JOIN
)和全外连
接(FULL OUTER JOIN
或FULL JOIN
)三种。与内连接不同的是,外连接不只列出与连接条件相匹配的行,还列出
左表(左外连接时)、右表(右外连接时)或两个表(全外连接时)中所有符合搜索条件的数据行。
insert into hr.employees(employee_id,last_name,email,hire_date,job_id,department_id)
values(1000,'blaine','blaine@hotmail.com',to_date('2009-05-01','yyyy-mm-dd'),
'IT_PROG',null);
select em.employee_id,em.last_name,dep.department_name
from hr.employees em inner join hr.departments dep
on em.department_id = dep.department_id
where em.job_id = 'IT_PROG';
EMPLOYEE_ID|LAST_NAME|DEPARTMENT_NAME|
-----------+---------+---------------+
104|Ernst |IT |
103|Hunold |IT |
107|Lorentz |IT |
105|Austin |IT |
106|Pataballa|IT |
select em.employee_id,em.last_name,dep.department_name
from hr.employees em left outer join hr.departments dep
on em.department_id = dep.department_id
where em.job_id = 'IT_PROG';
EMPLOYEE_ID|LAST_NAME|DEPARTMENT_NAME|
-----------+---------+---------------+
107|Lorentz |IT |
106|Pataballa|IT |
105|Austin |IT |
104|Ernst |IT |
103|Hunold |IT |
1000|blaine | |
select em.employee_id,em.last_name,dep.department_name
from hr.employees em right outer join hr.departments dep
on em.department_id = dep.department_id
where dep.location_id = 1700;
EMPLOYEE_ID|LAST_NAME |DEPARTMENT_NAME |
-----------+----------+--------------------+
200|Whalen |Administration |
205|Higgins |Accounting |
206|Gietz |Accounting |
100|King |Executive |
101|Kochhar |Executive |
102|De Haan |Executive |
108|Greenberg |Finance |
109|Faviet |Finance |
110|Chen |Finance |
111|Sciarra |Finance |
112|Urman |Finance |
113|Popp |Finance |
114|Raphaely |Purchasing |
115|Khoo |Purchasing |
116|Baida |Purchasing |
117|Tobias |Purchasing |
118|Himuro |Purchasing |
119|Colmenares|Purchasing |
| |NOC |
| |Manufacturing |
| |Recruiting |
| |Government Sales |
| |Operations |
| |IT Support |
| |Benefits |
| |Treasury |
| |Payroll |
| |Corporate Tax |
| |Shareholder Services|
| |Construction |
| |Retail Sales |
| |Contracting |
| |IT Helpdesk |
| |Control And Credit |
select em.employee_id,em.last_name,dep.department_name
from hr.employees em full outer join hr.departments dep
on em.department_id=dep.department_id
where dep.location_id = 1700 or em.job_id = 'IT_PROG';
EMPLOYEE_ID|LAST_NAME |DEPARTMENT_NAME |
-----------+----------+--------------------+
200|Whalen |Administration |
205|Higgins |Accounting |
206|Gietz |Accounting |
1000|blaine | |
100|King |Executive |
101|Kochhar |Executive |
102|De Haan |Executive |
103|Hunold |IT |
104|Ernst |IT |
105|Austin |IT |
106|Pataballa |IT |
107|Lorentz |IT |
108|Greenberg |Finance |
109|Faviet |Finance |
110|Chen |Finance |
111|Sciarra |Finance |
112|Urman |Finance |
113|Popp |Finance |
114|Raphaely |Purchasing |
115|Khoo |Purchasing |
116|Baida |Purchasing |
117|Tobias |Purchasing |
118|Himuro |Purchasing |
119|Colmenares|Purchasing |
| |NOC |
| |Manufacturing |
| |Government Sales |
| |IT Support |
| |Benefits |
| |Shareholder Services|
| |Retail Sales |
| |Control And Credit |
| |Recruiting |
| |Operations |
| |Treasury |
| |Payroll |
| |Corporate Tax |
| |Construction |
| |Contracting |
| |IT Helpdesk |
自连接
select employee_id,last_name,job_id,manager_id
from hr.employees order by employee_id;
select eml.last_name "manager" ,em2.last_name "employee"
from hr.employees eml left join hr.employees em2
on eml.employee_id = em2.manager_id
order by eml.employee_id;
manager |employee |
-----------+-----------+
King |Cambrault |
King |De Haan |
King |Errazuriz |
King |Fripp |
King |Hartstein |
King |Kaufling |
King |Kochhar |
King |Mourgos |
King |Partners |
King |Raphaely |
King |Russell |
King |Vollman |
King |Weiss |
King |Zlotkey |
Kochhar |Baer |
Kochhar |Higgins |
Kochhar |Greenberg |
Kochhar |Mavris |
Kochhar |Whalen |
1.5 集合操作
集合操作就是将两个或多个SQL查询结果合并构成复合查询,以完成一些特殊的任务需求。集合操作主要由集合操
作符实现,常用的集合操作符包括UNION
(并运算)、UNION ALL
、INTERSECT
(交运算)和MINUS
(差运算)。
1、UNION
select employee_id,last_name from hr.employees
where last_name like 'C%' or last_name like 'S%'
union
select employee_id,last_name from hr.employees
where last_name like 'S%' or last_name like 'T%';
EMPLOYEE_ID|LAST_NAME |
-----------+----------+
110|Chen |
111|Sciarra |
117|Tobias |
119|Colmenares|
138|Stiles |
139|Seo |
148|Cambrault |
150|Tucker |
154|Cambrault |
155|Tuvault |
157|Sully |
159|Smith |
161|Sewall |
171|Smith |
176|Taylor |
180|Taylor |
182|Sullivan |
184|Sarchand |
187|Cabrio |
188|Chung |
注意:UNION
运算会将合集中的重复记录滤除,这是UNION
运算和UNION ALL
运算唯一不同的地方。
2、UNION ALL
select employee_id,last_name from hr.employees
where last_name like 'C%' or last_name like 'S%'
union all
select employee_id,last_name from hr.employees
where last_name like 'S%' or last_name like 'T%';
EMPLOYEE_ID|LAST_NAME |
-----------+----------+
187|Cabrio |
148|Cambrault |
154|Cambrault |
110|Chen |
188|Chung |
119|Colmenares|
184|Sarchand |
111|Sciarra |
139|Seo |
161|Sewall |
159|Smith |
171|Smith |
138|Stiles |
182|Sullivan |
157|Sully |
184|Sarchand |
111|Sciarra |
139|Seo |
161|Sewall |
159|Smith |
171|Smith |
138|Stiles |
182|Sullivan |
157|Sully |
176|Taylor |
180|Taylor |
117|Tobias |
150|Tucker |
155|Tuvault |
3、INTERSECT
select employee_id,last_name from hr.employees
where last_name like 'C%' or last_name like 'S%'
intersect
select employee_id,last_name from hr.employees
where last_name like 'S%' or last_name like 'T%';
EMPLOYEE_ID|LAST_NAME|
-----------+---------+
111|Sciarra |
138|Stiles |
139|Seo |
157|Sully |
159|Smith |
161|Sewall |
171|Smith |
182|Sullivan |
184|Sarchand |
4、MINUS
select employee_id,last_name from hr.employees
where last_name like 'C%' or last_name like 'S%'
minus
select employee_id,last_name from hr.employees
where last_name like 'S%' or last_name like 'T%';
EMPLOYEE_ID|LAST_NAME |
-----------+----------+
110|Chen |
119|Colmenares|
148|Cambrault |
154|Cambrault |
187|Cabrio |
188|Chung |
1.6 子查询
1、IN关键字
select employee_id,last_name,department_id
from hr.employees
where department_id in(
select department_id
from hr.departments
where location_id=1700);
EMPLOYEE_ID|LAST_NAME |DEPARTMENT_ID|
-----------+----------+-------------+
200|Whalen | 10|
205|Higgins | 110|
206|Gietz | 110|
100|King | 90|
101|Kochhar | 90|
102|De Haan | 90|
108|Greenberg | 100|
109|Faviet | 100|
110|Chen | 100|
111|Sciarra | 100|
112|Urman | 100|
113|Popp | 100|
114|Raphaely | 30|
115|Khoo | 30|
116|Baida | 30|
117|Tobias | 30|
118|Himuro | 30|
119|Colmenares| 30|
2、EXISTS关键字
select employee_id,last_name from hr.employees em
where exists(
select * from hr.departments dep
where em.department_id = dep.department_id
and location_id=1700);
EMPLOYEE_ID|LAST_NAME |
-----------+----------+
200|Whalen |
119|Colmenares|
118|Himuro |
117|Tobias |
116|Baida |
115|Khoo |
114|Raphaely |
102|De Haan |
101|Kochhar |
100|King |
113|Popp |
112|Urman |
111|Sciarra |
110|Chen |
109|Faviet |
108|Greenberg |
206|Gietz |
205|Higgins |
3、比较运算符
=
、<>
、<
、>
、<=
、>=
。
select employee_id,last_name,job_id,salary from hr.employees
where job_id = 'PU_MAN' and
salary >= (select avg(salary) from hr.employees
where job_id = 'PU_MAN');
EMPLOYEE_ID|LAST_NAME|JOB_ID|SALARY|
-----------+---------+------+------+
114|Raphaely |PU_MAN| 11000|
1.4 数据操纵DML(INSERT、UPDATE、DELETE)
1.4.1 INSERT
1、一般INSERT语句
INSERT INTO[user.]table[@db_link][(column1[,column2]...)]
VALUES(express1[,express2]...)
insert into jobs(job_id,job_title,min_salary,max_salary)
values('IT_TEST','测试员',3000.00,8000.00);
SELECT * FROM hr.jobs;
JOB_ID |JOB_TITLE |MIN_SALARY|MAX_SALARY|
----------+-------------------------------+----------+----------+
IT_TEST |测试员 | 3000| 8000|
AD_PRES |President | 20080| 40000|
AD_VP |Administration Vice President | 15000| 30000|
AD_ASST |Administration Assistant | 3000| 6000|
FI_MGR |Finance Manager | 8200| 16000|
FI_ACCOUNT|Accountant | 4200| 9000|
AC_MGR |Accounting Manager | 8200| 16000|
AC_ACCOUNT|Public Accountant | 4200| 9000|
SA_MAN |Sales Manager | 10000| 20080|
SA_REP |Sales Representative | 6000| 12008|
PU_MAN |Purchasing Manager | 8000| 15000|
PU_CLERK |Purchasing Clerk | 2500| 5500|
ST_MAN |Stock Manager | 5500| 8500|
ST_CLERK |Stock Clerk | 2008| 5000|
SH_CLERK |Shipping Clerk | 2500| 5500|
IT_PROG |Programmer | 4000| 10000|
MK_MAN |Marketing Manager | 9000| 15000|
MK_REP |Marketing Representative | 4000| 9000|
HR_REP |Human Resources Representative | 4000| 9000|
PR_REP |Public Relations Representative| 4500| 10500|
SQL> desc jobs;
名称 是否为空? 类型
----------------------------------------- -------- ----------------------------
JOB_ID NOT NULL VARCHAR2(10)
JOB_TITLE NOT NULL VARCHAR2(35)
MIN_SALARY NUMBER(6)
MAX_SALARY NUMBER(6)
insert into hr.jobs values('IT_DBA','数据库管理员',5000.00,15000.00);
insert into hr.jobs(job_id,job_title,min_salary) values('PP_MAN','产品经理',5000.00);
JOB_ID |JOB_TITLE |MIN_SALARY|MAX_SALARY|
----------+-------------------------------+----------+----------+
IT_TEST |测试员 | 3000| 8000|
IT_DBA |数据库管理员 | 5000| 15000|
PP_MAN |产品经理 | 5000| |
AD_PRES |President | 20080| 40000|
AD_VP |Administration Vice President | 15000| 30000|
AD_ASST |Administration Assistant | 3000| 6000|
FI_MGR |Finance Manager | 8200| 16000|
FI_ACCOUNT|Accountant | 4200| 9000|
AC_MGR |Accounting Manager | 8200| 16000|
AC_ACCOUNT|Public Accountant | 4200| 9000|
SA_MAN |Sales Manager | 10000| 20080|
SA_REP |Sales Representative | 6000| 12008|
PU_MAN |Purchasing Manager | 8000| 15000|
PU_CLERK |Purchasing Clerk | 2500| 5500|
ST_MAN |Stock Manager | 5500| 8500|
ST_CLERK |Stock Clerk | 2008| 5000|
SH_CLERK |Shipping Clerk | 2500| 5500|
IT_PROG |Programmer | 4000| 10000|
MK_MAN |Marketing Manager | 9000| 15000|
MK_REP |Marketing Representative | 4000| 9000|
HR_REP |Human Resources Representative | 4000| 9000|
PR_REP |Public Relations Representative| 4500| 10500|
2、批量INSERT
INSERT INTO[user.]table[@db_link][(column1[,column2]...)]Subquery
其中,Subquery
是子查询语句,可以是任何合法的SELECT
语句,其所选列的个数和类型应该与前边的column
相对应。
insert into IT_EMPLOYEES(
employee_id,first_name,last_name,email,phone_number,job_id,salary,manager_id)
select em.employee_id,em.first_name,em.last_name,em.email,em.phone_number,em.job_id,em.salary,em.manager_id from hr.employees em,hr.departments dep
where em.department_id = dep.department_id
and dep.department_name='IT';
SELECT * FROM IT_EMPLOYEES;
EMPLOYEE_ID|FIRST_NAME|LAST_NAME|EMAIL |PHONE_NUMBER|JOB_ID |SALARY|MANAGER_ID|BIRTH_DATE|
-----------+----------+---------+--------+------------+-------+------+----------+----------+
103|Alexander |Hunold |AHUNOLD |590.423.4567|IT_PROG| 9000| 102| |
104|Bruce |Ernst |BERNST |590.423.4568|IT_PROG| 6000| 103| |
105|David |Austin |DAUSTIN |590.423.4569|IT_PROG| 4800| 103| |
106|Valli |Pataballa|VPATABAL|590.423.4560|IT_PROG| 4800| 103| |
107|Diana |Lorentz |DLORENTZ|590.423.5567|IT_PROG| 4200| 103| |
1.4.2 UPDATE
UPDATE table_name SET{columnl=express1[,column2=express2]
(columnl[,column2])=(select query)}
[WHERE condition]
update hr.employees
set salary = salary*1.15
where job_id = 'IT_PROG';
update hr.employees
set salary = (select avg(salary) from hr.employees
where job_id = 'IT_PROG') where employee_id = 104;
1.4.3 DELETE
DALETE FROM table_name
[WHERE condition]
delete from it_employees where employee_id = 107;
1.4.4 TRUNCATE语句
truncate table hr.it_employees;
select employee_id,last_name from hr.it_employees;
EMPLOYEE_ID|LAST_NAME|
-----------+---------+
在TRUNCATE
语句中还可以使用关键字REUSE STORAGE
,表示删除记录后仍然保存记录占用的空间;与此相反,
也可以使用DROP STORAGE
关键字,表示删除记录后立即回收记录占用的空间。TRUNCATE
语句默认为使用
DROP STORAGE
关键字。使用关键字REUSE STORAGE
保留删除记录后的空间的TRUNCATE
语句如下:
truncate table it_employees reuse storage;
1.5 数据控制DCL(GRANT、REVOKE)
1.5.1 GRANT语句
SQL
用GRANT
语句向用户授予操作权限,GRANT
语句的一般格式为:
GRANT<权限>[,<权限>]...
[ON<对象类型><对象名>]
TO<用户>[,<用户>]...
[WITH GRANT OPTION]
对于不同类型的操作对象有不同的操作权限,对属性列和视图的操作权限包括查询(SELECT
)、插入(INSERT
)、修
改(UPDATE
)、删除(DELETE
)以及这4种权限的总和(ALLPRIVILEGES
)。对基表的操作权限包括查询、插入、修
改、删除、修改表(ALTER)和建立索引(INDEX)以及这六种权限的总和。对数据库可以有建立表(CREATETAB
)的权
限,该权限属于DBA,可由DBA 授予普通用户,普通用户拥有此权限后可以建立基表,基表的所有者(Owner)拥有
对该表的一切操作权限。
对象 | 对象类型 | 操作权限 |
---|---|---|
属性列 | TABLE COLUMN | SELECT、INSERT、UPDATE、DELETE、ALL PRIVILEGES |
视图 | TABLE VIEW | SELECT、INSERT、UPDATE、 DELETE、ALL PRIVILEGES |
基表 | TABLE | SELECT、INSERT、UPDATE、DELETE、ALTER、INDEX、ALL PRIVILEGES |
数据库 | DATABASE | CREATETAB |
接受权限的用户可以是一个或多个具体用户,也可以是PUBLIC
,即全体用户。如果指定了WITH GRANT
OPTION
子句,则获得某种权限的用户还可以把这种权限再授予其他的用户。如果没有指定WITH GRANT
OPTION
子句,则获得某种权限的用户只能使用该权限,但不能传播该权限。
请输入用户名: sys as sysdba
输入口令:
连接到:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
# 创建用户
create user User1 identified by 123456;
# 把查询IT_EMPLOYEES表的权限授给用户User1
GRANT SELECT ON IT_EMPLOYEES TO User1;
# 把对IT_EMPLOYEES表的全部操作权限授予用户User2和User3。
create user User2 identified by 123456;
create user User3 identified by 123456;
GRANT ALL PRIVILEGES ON IT_EMPLOYEES TO User2,User3;
# 把对表DEPARTMENTS的查询权限授予所有用户
GRANT SELECT ON hr.DEPARTMENTS TO PUBLIC;
# 把查询IT_EMPLOYEES表和修改雇员编号的权限授给用户User4
create user User4 identified by 123456;
GRANT UPDATE(EMPLOYEE_ID),SELECT ON IT_EMPLOYEES TO User4;
# 把对表DEPARTMENTS的INSERT权限授予User5用户,并允许将此权限再授予其他用户
create user User5 identified by 123456;
GRANT INSERT ON hr.DEPARTMENTS TO User5 WITH GRANT OPTION;
# User5将此权限授予User6
create user User6 identified by 123456;
GRANT INSERT ON hr.DEPARTMENTS TO User6 WITH GRANT OPTION;
# User6 将此权限授予User7
create user User7 identified by 123456;
GRANT INSERT ON hr.DEPARTMENTS TO User7;
# DBA把建立表的权限授予用户User8
create user User8 identified by 123456;
GRANT create table TO User8;
1.5.2 REVOKE语句
授予的权限可以由DBA
或其他授权者用REVOKE
语句收回。
REVOKE<权限>[,<权限>]..
[ON<对象类型><对象名>]
FROM<用户>[,<用户>]...;
# 把用户User4修改雇员编号的权限收回
REVOKE UPDATE on IT_EMPLOYEES FROM User4;
# 收回所有用户对表DEPARTMENTS的查询权限。
REVOKE SELECT ON hr.DEPARTMENTS FROM PUBLIC;
# 把用户User5对DEPARTMENTS表的INSERT权限收回
REVOKE INSERT ON hr.DEPARTMENTS FROM User5;
1.6 Oracle常用函数
1.6.1 字符串类函数
1、ASCII(<c1>)
该函数用于返回c1
第一个字母的ASCII
码,其中c1
是字符串。它的逆函数是CHR()
。
select ASCII('A') BIG_A,ASCII('a') SMALL_A FROM dual;
BIG_A|SMALL_A|
-----+-------+
65| 97|
2、CHR(<i>)
该函数用于求i
对应的ASCII
字符,其中i
是一个数字。
select CHR(65),CHR(97) FROM dual;
CHR(65)|CHR(97)|
-------+-------+
A |a |
3、CONCAT(cl,c2)
该函数将c2
连接到c1
的后面,如果cl
为null
,将返回c2
;如果c2
为null
,则返回cl
;如果c1、c2
都为
null
,则返回null
。其中,c1、c2
均为字符串,它和操作符|
返回的结果相同。
select concat('oracle','11g') name from dual;
NAME |
---------+
oracle11g|
4、INITCAP(c1)
该函数将cl
中每个单词的第一个字母大写,其他字母小写返回。单词由空格、控制字符、标点符号限制。其中
c1
为字符串。
select INITCAP('oracle universal installer') name from dual;
NAME |
--------------------------+
Oracle Universal Installer|
5、INSTR(cl,[c2,<i>[,j]])
该函数用于返回c2
在c1
中第j
次出现的位置,搜索从c1
的第i
个字符开始。当没有发现需要的字符时返回0,如
果i
为负数,那么搜索将从右到左进行,但是位置还是按从左到右来计算,i和j的默认值为1。其中,cl、c2均为字
符串,i、j为整数。
select INSTR('Moisossoppo','o',3,3) from dual;
INSTR('MOISOSSOPPO','O',3,3)|
----------------------------+
11|
select INSTR('Moisossoppo','o',-2,3)from dual;
INSTR('MOISOSSOPPO','O',-2,3)|
-----------------------------+
2|
提示:INSTRB(cl,[c2,<i>[j]])
与 INSTRO
函数一样,只是其返回的是字节,对于单字节INSTRBO
等于
INSTRO
。
6、LENGTH(c1)
该函数用于返回c1
的长度,如果cl为null,那么将返回null值。其中c1为字符串。
select LENGTH('Oracle 11g') name from dual;
NAME|
----+
10|
7、LOWER(c1)
该函数用于返回c1的小写字符,经常出现在 WHERE子串中。
select LOWER(job_id) from hr.JOBS WHERE LOWER(job_id) LIKE 'it%';
LOWER(JOB_ID)|
-------------+
it_dba |
it_prog |
it_test |
8、LTRIM(cl,c2)
该函数表示将c1中最左边的字符去掉,使其第一个字符不在c2中,如果没有c2,那么cl就不会改变。
select LTRIM('Moisossoppo','Mois') from dual;
LTRIM('MOISOSSOPPO','MOIS')|
---------------------------+
ppo |
9、REPLACE(c1,c2[,c3])
该函数用c3代替出现在cl中的c2后返回,其中cl、c2、c3都是字符串。
select REPLACE('feelblue','blue','yellow') from dual;
REPLACE('FEELBLUE','BLUE','YELLOW')|
-----------------------------------+
feelyellow |
10、SUBSTR(c1,<i>[j])
该函数表示从cl的第i位开始返回长度为j的子尾部。其中,cl为一字符串,i、j为整数。
select SUBSTR('Message',1,4) from dual;
SUBSTR('MESSAGE',1,4)|
---------------------+
Mess |
1.6.2 数字类函数
数字函数操作数字数据,执行数学和算术运算。所有函数都有数字参数并返回数字值。需要注意的是所有三角函数
的操作数和值都是弧度而不是角度。同时,在Oracle中并没有提供内建的弧度和角度的转换函数。
1.6.3 日期类函数
日期函数操作DATE
数据类型,绝大多数都有DATE
数据类型的参数,且其返回值也大都为DATE
数据类型。
1.6.4 转换类函数
转换函数用于操作多数据类型,在数据类型之间进行转换。在使用 SQL 语句进行数据操作时,经常使用到这一类
函数。
1.6.5 聚集类函数
聚集类函数也称为集合函数,返回基于多个行的单一结果,行的准确数量无法确定,除非查询被执行并且所有的结
果都被包含在内。与单行函数不同的是,在解析时所有的行都是已知的。由于这种差别使聚集类函数与单行函数在
要求和行为上有微小的差异。
Oracle提供了丰富的聚集类函数。这些函数可以在SELECT
或SELECT
的HAVING
子句中使用,当用于SELECT
子句
时常常与GROUP BY
一起使用。
至此,SQL基础介绍完毕。