Orlce数据库——表查询

1、Oralce中数据库名 SID等的区别

数据库实例名是用于和操作系统进行联系的标识,就是说数据库和操作系统之间的交互用的是数据库实例名。实例名也被写入参数文件中,该参数为INSTANCE_NAME。数据库名和实例名可以相同也可以不同。
在一般情况下,数据库名和实例名是一对一的关系,但如果在Oracle并行服务器架构(Oracle实时应用集群中)中,数据库名和实例名是一对多的关系。
查询数据库名用select name from v$database;

查询实例名用show instance_name from v$instance;
也可以用show parameter instance查实例名;

数据类型:
Number(p,s) :类似浮点型,最大精度p,小数位s位
Varchar2(s) :可变长字符类型
date : 日期型
Char(s) :定长字符型

2、操作符

  • 乘除的优先级高于加减。
  • 同一优先级运算符从左向右执行。
  • 括号内的运算先执行。
  • 对于日期型数据, 做 *, / 运算不合法
比较运算:

等于用 单=不能用两个==
<>和!=都代表不等于
:=这是赋值

小知识点:
  • 包含空值的数学表达式的值都为空值
  • 别名使用双引号!
  • oracle 中连接字符串使用 “||”, 而不是 java 中的 “+”
  • 日期和字符只能在单引号中出现. 输出 last_name`s email is email

3、关键字

1、 distinct: 去重(删除重复行)

例:查询employees表中的department_id 的id

 SELECT distinct department_id
FROM   employees;

这样就把department_id查出的重复的删掉了。

2、describe: 查询表结构 (简写:desc)
desc  tablename;

这样就查出tablename表中有哪些字段 name id org 等等

3、between ··· and ···· : 在两个值之间(包含边界)

例:查询工资在 5000 – 10000 之间的员工信息.
1). 使用 and

select *
from employees
where salary >= 5000 and salary <= 10000

2). 使用 BETWEEN … AND …, 注意: 包含边界!!

select *
from employees
where salary between 5000 and 10000
4、in: 等于值列表中的一个

例: 查询工资等于 6000, 7000, 8000, 9000, 10000 的员工信息
1). 使用 or

select *
from employees
where salary = 6000 or salary = 7000 or salary = 8000 or salary = 9000 or salary = 10000

2). 使用 in

select *
from employees
where salary in (6000, 7000, 8000, 9000, 10000)
5、like: 模糊查询

1 查询 LAST_NAME 中有 ‘o’ 字符的所有员工信息.

select *
from employees
where last_name like '%o%'

2 查询 LAST_NAME 中第二个字符是 ‘o’ 的所有员工信息.

select *
from employees
where last_name like '_o%'

3查询LAST_NAME 中有 'a’和’e’字符的员工信息

   select *
	from employees
	where last_name like '%a%e%' or  last_name like '%e%a%'
6、escape: 转义字符

3 查询 LAST_NAME 中含有 ‘_’ 字符的所有员工信息

2). 使用 escape 说明转义字符.
select *
from employees
where last_name like '%\_%' escape '\'

这里的’'可以也可以是别的符号:where last_name like ‘%#_%’ escape ‘#’

7、is null: 空值

例:1. 查询 COMMISSION_PCT 字段为空的所有员工信息

select last_name, commission_pct
from employees
where commission_pct is null
  1. 查询 COMMISSION_PCT 字段不为空的所有员工信息
	select last_name, commission_pct
	from employees
	where commission_pct  is not null
8、order by: 使子句排序

ASC(ascend): 升序
DESC(descend): 降序
ORDER BY 子句在SELECT语句的结尾。
例:

SELECT   last_name, job_id, department_id, hire_date
FROM     employees
ORDER BY hire_date DESC ;
9、months_between(date1, date2): 返回两个日期之间的月份数

如果两个日期月份内天数相同,或者都是某个月的最后一天,返回一个整数,否则,返回数值带小数,以每天1/31月来计算月中剩余天数,
months_between(date1, date2),必须注意的是,date1与date2都为Date类型,不然会出现错误。须用to_date(‘’,’’) 来转换为日期格式,才能参加计算。
例:
查询各员工的姓名,并显示出各员工在公司工作的月份数(worked_month)。
结果:

  select last_name,hire_date,
  round(months_between(sysdate,hire_date),1) workded_month
	from employees

返回的小数用round 函数保留一位

10、 rownum: 查询出前多少条数据

例:

select last_name from employees where rownum<=20;

这样就会查询出前20条数据。

4、单行函数:

Orlce数据库——表查询_第1张图片

  • 操作数据对象
  • 接受参数返回一个结果
  • 只对一行进行变换
  • 每行返回一个结果
  • 可以转换数据类型
  • 可以嵌套
  • 参数可以是一列或一个值
    function_name [(arg1, arg2,…)]

4. 1 字符函数:

1、大小写控制函数

lower: 把所有的字符转化为小写

例:
LOWER(‘SQL Course’)
结果:sql course
例:显示员工 Higgins的信息:

SELECT employee_id, last_name, department_id
FROM   employees
WHERE  LOWER(last_name) = 'higgins';

这样不论数据库中字符是大写小写,都转化为小写,这样就可以与 'higgins’进行比较了

upper: 把所有的字符转化为大写

例:
UPPER(‘SQL Course’)
结果:SQL COURSE

initcap: 把所有的字符转化为首字母大写

例:
INITCAP(‘SQL Course’)
结果:Sql Course

2、字符控制函数 HelloWorld

concat(‘Hello’, ‘World’): 拼接字符串

结果:HelloWorld

substr(‘HelloWorld’,1,5): 从第1个开始,读取5个字符串

结果:Hello
在sql中下标是从1开始的,所以第一个就是1.

length(‘HelloWorld’): 字符串长度

结果:10

instr(‘HelloWorld’, ‘W’) w在第六个

结果:6

lpad(salary,10,’*’) 查询10位,不够10位的用 ’ * ’ 代替,在列的左边粘贴字符

结果:*****24000

rpad(salary, 10, ‘*’) 查询10位,不够10位的用 ’ * ’ 代替,在列的右边粘贴

结果:24000*****

trim(‘H’ FROM ‘HelloWorld’) 去除 H 字符,它可以去除首位 字符,中间的无法去除

结果:elloWorld

replace(‘abcd’,’b’,’m’) 把b替换为m,是所有的都替换

结果:amcd

4. 2 数字函数:

round: 四舍五入

例:ROUND(45.926, 2) 保留两位
结果: 45.93

trunc: 截断

TRUNC(45.926, 2) ,保留2位,后面的直接舍去,
结果: 45.92
TRUNC(89.985)=89 默认是保留整数
TRUNC(89.985,-1)=80,把9舍去,得80

mod: 求余

MOD(1600, 300)
结果: 100

4. 3 转换函数:

1、隐性转换

Oracle 自动完成下列转换:
VARCHAR2 or CHAR: 可以自转成NUMBER
VARCHAR2 or CHAR: 可以自转成 DATE
NUMBER: 可以自转成VARCHAR2
DATE: 可以自转成VARCHAR2

2、显式数据类型转换

Orlce数据库——表查询_第2张图片

to_char: 1、函数对日期的转换

例:
1、 打印出 “2009年10月14日 9:25:40” 格式的当前系统的日期和时间.

select to_char(sysdate, 'YYYY"年"MM"月"DD"日" HH:MI:SS')
from dual	

结果:
2019年06月03日10:46:32

注意: 使用双引号向日期中添加字符
2、

select employee_id,last_name,hire_date
from employees
where to_char(hire_date,’yyyy-mm-dd’) = ‘1987-09-17’
2、to_char函数对数字的转换

格式化数字: 1234567.89 为 1,234,567.89

select to_char(1234567.89, '999,999,999.99')
from dual

结果:
1,234,567.89

这是使用9的,
使用0位数不够会补上,
如果

	select to_char(1234567.89, '000,000,000.00')
	from dual

结果:
001,234,567.89

to_date: 函数对字符的转换
select employee_id,last_name,hire_date
from employees
where to_date( ‘1987-09-17’,’yyyy-mm-dd’) =hire_date
to_number: 函数对字符的转换
TO_NUMBER(‘¥1,234,567,890.00’,’L999,999,999,999.99’)
from dual

4. 4 通用函数

这些函数适用于任何数据类型,同时也适用于空值:

NVL (expr1, expr2): 将空值转换成一个已知的值

就是当expr1为空时,用expr2代替,不为空时就用本身的值。

例:
计算公司员工的年薪

--错误写法: 因为空值计算的结果还是空值
select last_name, salary * 12 * (1 + commission_pct) year_sal
from employees

--正确写法
select last_name, salary * 12 * (1 + nvl(commission_pct, 0)) year_sal
from employees
NVL2 (expr1, expr2, expr3): expr1不为NULL,返回expr2;为NULL,返回expr3。
NULLIF (expr1, expr2): expr1和expr2 相等返回NULL,不等返回expr1
COALESCE (expr1, expr2, …, exprn):

COALESCE 与 NVL 相比的优点在于 COALESCE 可以同时处理交替的多个值。
如果第一个表达式为空,则返回下一个表达式,对其他的参数进行COALESCE 。
也就是第一个为空,返回第二个,第二个为空,返回第三,依次往下。

4.5条件表达式

在 SQL 语句中使用IF-THEN-ELSE 逻辑
使用两种方法:
CASE 表达式
DECODE 函数

case表达式: 类似java中switch
CASE expr WHEN comparison_expr1 THEN return_expr1
         [WHEN comparison_expr2 THEN return_expr2
          WHEN comparison_exprn THEN return_exprn
          ELSE else_expr]
END

这个的意思是当expr 等于comparison_expr1 时,做return_expr1处理,
当等于comparison_expr2 时,做return_expr2处理,
都不等时做else_expr处理,
END结束
例:
查询部门号为 10, 20, 30 的员工信息, 若部门号为 10, 则打印其工资的 1.1 倍, 20 号部门, 则打印其工资的 1.2 倍, 30 号部门打印其工资的 1.3 倍数
department_id 是部门列

在需要使用 IF-THEN-ELSE 逻辑时:
1、使用 case-when-then-else-end 表达式
select last_name, department_id, salary, case department_id when 10  then salary * 1.1
                                                            when 20  then salary * 1.2
                                                            else          salary * 1.3
                                                            end new_sal
from employees
where department_id in (10, 20, 30)

或者

select sum( case  when g  >=60 
								then 1
								 else 0 
								 end
								 		)/count(*)*100||'%'
from xc
where c#='1'
DECODE: 和case的意思差不多

例:
上面的要求
–使用 decode

	select last_name, department_id, salary, decode(department_id, 10, salary * 1.1,
                                               		               20, salary * 1.2,
                                                                   30, salary * 1.3
                                                                   '指定值'
                                                                ) new_sal
        from employees
        where department_id in (10, 20, 30)

10、20、30都没有满足的, 那就可以指定一个值
在这里插入图片描述

5、多表查询

演示笛卡尔集的错误情况:

select last_name, department_name
from employees, departments
这样他就会出现107*27=2889条,实际只有107条,

select count(employee_id) from employees;
假设输出107行
select count(department_id)from departments;
假设输出27行
select 107*27 from dual;
笛卡尔集会在下面条件下产生:

  • 省略连接条件
  • 连接条件无效
  • 所有表中的所有行互相连接

为了避免笛卡尔集, 可以在 WHERE 加入有效的连接条件。

连接 n个表,至少需要 n-1个连接条件。 例如:连接三个表,至少需要两个连接条件。
例:
查询出公司员工的 last_name, department_name, city

select last_name, department_name, city
from departments d, employees e, locations l
where d.department_id = e.department_id and d.location_id = l.location_id
内连接和外连接:
自连接:

SQL语句的多表查询方式:
例:按照department_id查询employees(员工表)和departments(部门表)的信息。

方式一(通用型):SELECT … FROM … WHERE
SELECT e.last_name,e.department_id,d.department_name
FROM employees e,departments d
where e.department_id = d.department_id

方式二:SELECT … FROM … JOIN … ON …
这个是常用方式,较方式一,更易实现外联接(左、右、满)
SELECT last_name,e.department_id,department_name
FROM employees e
JOIN departments d
ON e.department_id = d.department_id

方式三:SELECT … JOIN … USING …
有局限性:好于方式二,但若多表的连接列列名不同,此法不合适
SELECT last_name,department_id,department_name
FROM employees
JOIN departments
USING(department_id)

方式四:SELECT … FROM … NATURAL JOIN …
有局限性:会自动连接两个表中相同的列(可能有多个:department_id和manager_id)
SELECT last_name,department_id,department_name
FROM employees
NATURAL JOIN departments
常用方式一二,三四了解即可。

on:

自然连接中是以具有相同名字的列为连接条件的。
可以使用 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);
使用 ON 子句创建多表连接:

join 表 on 条件 ,join 表 on 条件,join 表 on 条件
就是join一个表,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;

内连接: 合并具有同一列的两个以上的表的行, 结果集中不包含一个表与另一个表不匹配的行
外连接: 两个表在连接过程中除了返回满足连接条件的行以外还返回左(或右)表中不满足条件的行 ,这种连接称为左(或右) 外连接。没有匹配的行时, 结果表中相应的列为空(NULL). 外连接的 WHERE 子句条件类似于内部连接, 但连接条件中没有匹配行的表的列后面要加外连接运算符, 即用圆括号括起来的加号(+).

使用外连接可以查询不满足连接条件的数据。
外连接的符号是 (+)。
外关联是Oracle数据库的专有语句
Left Outer Join 和RIGHT OUTER JOIN
则是SQL-92的标准语句;
通常认为这两个SQL是可以等效的,但还是有些细微的差别。

Oracle中Left Outer Join和外关联(+)的区别:https://www.cnblogs.com/dar521lin/p/5443179.html

左外连接:取得左边所有记录;
右外连接:取得右边所有记录;

比如一个班级表在左边,一个学生表在右边,大部分学生和班级对应的,少量班级没有学生,也有少量学生没有分配班级;
左外的话会或者所有班级记录,没学生的班级,学生选项会显示null,没有班级的学生则查不出来。右外则相反。
关于表关联查询的理解(左连接和左外连接、右连接和右外连接、完全连接):https://blog.csdn.net/liangwanmian/article/details/78366588

右外连接:

1、oracle数据库专有的:

		select last_name, d.department_id, department_name
		from employees e, departments d
		where e.department_id(+) = d.department_id

2、SQL-92的标准语句: right outer join (省略写法 right jion)

SELECT e.last_name, e.department_id, d.department_name
FROM   employees e
RIGHT OUTER JOIN departments d
ON    (e.department_id = d.department_id) ;
左外连接:

1、oracle数据库专有的:

		select last_name, e.department_id, department_name
		from employees e, departments d
		where e.department_id = d.department_id(+)

2、SQL-92的标准语句: left outer join (省略写法 left jion)

SELECT e.last_name, e.department_id, d.department_name
FROM   employees e
LEFT OUTER JOIN departments d
ON   (e.department_id = d.department_id) ;

理解 “(+)” 的位置: 以左外连接为例, 因为左表需要返回更多的记录,
右表就需要 “加上” 更多的记录, 所以在右表的链接条件上加上 “(+)”

注意: 1). 两边都加上 “(+)” 符号, 会发生语法错误!
2). 这种语法为 Oracle 所独有, 不能在其它数据库中使用.

满外连接:

full outer join (省略写法 full jion)

select last_name, department_name
			from employees e
			 full join departments d
			on e.department_id = d.department_id	

sql 99:

SQL 99 的左外连接:left join
右外连接: right join
满外连接:full outer join
还有 join ··· on ··· 也是sql99的

6、分组函数(多行函数)

组函数不计算空值

可以对数值型数据使用AVG 和 SUM 函数

AVG: 求平均值

例:
查询全公司奖金基数的平均值(没有奖金的人按 0 计算)

select avg(nvl(commission_pct, 0))
		from employees
组函数忽略空值:
SELECT AVG(commission_pct)
FROM   employees;
NVL函数使分组函数无法忽略空值:
SELECT AVG(NVL(commission_pct, 0))
FROM   employees;
SUM: 合计

可以对任意数据类型的数据使用 MIN 和 MAX 函数:

MAX: 查询最大值
MIN: 查询最小值
COUNT: 计数函数

COUNT(*) 返回表中记录总数,适用于任意数据类型
例:
查询 employees 表中有多少个部门

select count(distinct department_id)
		from employees	
COUNT(expr): 返回expr不为空的记录总数
COUNT(distinct expr): 返回expr非空且不重复的记录总数
STDDEV: 求标准差(方差)

一般用不到
StdDev返回expr的样本标准偏差。它可用作聚集和分析函数

6、1 分组数据

GROUP BY: 将表中的数据分成若干组

例:
查询各个部门的平均工资
–错误:
avg(salary) 返回公司平均工资, 只有一个值; 而 department_id 有多个值, 无法匹配返回

select department_id, avg(salary)
		from employees

–正确:
按 department_id 进行分组

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

部门不写也可以:

select avg(salary)
   	from employees
   	group by department_id
在SELECT 列表中所有未包含在组函数中的列都应该包含在 GROUP BY 子句中。

Orlce数据库——表查询_第3张图片

包含在 GROUP BY 子句中的列不必包含在SELECT 列表中

Orlce数据库——表查询_第4张图片
在GROUP BY子句中包含多个列:

SELECT   department_id , job_id, SUM(salary)
FROM     employees
GROUP BY department_id, job_id ;
非法使用组函数:

1、没有GROUP BY

SELECT department_id, COUNT(last_name)
FROM   employees;

2、不能在 WHERE 子句中使用组函数。可以在 HAVING 子句中使用组函数。

SELECT   department_id, AVG(salary)
FROM     employees
WHERE    AVG(salary) > 8000
GROUP BY department_id;

需要使用having

HAVING: 过滤分组

使用 HAVING 过滤分组:

  • 行已经被分组。
  • 使用了组函数。
  • 满足HAVING 子句中条件的分组将被显示。

例:

SELECT   department_id, MAX(salary)
FROM     employees
GROUP BY department_id
HAVING   MAX(salary)>10000 ;
嵌套函数:

例:
显示各部门平均工资的最大值

SELECT   MAX(AVG(salary))
FROM     employees
GROUP BY department_id;

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