Oracle 基础知识

本篇内容主要是基础知识简单查询语句以及一些Oracle的常用函数

大部分内容都是平时上课或是从老师ppt总结的,部分有参考《Oracle Datebase 11g SQL 开发之南》,如有不准确或是不正确的地方还望指正。

建表语句可以从如下链接下载:store_schema.sql

下载完成后用记事本打开,复制全部内容在command window下即可(开始可能会有报错,无视就好,原因是建表语句中有“drop table XXX;”这一句,防止重复建表,而在建表之前是没有XXX表的,所以会报错)。

注:

  • 数据表和《Oracle Datebase 11g SQL 开发之南》中的实例相同。
  • 转载请标明转载出处 http://santong.me 谢谢啦!

基本信息

Oracle版本:Oracle 11g

管理工具:PL/SQL;

常用窗口:command窗口,SQL窗口;

常用数据库账号:

  1. store/store123(当把建表语句复制进command window时会创建);

  2. system/your_password(有时可能用到,system密码取决于你安装oracle时自己的设置);

基础SQL语句

基础知识

  1. Oracle大小写不敏感,即SELECT 和 select是等价的;

  2. Oracle数据表中每行纪录对应不同的rowid,rownum,称为伪列,其中rowid是唯一标示;当执行查询语句时,rownum会根据返回的行从1开始重新顺序编号;

  3. Oracle中的表可以不定义主键;

  4. 可以从dual表中查询与表内容无关的值;

    select 1+1 from dual;             // 返回2;
    
  5. Oracle中算术运算符有: + - * /

    select to_date('25-1-2015')+2    // to_date()为日期函数;
    from dual;                        // 返回2015/1/27;
    
  6. 可以在查询语句中用as关键字为列设置别名;

    select name,price+2 as price 
    from products;                    // 返回两列,名为name和price;
    
  7. 使用||连接列;

    // 虽然查询了两个列,但是只返回一列名为Customer Name;
    select first_name||' '||last_name as "Customer Name"
    from customers;                    
    
  8. 在数据库中难免会有空值null,可以使用is

    select * from  customers
    where dob is null; 
    
  9. 利用distinct禁止重复显示相同行;

    select distinct customer_id     
    from purchases;
    
  10. 比较符号有: = , != , <> , < , > , <= , >=;

    注意:与rownum相关的比较符只能是<或者是<=;

  11. Oracle 10g引入了两种新的数据类型:BINARY_FLOAT和BINARY_DOUBLE,前者可以存储一个单精度的32位浮点数,后者可以存储一个双精度的64位浮点数,这两种新的数据类型根据二进制浮点运算的IEEE标准提出的。其需要的存储空间较小,可表示范围更大,执行速度更快,并且运算封闭,取整透明。如果需要开发一个涉及大量数字运算的系统,建议考虑如上类型。

  12. 逻辑操作优先级 NOT > AND > OR;

    select * from customers
    where not(dob>'01-1月-1970'); 
    
  13. Oracle注释用 “–”

查询语句

*表示所有列:
select * from student;
where语句来过滤行:
select * from student
where student_id = 2;    
any和some

表示满足一定范围内任意的值即满足条件(any也可以用some代替):

// 返回大于2的customer_id,即只大于2,3,4中的2就满足了条件
select customer_id from customers
where customer_id > any(2,3,4);
all

表示要大于一定范围内所有值才满足条件:

// 返回大于4的customer_id,即要大于2,3,4中的最大值才满足条件
select customer_id from customers
where customer_id>all(2,3,4);
like和not like

用于匹配字符串,_代表一个字符,%代表任意个字符(可以是0个),like可以和not组合使用:

// 返回first_name中包含一个“o”的名字
select first_name from customers
where first_name like '_o%';

// 返回first_name中不包含“o”的名字
select first_name from customers
where first_name not like '_o%';
escape

用于当使用like需要匹配”_”或是”%”的时候用来定义转义符:

select * from promotions
where name like '%\%%' escape '\';//此时\为转义符
in和not in

用来检索列值是否在列表中,not in检索不在列表中的列值。

注意:当not in和null组合使用时,无任何返回结果,因为null表示不知道是什么值即可能表示任何值,所以查询无任何结果:

//in
select * from customers
where customer_id in (2,3,5,6);
//not in
select * from customers
where customer_id not in (2,3,5,6);
//查询无结果
select * from customers
where customer_id not in (2,3,5,6,null);
between

检查列值是否在指定区间内:

select * from customers
where customer_id between 1 and 3;
order by子句

默认根据列值的升序排列,字句后加desc进行降序排列:

//根据列last_name排列
select * from customers
order by last_name;
//1代表按表的第一列排序
select * from customers
order by 1;
//字句末家desc进行降序排列
select * from customers
order by customer_id desc;
内连接

目的是进行多张表的联合查询,取多张表的交集,实现有以下几种方式:

  • 第一种方式是inner join…on…;

    //p,pt分别是products和product_types的别名
    select p.name, pt.name
    from products p inner join product_types pt
    on p.product_type_id = pt.product_type_id;
    
  • 第二种方式用where匹配过滤;

    //p,pt分别是products和product_types的别名
    select p.name, pt.name
    from products p, product_types pt
    where p.product_type_id = pt.product_type_id;
    
  • 第三种方式是比较推荐的,使用using来代替on字句,更加简洁常用;

    注意:using子句中用到的列名如果出现在select子句中,前面不得加表名或者表别名。

    //p,pt分别是products和product_types的别名
    select p.name, pt.name
    from products p inner join product_types pt
    using(product_type_id);
    
左外链接

同样是进行多张表的联合查询,但显示join左边表的所有数据:

  • 第一种方式,使用where过滤并在where子句中将join右边的表名后面加(+);

    select p.name, pt.name
    from products p, product_types pt
    where p.product_type_id = pt.product_type_id(+);
    
  • 第二种方式,使用…left outer join…using…子句;

    select p.name,pt.name
    from products p left outer join product_types pt
    using(product_type_id);
    
右外链接

同样是进行多张表的联合查询,但显示join右边表的所有数据:

  • 第一种方式,使用where过滤并在where子句中将join左边的表名后面加(+);

    select p.name, pt.name
    from products p, product_types pt
    where p.product_type_id(+) = pt.product_type_id;
    
  • 第二种方式,使用…right outer join…using…子句;

    select p.name,pt.name
    from products p right outer join product_types pt
    using(product_type_id);
    
全外链接

同样是进行多张表的联合查询,但显示所有数据,使用…full outer join…using

题外话:其实我觉得oracle很多语句就像说英语一样,比较通顺,个人觉得还是比较容易理解的。。。

select p.name,pt.name
from products p full outer join product_types pt
using(product_type_id);
自连接

如题所说,自己和自己连接,用来实现一些简单查询无法实现或者实现起来较麻烦的查询,注意和内连接区分,内连接是多张表联合查询,自连接使只对一张表进行查询:

select w.last_name||' works for '||m.last_name
from employees w inner join employees m
on w.manager_id=m.employee_id;
Group by子句

用于对行进行分组,也可以和聚合函数 配合,统计各组的信息:

//根据product_type_id进行分组,统计rowid,然后按照product_type_id排序
select product_type_id,count(rowid)
from products
group by product_type_id
order by product_type_id;

基础函数

字符函数

函数 说明
INITCAP(s) 返回s字符串首字母大写、其他字母小写的格式
LOWER(s) 返回s字符串所有字母小写的格式
UPPER(s) 返回s字符串所有字母大写的格式
LENGTH(s) 返回s字符串的长度
SUBSTR(s,start[,length]) 返回s的子串,从s的第start个字符开始,连续取length个字符;如果不写length,表示取到结尾
INSTR(s,find[,start][,occurrence]) 在字符串s中查找字符串find,返回find所在位置是s的第几个字符。start表示从s的第几个字符开始查找,occurrence表示返回第几次出现的位置
REPLACE(s,find,replace_string) 把s中所有的字符串find都替换成replace_string
CONCAT(s1,s2) 返回s1和s2字符串连接后的字符串,等价于`s1 s2`
NVL(x,value) 如果x的值为空,则返回value;否则返回x

eg.

// 若phone为空,查询结果中该行由'Unknown phone number'取代,其余不变
select customer_id,nvl(phone,'Unknown phone number')
from customers;

数字函数

函数 说明
ABS(x) 返回x的绝对值
SIGN(x) 如果x为正,则返回1;如果为负,则返回-1;如果为0,则返回0
CEIL(x) 返回大于或等于x的最小整数
FLOOR(x) 返回小于或等于x的最小整数
ROUND(x[,y]) 返回x四舍五入后的结果,如果有参数y表示在小数点后第y位四舍五入
TRUNC(x[,y]) 返回x的整数部分,如果有参数y表示在小数点后第y位进行截断
POWER(x,y) 返回x的y次幂
EXP(x) 返回e的x次幂
LOG(x,y) 返回以x为底、y的对数
LN(x) 返回以e为底、x的对数
SQRT(x) 返回x的平方根

转换函数

函数 说明
TO_NUMBER(x[,format]) 把x转换成数字
TO_CHAR(x[,format]) 把x转换成字符串
TO_DATE(x[,format]) 把x转换成日期

eg.

//将dob从日期型转为字符型
select * from customers
where to_char(dob,'yyyy')='1971';

聚合函数

函数 说明
count(x) 统计行数,count(*)会造成效率损失
SUM(x) 用于统计某列的值的总和
AVG(x) 用于统计某列的平均值
MAX(x) 用于统计某一列的最大值
MEDIAN(x) 用于统计某一列的中间值
MIN(x) 用于统计某一列的最小值

eg.

//统计product_id的行数
select count(product_id) 
from products;

聚合函数中,只有count(*)会统计空值(NULL)。