Oracle数据库学习

Select/条件和排序/单行函数(7.14)

条件查找

  • 去重
    SELECT DISTINCT department_id FROM employees; 使用DISTINCT 消除重复结果行

  • LIKE

    • escape可以转义任意字符为转义字符,可以指定
    • % >=个字符
    • _ 一个字符
  • between...and...包含区间

    SELECT last_name, salary
    FROM employees
    WHERE salary BETWEEN 2500 AND 3500;
    
  • in 在集合范围内

  • <> 不等于

  • not is not, not in, not like

排序

  • order by asc升序, desc倒序

单行函数

  • 大小写转换函数
    lower
    upper
    initcap

  • 字符串操作函数

    image

    concat 字符串连接 和||差不多

    substr

    length

    instr

    lpad 向左补齐

    rpad

    trim 去空格
    lower, upper, initcap, replace

  • 数字

    round(45.923, 2)四舍五入,保留两位小数

    trunc 全舍

    mod(12, 2) 取模

    保留几位小数, 正数和负数的作用

  • 日期

函数 结果
MONTHS_BETWEEN ('01-SEP-95','11-JAN-94') 19.6774194
ADD_MONTHS ('11-JAN-94',6) 11-Jul-94
NEXT_DAY ('01-SEP-95','FRIDAY') 8-Sep-95
NEXT_DAY ('01-SEP-95',1) 3-Sep-95
NEXT_DAY ('1995-09-01',1) ORA-01861:literal does not match format string
NEXT_DAY (to_date('1995-09-01','YYYY-MM-DD'),1) 3-Sep-95
LAST_DAY('01-FEB-95') 28-Feb-95
ROUND('25-JUL-95','MONTH') 1-Aug-95
ROUND('25-JUL-95' ,'YEAR') 1-Jan-96
TRUNC('25-JUL-95' ,'MONTH') 1-Jul-95
TRUNC('25-JUL-95','YEAR') 1-Jan-95

to_char用法

Select to_char(sysdate,'ss') from dual取当前时间秒部分

Select to_char(sysdate,'mi') from dual取当前时间分钟部分

Select to_char(sysdate,'HH24') from dual取当前时间秒小时部分

Select to_char(sysdate,'DD') from dual取当前时间日期部分

Select to_char(sysdate,'MM') from dual取当前时间月部分

Select to_char(sysdate,'YYYY') from dual取当前时间年部分

Select to_char(sysdate,'w') from dual取当前时间是一个月中的第几周(从1日开始算)

Select to_char(sysdate,'ww') from dual取当前时间是一年中的第几周(从1.1开始算)

Select to_char(sysdate,'iw') from dual取当前时间是一年中的第几周(按实际日历的)

Select to_char(sysdate,'d') from dual取当前时间是一周的第几天,从星期天开始,周六结束
Select to_char(sysdate,'day') from dual 取当前日是星期几,和数据库设置的字符集有关,会输出'Tuesday'

Select to_char(sysdate,'ddd') from dual 当前日是一年中的第几天

  • 其他

    NVL (expr1, expr2) 如果expr1为空,这返回expr2

    NVL2 (expr1, expr2, expr3) 如果expr1为空,这返回expr3(第2个结果)否则返回expr2

    NULLIF (expr1, expr2) 如果expr1和expr2相等,则返回空

    COALESCE (expr1, expr2, ..., exprn)如果expr1不为空,则返回expr1,结束;否则计算expr2,直到找到

  • 条件表达式case

    SELECT last_name, job_id, salary,
    CASE job_id
    WHEN 'IT_PROG' THEN 1.10*salary
    WHEN 'ST_CLERK' THEN 1.15*salary
    WHEN 'SA_REP' THEN 1.20*salary
    ELSE salary
    END "REVISED_SALARY"
    FROM employees;
    

    或者

    SELECT last_name, job_id, salary,
    DECODE(job_id, 'IT_PROG', 1.10*salary,
    'ST_CLERK', 1.15*salary,
    'SA_REP', 1.20*salary,
    salary) REVISED_SALARY
    FROM employees;
    

    一个加 as和不加, concat 和 ||

多表关联/分组计算和group by/子查询/DML语句/事务控制/锁(7.15)

  • 2 、SELECT 查询语句中同时选择分组计算函数表达式和其他独立字段时 ,其他字段必须出现在Group By 子
    句中,否则不合法

  • 3 、不能在Where 条件中使用分组计算函数表达式,当出现这样的需求的时候,使用Having 子句。

  • 单行比较必须对应单行子查询(返回单一结果值的查询); 比如= , >
    多行比较必须对应多行子查询(返回一个数据集合的查询);比如 IN , > ANY, > ALL

  • 使用子查询作为插入

    INSERT INTO (SELECT employee_id, last_name, email,
    hire_date, job_id, salary
    FROM employees
    WHERE department_id = 50 WITH CHECK OPTION)
    VALUES (99998, 'Smith', 'JSMITH',
    TO_DATE('07-JUN-99', 'DD-MON-RR'),
    'ST_CLERK', 5000);
    

    WITH CHECK OPTION 可以检查要插入的内容,是否符合目标子查询的WhereWITH CHECK OPTION 可以检查要插入的内容,是否符合目标子查询的Where

  • 如果遇到这种需求,也可以使用TRUNCATE 语句, ,TRUNCATE TABLE copy_emp ,
    但要注意,TRUNCATE 语句无法回滚,因此除非是单独执行,并非常确认,否则慎用

DML语句

  • insert into

    INSERT INTO table [(column [, column...])] VALUES (value [, value...]);

  • update

    UPDATE table SET column = value [, column = value, ...] [WHERE condition];

  • delete

    DELETE [FROM] table [WHERE condition];

  • merge语句
    MERGE 语句: 比较整合语句, 语法:

    MERGE INTO table_name table_alias
    USING (table|view|sub_query) alias
    ON (join condition)
    WHEN MATCHED THEN
    UPDATE SET
    col1 = col_val1,
    col2 = col2_val
    WHEN NOT MATCHED THEN
    INSERT (column_list)
    VALUES (column_values);
    

事务控制

  • 当如下事件发生是,会隐式的执行Commit 动作:
    1 、数据定义语句被执行的时候,比如新建一张表:Create Table …
    2 、数据控制语句被执行的时候,比如赋权 GRANT …( 或者 DENY)
    3 、正常退出 iSQL*Plus 或者PLSQL DEVELOPER, 而没有显式的执行 COMMIT 或者 ROLLBACK 语句
  • 在 在Commit 或者 Rollback 前后数据的状态:
    1 、在数据已经被更改,但没有Commit 前 ,被更改记录处于被锁定状态,其他用户无法进行更改;
    2、 、 在数据已经被更改,但没有Commit 前 ,只有当前Session 的用户可以看到这种变更 ,其他Session 的用户
    。 看不到数据的变化。
    3、 、 在数据已经被更改 ,并且被Commit 后, 被更改 记录自动解锁, 其他 用户 可以 进行 更改; ;
    4、 、 在数据已经被更改 ,被 并且被Commit后 后 ,其他Session的 的 用户再次访问这些数据时,看到的是变化后的数据

  • 更新一张表之前呢,先用select ... for update nowait查看此表是否已经被锁

表/约束/视图/序列&索引&同义词/集合操作/用户权限控制(7.16)

  • 更改表结构

    添加列

    ALTER TABLE table ADD (column datatype [DEFAULT expr] [, column datatype]...);

    更改列

    ALTER TABLE table MODIFY (column datatype [DEFAULT expr] [, column datatype]...);

    删除列

    ALTER TABLE table DROP (column);

    删除表DROP TABLE tableName;

    更改表名RENAME oldtablename to newtableName;

    一次性清空表TRUNCATE TABLE tableName;

约束

  • 添加约束

    ALTER TABLE table ADD CONSTRAINT 约束名 primary key();

  • 删除约束

    alter table t_table drop constraint pri;

TOP-N

SELECT [column_list], ROWNUM
FROM (SELECT [column_list]
FROM table
ORDER BY Top-N_column)
WHERE ROWNUM <= N;

索引

  • 在什么样的情况下创建索引对加快查询有利呢:

    答:查询条件中使用到这个列(或者这个列于其他列的组合),且这个列(或者与其他列的组合)上的数字
    量 范围跨度很大,而大多数情况下我们要获取的数据的量占整个表的数据总量 小于4% ;

  • 在什么样的情况下不适合创建索引呢:

  • 答: 1 )被查询的表本身就很小,即是是全表扫描也非常快; ; 或者基于这张表的查询,大多数情况下需要获取的数据量都超过了总量的4%;或者这张表需要频繁的被更新,建立索引的话会引起索引的频繁更新,从而反而
    降低数据库的整体效率。

  • 模糊查询的时候%放在前面,是不会用到索引的.

  • 字段类型要匹配,不然不会用到索引

  • 所有的索引字段使用的时候不能加任何函数,建议用函数索引.

集合操作

  • 并集,union

    去除重复项,union all保留重复项

    select employee_id, job_id
    from employees
    union
    select employee_id, job_id
    from job_history;
    
  • 交集, intersect

  • 差集, minus

Group By 子句增强/子查询进阶/递归查询/INSERT增强(7.17)

group by增强

  • rollup
    Rollup 后面跟了n 个字段,就将进行n+1 次分组,从右到左每次减少一个字段进行分组;然后进行
    union

    SELECT department_id, job_id, SUM(salary)
    FROM employees
    WHERE department_id < 60
    GROUP BY ROLLUP(department_id, job_id);
    

    第一次根据(department_id, job_id)进行分组,第二次根据(department_id)进行分组,第三次是总体的汇总

  • cube

    cuberollup一样,从右向左减少一个字段进行分组,还会从左往右减少一个字段分组,最后在汇总,即2^N次分组运算

  • grouping

    GROUPING 函数:Rollup 和 Cube 有点抽象,他分别相当于n+1 和 2 的n 次方常规 Group by 运 运
    算;那么在Rollup 和 Cube 的结果集中如何很明确的看出哪些行是针对那些列或者列的组合进行
    ? 分组运算的结果的? 答案是可以使用Grouping 函数; 没有被Grouping 到返回1

  • group sets

    代替多次的union

子查询进阶

  • 非相关子查询当做一张表使用

  • existsin效率高

    注意:Not In 里面 只要有一个NULL ,就不成立了,这是很容易出错的地方; 正确的方法请在后
    面的子查询中加上where department_id is not null;
    exists不返回数据,只返回True或者False

  • with

递归查询

SELECT [LEVEL], column, expr...
FROM table
[WHERE condition(s)]
[START WITH condition(s)]
[CONNECT BY PRIOR condition(s)] ;
    

举例:查询从King 开始,从上往下的各级员工。

SELECT last_name||' reports to '||
PRIOR last_name "Walk Top Down"
FROM employees
START WITH last_name = 'King'
CONNECT BY PRIOR employee_id = manager_id ;
  • lpad 向左补齐, level是等级

insert增强

  • 一个来源插入多个目标表(无条件)。
  • 一个来源插入多个目标表(有条件)
  • 一个来源插入多个目标表(有条件,首次匹配即跳到下一条)
  • 列转行(一行变多行,交叉报表的反操作)

SQL进阶功能(7.19)

  • over

    分析函数提供一系列比较高级的SQL 功能。分析函数时建立在数据窗口(over 在一定的数据库范
    围进行数据分析),在一定的数据范围进行排序、汇总等
    例如 over(parttion by .....)

  • rank, dense_rank, row_number

    rank 1 2 2 4 相同的会跳过编号
    dense_rank 1 2 2 3 相同的不跳过编号
    row_number 1 2 3 4 一直编号

  • 闪回功能

SELECT * FROM departments AS OF TIMESTAMP SYSDATE-5/(24*60)
  • 全局临时表

    • 基于会话
      CREATE GLOBAL TEMPORARY TABLE temp_table_session (...) ON COMMIT PRESERVE ROWS;
      基于会话的临时表,在会话断开之前,或者通过一个delete 或truncate 物理地删除行之前 ,
      这些 行会一直存在于这个临时表中。只有我的会话能看到这些行,即使我已经提交,其他会话也无法看到我的行。
    • 基于事务
      CREATE GLOBAL TEMPORARY TABLE temp_table_session (...) ON COMMIT DELETE ROWS;
      基于事务的临时表,我的会话提交时,临时表中的行就不见了。只需把分配给这个表的临时区段交回 ,
      这些 行就会消失,在临时表的自动清除过程中不存在开销。
  • length 是字符 个数,lengthb 指的是字节数。 。
    substr值 是按字来取值, ,substrb 是按字节来取值
    汉字。 字符对应多少字节,和数据库的字符集设置有关系

你可能感兴趣的:(Oracle数据库学习)