Oracle查询
一、单表查询
1、简单条件查询
1)精确查询
SELECT*
FROMT_OWNERS
WHEREwatermeter = '30408'
2)模糊查询
SELECT*
FROMt_owners
WHEREname LIKE '%刘%'
3)and运算符
SELECT*
FROMt_owners
WHEREname LIKE '%刘%' AND housenumber LIKE '%5%'
4)or运算符
SELECT*
FROMt_owners
WHEREname LIKE '%刘%' OR housenumber LIKE '%5%'
5)范围查询
-- 运算符
SELECT*
FROMT_ACCOUNT
WHEREusenum >= 10000 AND usenum <= 20000-- between and
SELECT*
FROMT_ACCOUNT
WHEREusenum BETWEEN 10000 AND 20000
6)空值查询
-- is null
SELECT*
FROMT_PRICETABLE t
WHEREmaxnum IS NULL-- is not null
SELECT*
FROMT_PRICETABLE t
WHEREmaxnum IS NOT NULL
2、去掉重复记录
SELECT DISTINCT*
FROMT_OWNERS
3、排序查询
1)升序排序
SELECT*
FROMT_ACCOUNT
ORDER BYusenum
2)降序排序
SELECT*
FROMT_ACCOUNT
ORDER BYusenum DESC
4、基于伪列的查询
1)ROWID
ROWID 伪列是该行的物理地址。使用 ROWID 可以快速的定位表中的某一行。ROWID 值可以唯一的 标识表中的一行。
SELECT ROWID,t.*
FROMT_AREA t
可以通过指定 ROWID 来查询记录
SELECT ROWID,t.*
FROMT_AREA t
WHEREROWID = 'AAAM1uAAGAAAAD8AAC';
2)ROWNUM
ROWNUM 为结果集中每一行标识一个行号,第一行返回 1, 第二行返回 2…
SELECT ROWNUM,t.*
FROMT_OWNERTYPE t
5、聚合统计
1)聚合函数
1. 求和 sum
SELECTsum( usenum )
FROMT_ACCOUNT
WHEREyear = '2012'
2. 求平均 avg
SELECTavg( usenum )
FROMT_ACCOUNT
WHEREyear = '2012'
3. 求最大值 max
SELECTmax( usenum )
FROMT_ACCOUNT
WHEREyear = '2012'
4. 求最小值 min
SELECTcount( * )
FROMT_OWNERS t
WHEREownertypeid =1
5. 统计记录个数 count
select count(*) from T_OWNERS t where ownertypeid=1
2)分组聚合 group by
select 后一定是分组聚合的条件或者是聚合函数
SELECTareaid,sum( money )
FROMt_account
GROUP BYareaid
3)分组后条件查询 having
SELECTareaid,sum( money )
FROMt_account
GROUP BYareaid
HAVINGsum( money ) > 169000
二、连接查询
1、多表内连接查询
SELECTo.id 业主编号,o.name 业主名称,ot.name 业主类型
FROMT_OWNERS o,T_OWNERTYPE ot
WHEREo.ownertypeid = ot.id
SELECTo.id 业主编号,o.name 业主名称,ad.name 地址,ot.name 业主类型
FROMT_OWNERS o,T_OWNERTYPE ot,T_ADDRESS ad
WHEREo.ownertypeid = ot.id AND o.addressid = ad.id
2、左外连接查询
-- SQL1999
SELECTow.id,ow.name,ac.year,ac.month,ac.money
FROMT_OWNERS owLEFT JOIN T_ACCOUNT ac ON ow.id = ac.owneruuid-- ORACLE
SELECTow.id,ow.name,ac.year,ac.month,ac.money
FROMT_OWNERS ow,T_ACCOUNT ac
WHEREow.id = ac.owneruuid ( + )
3、右外连接查询
-- SQL1999
SELECTow.id,ow.name,ac.year,ac.month,ac.money
FROMT_OWNERS owRIGHT JOIN T_ACCOUNT ac ON ow.id = ac.owneruuid-- ORACLE
SELECTow.id,ow.name,ac.year,ac.month,ac.money
FROMT_OWNERS ow,T_ACCOUNT ac
WHEREow.id ( + ) = ac.owneruuid
三、子查询
1、where子句中的子查询
1)单行子查询
- 子查询只返回一条记录
- 单行操作符(=、>、<…)
SELECT*
FROMT_ACCOUNT
WHEREyear = '2012' AND month = '01' AND usenum > (SELECTavg( usenum ) FROMT_ACCOUNT WHEREyear = '2012' AND month = '01' )
2)多行子查询
- 子查询返回了多条记录
- 多行操作符(
in
、any
、all
)
in运算符
select * from T_OWNERS where addressid in ( 1,3,4 )
-- in
SELECT *
FROM T_OWNERS
WHERE addressid IN ( SELECT id FROM t_address WHERE name LIKE '%花园%' )-- not in
SELECT *
FROM T_OWNERS
WHERE addressid NOT IN ( SELECT id FROM t_address WHERE name LIKE '%花园%' )
2、from子句中的子查询
SELECT*
FROM(SELECTo.id 业主编号,o.name 业主名称,ot.name 业主类型 FROMT_OWNERS o,T_OWNERTYPE ot WHEREo.ownertypeid = ot.id )
WHERE业主类型= '居民'
3、select子句中的子查询
select 子句的子查询必须为单行子查询
SELECTid,name,( SELECT name FROM t_address WHERE id = addressid ) addressname
FROMt_owners
四、简单分页查询
在 ORACLE 进行分页查询,需要用到伪列 ROWNUM
和嵌套查询
-- 前十条记录
SELECT ROWNUM,t.*
FROMT_ACCOUNT t
WHEREROWNUM <= 10
-- 11至20记录(错误写法)
-- 因为 rownum 是在查询语句扫描每条记录时产生的,所以不能使用"大于"符号
SELECT ROWNUM ,t.*
FROMT_ACCOUNT t
WHEREROWNUM > 10 AND ROWNUM <= 20
-- 11至20记录(正确写法)
-- 利用子查询
SELECT*
FROM(SELECT ROWNUM r,t.* FROMT_ACCOUNT t WHEREROWNUM <= 20)
WHERE r > 10
五、单行函数
1、字符函数
1)求字符串长度 LENGTH
dual 伪表:为了补全语法而存在
select length('ABCD') from dual
2)求字符串的子串 SUBSTR
select substr('ABCD',2,2) from dual;
3)字符串拼接 CONCAT
select concat('ABC','D') from dual
select 'ABC'||'D' from dual;
2、数值函数
1)四舍五入函数 ROUND
select round(100.567) from dual
select round(100.567,2) from dual
2)截取函数 TRUNC
select trunc(100.567) from dual
select trunc(100.567,2) from dual
3)取模 MOD
select mod(10,3) from dual
3、日期函数
0)当前日期与时间 sysdate
select sysdate from dual
1)加月函数 ADD_MONTHS
在当前日期基础上加指定的月
select add_months(sysdate,2) from dual
2)求所在月最后一天 LAST_DAY
select last_day(sysdate) from duall
3)日期截取 TRUNC
以
2016/10/11
为例
select TRUNC(sysdate) from dual
select TRUNC(sysdate,'yyyy') from dual
select TRUNC(sysdate,'mm') from dual
4、转换函数
1)数字转字符串 TO_CHAR
select TO_CHAR(1024) from dual
2)日期转字符串 TO_CHAR
select TO_CHAR(sysdate,'yyyy-mm-dd') from dualselect TO_CHAR(sysdate,'yyyy-mm-dd hh:mi:ss') from dual
3)字符串转日期 TO_DATE
select TO_DATE('2017-01-01','yyyy-mm-dd') from dual
4)字符串转数字 TO_NUMBER
select to_number('100') from dual
5、其它函数
1)空值处理函数 NVL
NVL(检测的值,如果为 null 的值)
select NVL(NULL,0) from dual
2)空值处理函数 NVL2
NVL2(检测的值,如果不为 null 的值,如果为 null 的值)
SELECTPRICE,MINNUM,NVL2( MAXNUM, to_char( MAXNUM ), '不限' )
FROMT_PRICETABLE
WHEREOWNERTYPEID =1
3)条件取值 decode
根据条件返回相应值
decode(条件,值1,翻译值1,值2,翻译值2,...值n,翻译值n,[缺省值])
-- decode 语句实现
SELECTname,decode(ownertypeid,1, ' 居 民 ',2, ' 行 政 事 业 单 位 ',3, '商业' ) 类型
FROMT_OWNERS
-- 也可以用 case when then 语句来实现
SELECTname,(CASE ownertypeid WHEN 1 THEN '居民' WHEN 2 THEN '行政事业单位' WHEN 3 THEN'商业' ELSE '其它' END )
FROMT_OWNERS
-- case when then 语句的另外一种写法
SELECTname,(CASE WHEN ownertypeid = 1 THEN '居民' WHEN ownertypeid = 2 THEN '行政事业' WHEN ownertypeid = 3 THEN '商业' END )
FROMT_OWNERS
六、分析函数
1、RANK
相同的值排名相同,排名跳跃
SELECTrank ( ) over ( ORDER BY usenum DESC ),usenum
FROMT_ACCOUNT
2、DENSE_RANK
相同的值排名相同,排名连续
SELECTdense_rank ( ) over ( ORDER BY usenum DESC ),usenum
FROMT_ACCOUNT
3、ROW_NUMBER
返回连续的排名,无论值是否相等
SELECTrow_number ( ) over ( ORDER BY usenum DESC ),usenum
FROMT_ACCOUNT
七、集合运算
1、并集运算
UNION ALL 不去掉重复记录
SELECT*
FROMt_owners
WHEREid <= 7 UNION ALL SELECT * FROM t_owners WHERE id >=5
UNION 去掉重复记录
SELECT*
FROMt_owners
WHEREid <= 7 UNION SELECT * FROM t_owners WHERE id >=5
2、交集运算
SELECT*
FROMt_owners
WHEREid <= 7 INTERSECT SELECT * FROM t_owners WHERE id >=5
3、差集运算
SELECT*
FROMt_owners
WHEREid <= 7 MINUS SELECT * FROM t_owners WHERE id >=5
可以用 minus 运算符来实现分页
SELECT ROWNUM,t.* FROMT_ACCOUNT t WHEREROWNUM <= 20 MINUS SELECT ROWNUM,t.* FROMT_ACCOUNT t WHEREROWNUM <= 10