您的位置:首页 > 数据库

sql扫盲(2)

2015-08-26 11:24 357 查看
1、多表连接查询:使用“=”连接

select table1.column,table2.column from table1,table2 where table1.column1 = table2.column2;


可以使用别名简化查询:


`select  e.employee_id,e.last_name,e.department_id,d.department_id,
d.location_id from employees e,departments d
where e.department_id = d.department_id`


(2)非等值连接:例如使用between … and

select e.last_name,e.salary,j.grade_level from employees e, job_grades j where e.salary between j.lowest_sal and j.hightest_sal


(3)内连接:合并具有同一列的两个以上的表的行, 结果集中不包含一个表与另一个表不匹配的行,使用内连接可以获取两表公共部分的记录,下面两条语句的效果都是一样的

select * from A join B on A.id = B.nameid


select * from A,B where A.id = B.nameid


(4)外连接:两个表在连接过程中除了返回满足连接条件的行以外还返回左(或右)表中不满足条件的行 ,这种连接称为左(或右) 外连接。外连接的符号是 (+)

select table1.column,table2.column from table1,table2 where table1.column(+)=table2.column


select table1.column,table2.column from table1,table2 where table1.column = table2.column(+)


还可以使用 (left/right)join on进行连接

左连接:

select * from A left join B on A.id = B.nameid


右连接:

select * from A right join B on A.id = B.nameid


(5)自连接:同一张表之间的连接,比如有两张相同结构的employee表,一张存放manager的数据,另一张存放worker的数据

select worker.last_name || 'works for' || manager.last_name from employees worker, employees manager where worker.manager_id = manager.employees_id;


(6)交叉连接:使用cross join 子句使连接的表产生叉集,叉集和笛卡尔集是相同的。

select last_name,department_name from employees cross join departments


以上代码产生的条目总数是employees表和departments表条目数之和

(7)自然连接:使用natural join 会以两个表中具有相同名字的列为条件创建等值连接。在表中查询满足等值条件的数据,但如果只是列名相同而数据类型不同,则会产生错误。

select department_id,department_name,location_id,city from departments natuaral join locations


(8)使用USING子句创建连接:在NATURAL JOIN 子句创建等值连接时,可以使用 USING 子句指定等值连接中需要用到的列。

select e.employee_id,e.last_name,d.location_id from employees e join departments d USING (department_id)


以上代码产生的表仅有一行department_id结构

(9)可以使用 ON 子句指定额外的连接条件:这个连接条件是与其它条件分开的,ON 子句使语句具有更高的易读性。

select e.employee_id,e.last_name,e.department_id,d.department_id,d.location_id from employees e join departments d on (e.department_id = d.department_id)


此时产生的表将会有两行department_id记录

(10)使用on子句创建多表连接

select employee_id,city,department_name from employees e join departments d on d.department_id = e.department_id join locations l on d.location_id = l.location_id


2、分组函数:分组函数作用于一组数据,并对一组数据返回一个值。

(1)分组函数类别:AVG、COUNT、MAX、MIN、STDDEV、SUM

(2)分组函数语法:

select [column] group_function(column),...
from table
[where condition]
[group by column]
[order by column];


(3)AVG(平均值)、SUM(合计)、MIN(最小值)、MAX(最大值)

select AVG(salary),MAX(salary),MIN(salary),SUM(salary) from employees where job_id like '%REP%';


(4)COUNT计数函数

count(*)返回表中记录总数

select count(*) from employees where department_id = 50;


count(expr)返回expr不为空的记录总数

count(distinct expr) expr不为空且不重复的记录总数

(5)组函数与空值

组函数是忽略空值的,但是可以使用NVL函数使分组函数无法忽略空值。

select AVG(NVL(commission_pct,0)) from employees;


(6)GROUP BY:可以使用GROUP BY 子句将表中的数据分成若干组

例如求出employees表中各部门的平均工资

select department_id,AVG(salary) from employees group by department_id


使用多个列分组

select department_id dept_id,job_id,SUM(salary) from employees group by department_id,job_id;


(7)不能再where中使用组函数,可以在HAVING中使用组函数

例如以下写法是错误的

select department_id,AVG(salary) from employees where AVG(salary)>8000 group by department_id;


使用 HAVING 过滤分组:

1. 行已经被分组。

2. 使用了组函数。

3. 满足HAVING 子句中条件的分组将被显示。

select department_id,MAX(salary) from employees group by department_id HAVING MAX(salary)>10000;


3、子查询

(1)子查询 (内查询) 在主查询之前一次执行完成。子查询的结果被主查询使用 (外查询)。

select last_name from employees where salary>
(select salary from employees where last_name = ‘Abel')


(2)多行子查询

IN 等于列表中的任何一个

ANY 和子查询返回的任意一个值比较

ALL和子查询返回的所有值比较

例如

select employee_id,last_name,job_id,salary from employees where salary<ANY
(select salary from employees where job_id = 'IT_PROG')
AND job_id<>'IT_PROG';


4、处理数据

在 INSERT 语句中加入子查询。

insert  into sales_reps(id,name,salary,commission_pct)
select employee_id,last_name,salary,commission_pct
from employees where job_id like '%rep%';


不必书写 VALUES 子句。

子查询中的值列表应与 INSERT 子句中的列名对应

5、数据库隔离级别

(1)三个概念:

脏读: 对于两个事物 T1, T2, T1 读取了已经被 T2 更新但还没有被提交的字段. 之后, 若 T2 回滚, T1读取的内容就是临时且无效的.

不可重复读: 对于两个事物 T1, T2, T1 读取了一个字段, 然后 T2 更新了该字段. 之后, T1再次读取同一个字段, 值就不同了.

幻读: 对于两个事物 T1, T2, T1 从一个表中读取了一个字段, 然后 T2 在该表中插入了一些新的行. 之后, 如果 T1 再次读取同一个表, 就会多出几行.

(2)数据库隔离级别

READ UNCOMMITTED :允许事务读取未被其他事务提交的变更,脏读,不可重复读、幻读的问题都会出现

READ COMMITED:只允许事务读取已经被其他事务提交的变更,可以避免脏读,但不可避免可重复读和幻读

REPEATABLE READ:确保事务可以多次从一个字段读取相同的值,在这个事务持续期间,禁止其他事务对这个字段进行更新,可以避免脏读和不可重复读,但是幻读的问题依然存在

SERIALIZABLE:确保事务可以从一个表中读取相同的行,在这个事务持续期间,禁止其他事务对该表执行插入、更新和删除操作,所有并发事务都可以避免,但性能十分低下

Oracle 支持的 2 种事务隔离级别:READ COMMITED, SERIALIZABLE. Oracle 默认的事务隔离级别为: READ COMMITED

Mysql 支持 4 中事务隔离级别. Mysql 默认的事务隔离级别为: REPEATABLE READ
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: