一、in的用法。 select ename,deptno from emp where sal in(800,1250) in 里面可以是一个结果集,是一个sql语句. 当然也可用not in 二、操作符优先级,* / + - 用括号可以改变这种优先级, 在sql中 .... and (d_isactve is null or d_isactive ==0) 这个在项目有遇到过,一个字段需要两种不同的条件判断, 用可以加个括号。 三、like %表示零个或者多个字符,_表示一个字符,均可以表示汉字和字母。 查询first的第三个字母是a的员工 select * from emp where first like '__a%'; 使用ESCAPE 标识符来查找带特殊符号的字符串 如果需要模糊查询的字符串中包含了作为通配符的”%”和”_”, 在这种情况下需要使用escape标识符来说明哪些是字符串的字符,哪些是通配符号 select * from feng where name like '%\%f%' escape '\' ; select * from feng where name like '%\%f\_%' escape '\'; --escape ‘\‘ 表示‘’\’后边的是字符串中的内容, ‘’\’ 可以用其它的字符来代替 四、空值,一定是 is null 或者 is not NULL.绝对没有==null这种东西。 五、逻辑运算符:and or not.用括号可以改变其优先级,在项目中遇到过。 not ->and -->or 运算顺序。用括号可以改变其优先级,在项目中遇到过。这点十分重要, 一定要谨记。 select * from emp where dep = 't' or dep = 'q' and salary >= 1500; 一定要明白这个结果是什么,先运算and ,再运算Or。 数学运算符和逻辑运算符,而且括号都可以改变运算顺序,十分好的。 六、著名的 order by 1、它一定是出现select语句的最后,有什么其它条件肯定要插在它的前面。 2、使用ORDER BY 子句根据某个字段所得结果记录排序ASC: 升序,缺省DESC: 降序 3、order by 后面所根据的字段,可以使用列的别名排序。 4、对多字段进行的方式,十分重要,十分好。 在进行排序的时候,也可以按照多个字段进行排序, 但是多字段排序要注意,必须对每个字段设置排序方式, 也就是说,不管是ASC还是DESC,都只是针对单个字段的设置, 所以在多字段排序中,需要设置每个字段的排序方式, 而且每个字段的排序方式不同也是可以的。 SELECT last_name, department_id, salary FROM employees ORDER BY department_id desc, salary asc; 首先会根据部门ID把部门结果按照部门的降序排列, 然后在每一个相同的ID部门里面,其工资又是按照升序 排列的,十分好的,十分有效。 六、函数。 当你寻找不到答案的时间,就去看官方的文档 。 常用的分组函数(各个数据库通用) AVG ([DISTINCT|ALL]n) COUNT ({ *|[DISTINCT|ALL]expr})--返回的是不重复的,这个字段非空的集合。 MAX ([DISTINCT|ALL]expr) MIN ([DISTINCT|ALL]expr) SUM ([DISTINCT|ALL]n) --********************************************************************************************************** --聚合函数 --在数字类型数据使用AVG and SUM 函数 --AVG:计算平均值 --SUM:计算总和 --输出员工工资的总和,工资的平均值 select sum(salary),avg(salary) from employees --输出员工表10号部门员工工资的总和,工资的平均值 select sum(salary),avg(salary) from employees where department_id=10 --MIN and MAX适用于任何数据类型 --MIN: 计算最小值 --MAX:计算最大值 --输出员工表中工资的最大值和最小值 select max(salary),min(salary) from employees --输出20号部门中工资的最大值和最小值 select max(salary),min(salary) from employees where department_id=20 --COUNT(*)返回表中所有符合条件的记录数 --查询有多少员工 select count(*) from employees --COUNT(字段) 返回所有符合条件并且字段值非空的记录 --带条件查询 --查询10号部门有多少员工 select count(employee_id) from employees select count(employee_id) from employees where department_id=10 --count(distinct(expr))返回不重复的,非空值的数量 --查询10号部门的工种数量 select count(distinct(job_id)) from employees where department_id=10 --分组函数在计算时省略列中的空值 --计算30号部门员工工资的平均工资 select avg(salary) from employees where department_id=30 --NVL函数迫使分组函数包括空值 --计算30号部门员工工资的平均工资 select avg(nvl(salary,0)) from employees where department_id=30 --***************************************************************************************************************** --分组的语法结构 SELECT column, group_function FROM table [WHERE condition] [GROUP BY group_by_expression] [ORDER BY column]; order by 始终是在最后的。 --查询每个部门工资的最大值,最小值 需求:输出结果如下 department_id max(salary),min(salary) 10 5000 1000.00 20 6000 1000.00 30..... select department_id,max(salary),min(salary) from employees group by department_id --你会发现select后面的必须出现在group by后面。 order by department_id asc --这个语句太厉害了,找出的各个部门中,所有工资的最大值,和最小值。 --pw --使用groupby子句的注意事项 --1、出现在SELECT列表中的字段,如果出现的位置不是在组函数中,那么必须出现在GROUP BY子句中 select department_id,job_id,max(salary),min(salary) from employees group by department_id,job_id --这里必须加上job_id,否则出错,也就是说在select之后的字段,必须要在 group by后面出现。 --2、在GROUP BY 子句中出现的字段,可以不出现在SELECT列表中 select max(salary),min(salary) from employees group by department_id --对多列分组 --一查询部门编号和工种并按 部门编号 和 工种分组 select department_id,job_id from employees group by department_id,job_id --不能在 WHERE 子句中限制组. --限制组必须使用 HAVING 子句. --不能在 WHERE 子句中使用组函数 语法结构: --使用HAVING子句对分组的结果进行限制 SELECT column, group_function FROM table [WHERE condition] [GROUP BY group_by_expression] [HAVING group_condition] [ORDER BY column]; --select语句的执行流程 * 先执行where子句,对数据进行过滤 * 过滤后的数据再用group by子句分组 * 分组后的数据再用 HAVING子句进行组函数过滤 * 最后,对查询的数据排序。 --按部门进行分组,输出部门id,部门的平均工资,要求平均工资>2000 select department_id,avg(salary) from employees group by department_id having avg(salary)>2000 order by department_id --按部门进行分组,输出部门id,部门的平均工资,要求平均工资>2000,并且部门不为null,并且不是10号部门 select department_id,avg(salary) from employees where department_id is not null and department_id<>10 group by department_id having avg(salary)>2000 order by department_id 大多数集合函数都能在计算时消除空值;COUNT函数则属于例外。 对包含空值的一个列使用COUNT函数,空值会从计算中消除。 但假如COUNT函数使用一个星号,它就计算所有行,而不管是否存在空值。 如果希望COUNT函数对给定列的所有行(包括空值)进行计数, 请使用ISNULL函数。ISNULL函数会将空值替换成有效的值。 事实上,对集合函数来说,如果空值可能导致错误结果, ISNULL函数就非常有用。记住在使用一个星号时,COUNT函数会对所有行进行计算。 ---多表连接和子查询。 --自连接与基本连接是一样的,只是把它看成两张表就OK了。 连接的概念: 连接分为条件连接、等值连接和自然连接三种。 1、条件连接就是在多个表的笛卡尔积中选取满足条件的行的连接,例如 select * from A,B where A.a > A.b 之类的有条件的查询。 2、等值连接就是特殊的条件连接,当条件为某字段=某字段时,即为等值连接。如SELECT ename,sal,dname FROM emp,dept WHERE emp.deptno=dept.deptno; 3、自然连接是一种特殊的等值连接,他要求多个表有相同的属性字段,然后条件为相同的属性字段值相等, 最后再将表中重复的属性字段去掉,即为自然连接。如A中a,b,c字段,B中有c,d字段, 则select * from A natural join B 相当于 select A.a,A.b,A.c,B.d from A.c = B.c 。 内连接与等值连接的区别: 内连接:两个表(或连接)中某一数据项相等的连接称为内连接。等值连接一般用where字句设置条件,内连接一般用on字句设置条件,但内连接与等值连接效果是相同的。 内连接与等值连接其实是一回事情(等效)。 经常有人会问到select a.id,b.name from a,b where a.id=b.pid 与 select a.id,b.name from a inner join b on a.id=b.pid 有什么区别,哪个效率更高一些。 实际上一回事情了。只是内连接是由SQL 1999规则定的书写方式。两个说的是一码事。 --支持SQL1999的新连接标准 包括以下新的TABLE JOIN的句法结构 CROSS JOIN——它在两个表格中创建了一个笛卡尔积,就象是在Oracle8i中没写WHERE时一样 NATURAL JOIN——它通过从WHERE子句中自动连接标准来改善SQL的稳定性,自然连接。 USING子句——它可以通过名字来具体指定连接 ON子句——这个句法允许在两个表中为连接具体指定列名 LEFT OUTER JOIN——它返回表格中左边的行和右边的数值,如果没有搭配的行的话,则返回空 RIGHT OUTER JOIN——它返回表格中右边的行和左边的数值,如果没有搭配的行的话,则返回空 FULL OUTER JOIN——它返回的是两个表格中所有的行,用空填满每一个空格。这在Oracle8i中则没有相应的此种句法 CROSS JOIN产生了一个笛卡尔积,就象是在连接两个表格时忘记加入一个WHERE子句一样,没有什么用处。 NATURAL JOIN 子句基于两个表中列名完全相同的多个列产生连接,必须要有两个重名的字段,才行。平时用的少。 从两个表中选出连接列的值相等的所有行 如果两个列的名称相同,但是具有不同的数据类型,则查询会返回一个错误 自然连接的条件是基于表中所有同名列的等值连接 为了设置任意的连接条件或者指定连接的列,需要使用ON子句 连接条件与其它的查询条件分开书写 使用ON 子句使查询语句更容易理解 select department_name, city from department d JOIN location l ON (d.location_id = l.id); --子查询 在使用select语句查询数据时,有时候会遇到这样的情况,在where查询条件中的限制条件不是一个确定的值,而是一个来自于另一个查询的结果。 SELECT select_list FROM table WHERE expr operator (SELECT select_list FROM table); 1、子查询在主查询前执行一次--且记,它先执行一次。注意执行顺序,是它先执行一次,然后另外一个才执行。 2、主查询使用子查询的结果 --注意事项 使用子查询的注意事项 1、子查询要用括号括起来 2、将子查询放在比较运算符的右边(增强可读性) 3、只有在执行Top-N分析时,子查询中才需要使用Order by子句,也就是分页。 4、在Oracle8i之前的版本中,子查询不能包含Order by子句 5、对单行子查询使用单行运算符 6、对多行子查询使用多行运算符 --子查询的种类 单行单列子查询:只包含一个字段的查询,返回的查询结果也只包含一行数据,一列数据。 多行单列子查询:只包含了一个字段,但返回的查询结果可能多行或者零行,但只有一列。 多列子查询:包含多个字段的返回,查询结构可能是单行或者多行。 --单行查询,用= => <> 等这个比较符号,因为我们已经知道结果只有一个,如果不确定有几个的话,要用多选子查询运算符号。 SELECT employee_id, last_name FROM employees WHERE salary = (SELECT MIN(salary) FROM employees GROUP BY department_id); ERROR at line 4: ORA-01427: single-row subquery returns more than one row 错误原因:对多行子查询使用了单行比较操作符 --多行子查询 1、返回多行 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'; ANY 通常与大小写符号搭配使用,不单独使用。可以是<ANY 和>ANY : 分别代表着下面的含义 <ANY 小于子查询数据中的最大值 >ANY 大于子查询数据中的最小值 SELECT employee_id, last_name, job_id, salary FROM employees WHERE salary < ALL (SELECT salary FROM employees WHERE job_id = 'IT_PROG') AND job_id <> 'IT_PROG'; ALL 通常与大小写符号搭配使用,不单独使用。可以是<ALL 和>ALL :分别代表着下面的含义 >ALL 指大于子查询数据中的最大值 <ALL 指小于子查询数据中的最小值 --其实,对有些条件,连接查询和子查询是可以互换的。 4. 查询在loc为NEW YORK的部门工作的员工的员工号,ename,deptno,job(使用连接查询,子查询两种查询方式) --子查询 select empno,ename,deptno,job from emp where deptno = (select deptno from dept where loc='NEW YORK') --连接查询 select e.empno,e.ename,d.deptno,e.job from emp e join dept d on(e.deptno=d.deptno) and d.loc='NEW YORK' --总结:在写复杂的SQL语句的时间,要学会分解,把复杂的东西分解到某个子条件中。然后再去查询。 --研究一下SQL语句的执行效率问题? ---事务问题 先来谈一上JDBC的事务 获取连接 Connection conn = null; ... try{ 1、设置连接的提交方式为非自动提交 con.setAutoCommit(false); 创建statement对象 Statement stmt = conn.createStatement(); 执行insert stmt.executeUpdate(insertsql); 2、提交。 conn.commit(); }catch{ 3、回滚 conn.rollback(); }finally{ 关闭资源。 } --使用子查询创建表 --****************************************************************************************** 使用子查询创建表的语法 CREATE TABLE table [column(, column...)] AS subquery; --带数据的 create table departments01 as select department_id,department_name,manager_id,location_id from departments --不带数据的 create table departments02 as select department_id,department_name,manager_id,location_id from departments where 1>2 select department_id,department_name,manager_id,location_id from departments where 1=1 --不省略字段列表 create table departments03 ( id, name, mid, lid ) as select department_id,department_name,manager_id,location_id from departments where 1>2 ----省略字段列表 create table departments04 as select department_id id,department_name name,manager_id mid,location_id lid from departments --****************************************************************************************** --修改表中的字段(了解) --在test表中增加字段 alter table test add sex varchar2(30) --修改test表中的字段,当表中没有字段的时间,你想怎么做就怎么做,但是当有数据的时间,并且你要缩小就要小心了。增大肯定没有问题。 alter table test modify sex varchar2(5) --删除表中的字段 alter table test drop column sex --****************************************************************************************** --删除表的内容 1、TRUNCATE TABLE 语句 清除表中所有的记录,delete可以选择删除表中的一部分 是DDL语句,不可以回滚,delete可以使用rollback回滚,放弃修改。 释放表的存储空间,delete不释放空间 2、 是删除数据的方法之一 3、TRUNCATE TABLE table_name; --删除departments04表中的数据 truncate table departments04 --****************************************************************************************** --删除表 DROP TABLE table_name; --删除departments04表 drop table departments04 --****************************************************************************************** 约束是在表上强制执行的数据校验规则. 当表中数据有相互依赖性时,可以保护相关的数据不被删除. Oracle 支持下面五类完整性约束: 1、NOT NULL 非空 2、UNIQUE Key 唯一键 3、PRIMARY KEY 主键 4、FOREIGN KEY 外键 5、CHECK 检察 Check约束条件是一种比较特殊的约束条件,通过check定义, 强制定义在字段上的每一记录都要满足check中定义的条件。 在check中定义检查的条件表达式,进入表中的数据必须符合 check中设置的条件 条件表达式不允许使用: 1、SYSDATE, USER等函数 2、参照其他记录的值 ..., salary NUMBER(2) CONSTRAINT emp_salary_min CHECK (salary > 0),... --********************************************************************-- --数据优化与索引有关??且记,在优化的时间用。 --视图,十分重要。 视图也就是虚表,实际上视图就是一个命名的查询,用于改变基表数据的显示。 可以限制对数据的访问 可以使复杂的查询变的简单 提供了数据的独立性 提供了对相同数据的不同显示 --视图: --为sql语句起的别名 给予表之上的一个查询语句 --语法: --在CREATE VIEW语句后加入子查询. CREATE [OR REPLACE] VIEW view_name [(alias[, alias]...)] AS subquery [WITH READ ONLY]; create or replace view v_emp as select * from employees --查询视图 select * from v_emp; --它是为一些比较的复杂的sql语句,添加一个别名。这样在程序中就能够直接调用 --一个简单的视图,而不是要写复杂的SQL语句。 --视图的作用 --* select 语句比较复杂 --* select语句在开发的程序中可能多次使用 --* 在程序中直接使用视图 select * from v_emp create or replace view v_emp as select "EMPLOYEE_ID","FIRST_NAME","LAST_NAME","EMAIL","PHONE_NUMBER", "HIRE_DATE","JOB_ID","SALARY","COMMISSION_PCT","MANAGER_ID","DEPARTMENT_ID" from employees --描述视图的结构(命令行执行) desc v_emp describe v_emp --创建复杂视图 create or replace view v_emp_dept as select d.department_name,min(salary) mins,max(salary) mass,avg(salary) avgs,sum(salary) sums,count(salary) counts from employees e,departments d where e.department_id=d.department_id group by d.department_name --查询视图 select * from v_emp_dept --通过视图插入数据到表中 create or replace view v_dept as select deptno,dname,loc from dept --查询视图 select * from v_dept --通过 v_dept视图插入数据到dept表中 insert into v_dept(deptno,dname,loc) values(89,'xxx','ss') --通过设置WITH READ ONLY选项可以禁止对视图执行DML操作. create or replace view v_dept as select deptno,dname,loc from dept with read only --删除视图 --删掉视图不会导致数据的丢失,因为视图是基于数据库的表之上的一个查询定义. DROP VIEW view_name; --删除v_dept视图 drop view v_dept --****************************************************************************************************** TOP分析法:oracle 分页 行内视图 行内视图是在SQL语句中使用的一个带有别名的子查询. 在主查询FROM 子句中的子查询就是行内视图. 行内视图不是数据库的对象,所以不需要显式的创建. Top-N分析的语法注意事项: 1、使用了rownum这个伪列,这个伪列将会返回行号,可以作为返回记录的序列号显示。 2、在from后面使用了子查询,这是标准的行内视图的使用。 3、在子查询中使用了order by进行排序,在前面的子查询中不需要使用。 4、在主查询中通过where条件中的rownum伪列定义过滤条件,只返回最什么的前几行数据 -- 查询员工表中 employee_id为10001 10002 10003 不能使用表中的任何字段作为查询条件 select employee_id,first_name from employees where rownum<4 ---它只能查询小于的,不能查询大于的,此时里面的已经变成了,逆序的排列,然后再用<这种做就OK了。 -- 查询员工表中 employee_id为100010 10009 10008 不能使用表中的任何字段作为查询条件 select employee_id,first_name from( select employee_id,first_name from employees order by employee_id asc ) where rownum < 4 --分页 每页显示3条记录 rownum rank也是oracle中的隐藏字段。 -- 第一页 查询员工表中 employee_id为10001 10002 10003 不能使用表中的任何字段作为查询条件 select employee_id,first_name from( select rownum rank,employee_id,first_name from ( select employee_id,first_name from employees order by employee_id asc ) where rownum <4 ) where rank>0 -- 第二页 查询员工表中 employee_id为10004 10005 10006 不能使用表中的任何字段作为查询条件 select employee_id,first_name from( select rownum rank,employee_id,first_name from ( select employee_id,first_name from employees order by employee_id asc ) where rownum <7 ) where rank>3 -- 第三页 查询员工表中 employee_id为10007 10008 10009 不能使用表中的任何字段作为查询条件 select employee_id,first_name from( select rownum rank,employee_id,first_name from ( select employee_id,first_name from employees order by employee_id asc ) where rownum <10 ) where rank>6 -- 第四页 查询员工表中 employee_id为100010 不能使用表中的任何字段作为查询条件 select employee_id,first_name from( select rownum rank,employee_id,first_name from ( select employee_id,first_name from employees order by employee_id asc ) where rownum <13 ) where rank>9 --****************************************************************************************************** --同义词: 同义词是数据库中一个对象的别名,可以简化对对象的访问 通过使用同义词,可以: 1、简化了引用另一个用户对象的方法 2、缩短了对象名称的长度 CREATE [PUBLIC] SYNONYM synonym FOR object; --创建同义词,其实就是给表起了一个别名。 create synonym xx for departments --使用同义词查询 select * from xx --删除同义词. DROP SYNONYM s_emp; --删除xx drop synonym xx --*****************************************************************************************************