ORACLE函数开始讲解
准备两张表:
测试的表结构:
People
Person
内连接
1.用内链接进行查询
SELECT * FROM "Person" per INNER JOIN "People" peo ON PER."id"=PEO."id"
2.用内链接进行查询(省略了inner 关键字)
SELECT * FROM "Person" per JOIN "People" peo ON PER."id"=PEO."id"
3.多表查询
SELECT *FROM "Person" per,"People" peo WHERE PEO."id"=PER."id"
三个SQL 的结果我们也可以看出,他们的作用是一样的。
自然连接(Natural join):
自然连接是在两张表中寻找那些数据类型和列名都相同的字段,然后自动地将他们连接起来,并返回所有符合条件按的结果。
SELECT * FROM "Person" per NATURAL join "People" peo
这里我们并没有指定连接的条件,实际上oracle为我们自作主张的将,Person表中的id,name,age和People表中的id,name,age字段进行了连接。也就是 相当于:
SELECT * FROM "Person" per join "People" peo ON PEO."id"=PER."id" AND PEO."name"=PER."name" AND PEO."age"=PER."age"
所以我们也可以将 自然连接理解为 内连接的一种。
自然连接补充知识:
有关自然连接的一些注意事项:
(1).如果做自然连接的两个表的有多个字段都满足有相同名称个类型,那么他们会被作为自然连接的条件。
(2).如果自然连接的两个表仅是字段名称相同,但数据类型不同,那么将会返回一个错误。
外连接
outer join则会返回每个满足第一个(顶端)输入与第二个(底端)输入的联接的行。它还返回任何在第二个输入中没有匹配行的第一个输入中的行。外连接分为三种: 左外连接,右外连接,全外连接。 对应SQL:LEFT/RIGHT/FULL OUTER JOIN。 通常我们省略outer 这个关键字。 写成:LEFT/RIGHT/FULL JOIN。
在左外连接和右外连接时都会以一张表为基表,该表的内容会全部显示,然后加上两张表匹配的内容。 如果基表的数据在另一张表没有记录。 那么在相关联的结果集行中列显示为空值(NULL)。
对于外连接, 也可以使用“(+) ”来表示。 关于使用(+)的一些注意事项:
1.(+)操作符只能出现在where子句中,并且不能与outer join语法同时使用。
2. 当使用(+)操作符执行外连接时,如果在where子句中包含有多个条件,则必须在所有条件中都包含(+)操作符
3.(+)操作符只适用于列,而不能用在表达式上。
4.(+)操作符不能与or和in操作符一起使用。
5.(+)操作符只能用于实现左外连接和右外连接,而不能用于实现完全外连接。
左外连接
Left outer join/ left join方式
left join是以左表的记录为基础的,示例中Person可以看成左表,People可以看成右表,它的结果集是Person表中的数据,在加上Person表和People表匹配的数据。换句话说,左表(Person)的记录将会全部表示出来,而右表(People)只会显示符合搜索条件的记录。People表记录不足的地方均为NULL.
SELECT *FROM "Person" per LEFT outer JOIN "People" peo ON PER."id" =PEO."id"
或者是SELECT *FROM "Person" per LEFT JOIN "People" peo ON PER."id" =PEO."id"
(+)方式
用(+)来实现, 这个+号可以这样来理解: + 表示补充,即哪个表有加号,这个表就是匹配表。所以加号写在右表,左表就是全部显示,故是左连接。
-- 注意: 用(+) 就要用关键字where
SELECT *FROM "Person" per , "People" peo WHERE PER."id" =PEO."id"(+) ORDER BY PER."id"
右外连接
right outer join/ right join方式
和left join的结果刚好相反,是以右表(People)为基础的, 显示People表的所以记录,在加上Person和People 匹配的结果。 Person表不足的地方用NULL填充.
SELECT *FROM "Person" per RIGHT OUTER JOIN "People" peo ON PER."id" =PEO."id"
或者是
SELECT *FROM "Person" per RIGHT JOIN "People" peo ON PER."id" =PEO."id" ORDER BY PER."id"
(+)方式
用(+)来实现, 这个+号可以这样来理解: + 表示补充,即哪个表有加号,这个表就是匹配表。所以加号写在左表,右表就是全部显示,故是右连接。
SELECT *FROM "Person" per, "People" peo WHEREPER."id"(+) =PEO."id"
全外连接
全外连接=左外连接+右外链接-(重复记录)
full outer join/ full join
左表和右表都不做限制,所有的记录都显示,两表不足的地方用null 填充。 全外连接不支持(+)这种写法。
SELECT *FROM "Person" per full join "People" peo ON PER."id" =PEO."id" ORDER BY PER."id" 或者是SELECT *FROM "Person" per full outer join "People" peo ON PER."id" =PEO."id" ORDER BY PER."id"
JOIN...USING
JOIN...USING使用注意事项:
--关联的两个表中需要有相同的字段.(名字和类型相同)
--关联的字段在使用时不能加别名
SELECT * FROM "Person" JOIN "People" USING ("id")
自连接
关联双方的表是同一个表。
自连接(self join)是SQL语句中经常要用的连接方式,使用自连接可以将自身表的一个镜像当作另一个表来对待,从而能够得到一些特殊的数据。
示例:
在oracle的scott的schema中有一个表是emp。在emp中的每一个员工都有自己的mgr(经理),并且每一个经理自身也是公司的员工,自身也有自己的经理。
下面我们需要将每一个员工自己的名字和经理的名字都找出来。我们该怎么做?
如果我们有两张这样的表分别教worker和mgr,那么我们就很好写SQL语句。
Select worker.name,
Mgr.name
From worker,mgr
Where worker.id = mgr.id;
但现在我们只有一张emp表。所以我们可以采用自连接。自连接的本意就是将一张表看成多张表来做连接。我们可以这样来写SQL语句:
//查询员工编号,员工名,上级编号,上级名称
select e.empno,e.ename,e.mgr,e1.ename
from EMP e left outer join
EMP e1 on(e.mgr=e1.empno);
//查询员工编号,员工名,所在部门名,上级编号,上级名称
select e.empno,e.ename,d.dname,e.mgr,e1.ename
from EMP e
left outer join EMP e1 on(e.mgr=e1.empno)
left outer join DEPT d on(d.deptno=e.deptno);
各种连接的图示
count(*) 和 count(1)和count(列名)
执行效果上:
1.count(*)包括了所有的列,相当于行数,在统计结果的时候,不会忽略列值为NULL
2.count(1)包括了忽略所有列,用1代表代码行,在统计结果的时候,不会忽略列值为NULL
3.count(列名)只包括列名那一列,在统计结果的时候,会忽略列值为空(这里的空不是只空字符串或者0,而是表示null)的计数,即某个字段值为NULL时,不统计
执行效率上:
1. 列名为主键,count(列名)会比count(1)快
2. 列名不为主键,count(1)会比count(列名)快
3. 如果表多个列并且没有主键,则 count(1) 的执行效率优于 count(*)
4. 如果有主键,则 select count(主键)的执行效率是最优的
5. 如果表只有一个字段,则 select count(*)最优
SELECT "COUNT"("name") FROM "Person" ----只查询有值的对应字段的记录
SELECT "COUNT"(*) FROM "Person" ----全部查询所有记录,包括null
SELECT "COUNT"(1) FROM "Person" ---全部查询所有记录,包括null
数值型常用函数
ceil(n)
大于或等于数值n的最小整数
SELECT *FROM "Person" WHERE "age">(SELECT "CEIL"(19.3) FROM dual)
SELECT "CEIL"(19.3)cl FROM dual
floor(n)
小于等于数值n的最大整数
SELECT *FROM "Person" WHERE "age">(SELECT "FLOOR"(19.3) fl FROM dual)
SELECT "FLOOR"(19.3) fl FROM dual
round(n,m)
将n四舍五入,保留小数点后m位
SELECT round(19.33625,2)cl FROM dual
sign(n)
若n=0,则返回0,否则,n>0,则返回1,n<0,则返回-1
select sign(12)SIG from dual;
常用字符函数
initcap(char)
把每个字符串的第一个字符换成大写
select "INITCAP"('fff')inittc from dual
lower(char)
整个字符串换成小写
select "LOWER"('FFKKL') inittc from dual
substr(char,m,n)
取出从m字符开始的n个字符的子串
select substr('ABCDEF',2,2) from dual;
Length
求字符串的长度
select length('ACD') from dual;
||
并置运算符
select 'ABCD'||'EFGH' PING from dual; ABCDEFGH
日期型函数
sysdate
当前日期和时间
select sysdate from dual;
last_day
本月最后一天
select last_day(sysdate) from dual;
add_months(d,n)
当前日期d后推n个月
select add_months(sysdate,2) from dual;
months_between(d,n)
日期d和n相差月数select months_between(sysdate,to_date('20020812','YYYYMMDD')) from dual;
next_day(d,day) d后第一周指定day的日期select next_day(sysdate,'Monday') from dual;
特殊格式的日期型函数
ww
当年第几周
select to_char(sysdate,'ww') from dual;
w
本月第几周
select to_char(sysdate,'w') from dual;
DD
当月第几天 select to_char(sysdate,'DD') from dual;
D
周内第几天 select to_char(sysdate,'D') from dual;如 Sunday
to_number()
将合法的数字字符串 select to_number('88877') from dual; 88877
to_char()
将数字转换为字符串 select to_char(88877) from dual; '88877'
字符函数
字符函数主要用于修改字符列。这些函数接受字符输入,返回字符或数字值。Oracle 提供的一些字符函数如下。
CONCAT (char1, char2)
返回连接“char2”的“char1”。
示例 SELECT "CONCAT"("name", '爱上我了') CONCAT2 FROM "Person"
SELECT "CONCAT"("name", '爱上我了')||"CONCAT"("age", '18') CONCAT22 FROM "Person"
4. LPAD(char1,n [,char2])
返回“char1”,左起由“char2”中的字符补充到“n”个字符长。如果“char1”比“n”长,则函数返回“char1”的前“n”个字符。
示例 SELECT "LPAD"("name", 4, '*') FROM "Person"
5. LTRIM(string,trim_set)
从左边删除字符,此处“string”是数据库的列,或者是字面字符串,而“trim_set”是我们要去掉的字符的集合。
示例SELECT "LTRIM"("name",'小') FROM "Person"
6. REPLACE(string, if, then)
用 0 或其他字符代替字符串中的字符。“if”是字符或字符串,对于每个出现在“string”中的“if”,都用“then”的内容代替。
示例 SELECT "REPLACE"("name", '小', '李') FROM "Person"
7. RPAD(char1, n [,char2])
返回“char1”,右侧用“char2”中的字符补充到“n”个字符长。如果“char1”比“n”长,则函数返回“char1”的前“n”个字符。
示例SELECT "RPAD"("name", 2, '*') FROM "Person"
8. RTRIM(string,trim_set)
从右侧删除字符,此处“string”是数据库的列,或者是字面字符串,而“trim_set”是我们要去掉的字符的集合。
示例 SELECT "RTRIM"("name",'2') FROM "Person"
9. SOUNDEX(char)
返回包含“char”的表意字符的字符串。它允许比较英语中拼写不同而发音类似的字。
示例 SELECT ename FROM emp
WHERE SOUNDEX(ename) = SoUNDEX('SMYTHE');
10. SUBSTR(string, start [,count])
返回“string”中截取的一部分。该命令截取“string”的一个子集,从“start”位置开始,持续“count”个字符。如果我们不指定“count”,则从“start”开始截取到“string”的尾部。
示例 SELECT "SUBSTR"("name", 1, 1)FROM "Person"
11. TRANSLATE(string, if, then)
“if”中字符的位置,并检查“then”的相同位置,然后用该位置的字符替换“string”中的字符。
示例 SELECT TRANSLATE(ename,'AEIOU', 'XXXXX') FROM emp;
12. UPPER(string)
返回大写的“string”。
示例 SELECT UPPER('aptech computer education') FROM dual;
13. ASCII(string)
该命令是“American Standard Code for Information Interchange”的缩写。它是使用数字表示可打印字符的基本规则。该函数返回“string”中第一个(最左边)字符的ASCII值。
示例 SELECT ASCII('APTECH') from dual;
14. INSTR (string, set[, start[, occurrence] ] )
该命令“string”中从“start”位置开始查找字符集合的位置,再查找“set”出现的第一次、第二次等等的“occurrence”(次数)。“start”的值也可以是负数,代表从字符串结尾开始向反方向搜索。该函数也用于数字和日期数据类型。
示例 SELECT INSTR('aptech is aptech','ap',1,2) FROM DUAL;
15. LENGTH(string)
返回“string”的长度值。
示例 SELECT "name" ,"LENGTH"("name") FROM "Person"
Oracle中的Exists、In、ANY、AL
Exists:子查询至少返回一行时条件为true。
Not Exists:子查询不返回任何一行时条件为true。
In:与子查询返回结果集中某个值相等。
Not In:与子查询返回结果集中任何一个值不相等。
>ANY:比子查询返回结果中的某个值大。
=ANY:与子查询返回结果中的某个值相等。
<ANY:比子查询返回结果中的某个值小。
>ALL:比子查询返回结果中的所有值都大。
<ALL :比子查询返回结果中的所有值都小
Exists
SELECT *FROM "Person" PER WHERE EXISTS(SELECT *FROM "People" PEO WHERE PEO."id"=PER."id" )