学自B站黑马程序员
1.单表查询
//查询水表编号为 30408 的业主记录
select * from T_OWNERS where watermeter='30408'
//查询业主名称包含“刘”的业主记录
select * from t_owners where name like '%刘%'
//查询业主名称包含“刘”的并且门牌号包含 5 的业主记录
select * from t_owners where name like '%刘%' and housenumber
like '%5%'
//查询业主名称包含“刘”的或者门牌号包含5的业主记录
select * from t_owners where name like '%刘%' or housenumber like '%5%'
//查询业主名称包含“刘”的或者门牌号包含5的业主记录,并且地址编号为3的记录
select * from t_owners where (name like '%刘%' or housenumber like '%5%') and addressid=3
//因为 and 的优先级比 or 大,所以我们需要用 ( ) 来改变优先级
//查询台账记录中用水字数大于等于 10000,并且小于等于 20000 的记录
select * from T_ACCOUNT where usenum>=10000 and usenum<=20000
select * from T_ACCOUNT where usenum between 10000 and 20000 //闭区间
//查询 T_PRICETABLE 表中 MAXNUM 为空的记录
select * from T_PRICETABLE t where maxnum is null
//查询 T_PRICETABLE 表中 MAXNUM 不为空的记录
select * from T_PRICETABLE t where maxnum is not null
//查询业主表中的地址 ID,不重复显示
select distinct addressid from T_OWNERS
//对多个字段去重指两个字段都一模一样才会被去重,有一个字段不同都会保留
select distinct addressid,ownertypeid from T_OWNERS
//对T_ACCOUNT表按使用量进行升序排序
select * from T_ACCOUNT order by usenum
//对T_ACCOUNT表按使用量进行降序排序
select * from T_ACCOUNT order by usenum desc
2.基于伪列的查询
实际表中还有一些附加的列,称为伪列。伪列就像表中的列一样,但是在表中并不存储。伪列只能查询,不能进行增删改操作。例如:ROWID 和 ROWNUM。伪列指在建表时没有指定这一列,但oracle会自动添加这列,每个表都有
-
ROWID (每一行数据的物理地址)
- 常规的select * 是无法查询到伪列的,此时需要给 * 起别名,或者指定字段不用*
- select rowid,t.* from t_owners t
- select rowid,id from t_owners
- 也可以通过rowid进行查询,rowid相当于唯一标识
- rowid本身是物理地址,可以直接定位,故用rowid查询会更快
- 使用 ROWID 可以显示行是如何存储的。
-
ROWNUM(每一行的行号,与id无关)
- ROWNUM是结果集的序号,通过ROWNUM伪列可限制查询结果集中返回的行数
- select ROWNUM,id from t_owners
- select ROWNUM,id from t_owners where id>3
3.聚合统计
//统计 2012 年所有用户的用水量总和此时的year是字符串类型的
select sum(usenum) from t_account where year='2012'
//统计 2012 年所有用水量(字数)的平均值
select avg(usenum) from T_ACCOUNT where year='2012'
//统计 2012 年最高用水量
select max(usenum) from T_ACCOUNT where year='2012'
//统计 2012 年最低用水量(字数)
select min(usenum) from T_ACCOUNT where year='2012'
//统计业主类型 ID 为 1 的业主数量
select count(*) from T_OWNERS t where ownertypeid=1
//分组聚合统计select后一定是分组聚合的条件或者聚合函数(否则语法不允许)
//按区域分组统计水费合计数(首先查询总数,再根据group by areaid进行分组)
select areaid,sum(money) from t_account group by areaid
//having是分组后的条件查询(where在分组前条件筛选)
//查询水费合计大于 16900 的区域及水费合计
select areaid,sum(money) from t_account group by areaid
having sum(money)>169000
4.多表查询
① 多表内连接查询(不加条件会成为一个笛卡尔积,id字段重复需要加别名)
//多表内连接查询(不加条件会成为一个笛卡尔积,id字段重复需要加别名)
//查询显示业主编号,业主名称,业主类型名称(来自业主表,业主类型表)
select o.id 业主编号,o.name 业主名称,ot.name 业主类型
from T_OWNERS o,T_OWNERTYPE ot
where o.ownertypeid=ot.id
//查询显示业主编号,业主名称、地址和业主类型(在加上地址表)
select o.id 业主编号,o.name 业主名称,ad.name 地址,
ot.name 业主类型
from T_OWNERS o,T_OWNERTYPE ot,T_ADDRESS ad
where o.ownertypeid=ot.id and o.addressid=ad.id
//查询显示业主编号、业主名称、地址、所属区域、业主分类(在加上区域表)
select o.id 业主编号,o.name 业主名称,ar.name 区域, ad.name 地
址, ot.name 业主类型
from T_OWNERS o ,T_OWNERTYPE ot,T_ADDRESS ad,T_AREA ar
where o.ownertypeid=ot.id and o.addressid=ad.id and
ad.areaid=ar.id
//查询显示业主编号、业主名称、地址、所属区域、收费员、业主分类(在加上收费员表)
select ow.id 业主编号,ow.name 业主名称,ad.name 地址,
ar.name 所属区域,op.name 收费员, ot.name 业主类型
from T_OWNERS ow,T_OWNERTYPE ot,T_ADDRESS ad ,
T_AREA ar,T_OPERATOR op
where ow.ownertypeid=ot.id and ow.addressid=ad.id
and ad.areaid=ar.id and ad.operatorid=op.id
② 左外链接(以左边为主,右边可以是空的,left join左边为主表,where变on)
//查询业主的账务记录,显示业主编号、名称、年、月、金额。如果此业主没有账务记录也要列出姓名。(人可能存在,但没有账务记录)我们要查询这个结果,需要用到 T_OWNERS(业主表) ,T_ACCOUNT(台账表) 按照查询结果,业主表为左表、账务表为右表。
//SQL1999 标准的语法(通用的语言标准)
SELECT ow.id,ow.name,ac.year,ac.month,ac.money
FROM T_OWNERS ow left join T_ACCOUNT ac
on ow.id=ac.owneruuid
//oracle特有的语法(内连接的写法,如果是左外链接就在右表的条件上加(+))右外就反过来
SELECT ow.id,ow.name,ac.year ,ac.month,ac.money FROM
T_OWNERS ow,T_ACCOUNT ac
WHERE ow.id=ac.owneruuid(+)
③ 右外链接(以右边为主,左边可以是空的,right join右边为主表,where变on)
//查询业主的账务记录,显示业主编号、名称、年、月、金额。如果账务记录没有对应的业主信息,也要列出记录。
//SQL1999 标准的语法(通用的语言标准)
select ow.id,ow.name,ac.year,ac.month,ac.money from
T_OWNERS ow right join T_ACCOUNT ac
on ow.id=ac.owneruuid
//oracle特有的语法
select ow.id,ow.name,ac.year,ac.month,ac.money from
T_OWNERS ow , T_ACCOUNT ac
where ow.id(+) =ac.owneruuid
5.子查询(嵌套查询)
① where字句中的子查询(查询结果是where字句的条件值)
//单行子查询(子查询返回的结果只能是一条记录)
//单行操作符(=,>,>=,<,<=,<>)
//查询 2012 年 1 月用水量大于平均值的台账记录,先查询1月平均用水量,再查比他大的
select * from T_ACCOUNT
where year='2012' and month='01' and usenum>
(select avg(usenum) from T_ACCOUNT where year='2012' and month='01')
//多行子查询(子查询结果可返回多行,操作符in,any和子查询返回的任意一个值比较,all和子查询返回的所有值比较)
//查询地址编号为 1 、3、4 的业主记录
select * from T_OWNERS
where addressid in (1,3,4)
//查询地址含有“花园”的业主的信息,先查地址含花园的地址编号,再查地址编号1,4的业主
select * from T_OWNERS
where addressid in
(select id from t_address where name like '%花园%')
//查询地址不含有“花园”的业主的信息
select * from T_OWNERS
where addressid not in
(select id from t_address where name like '%花园%')
② from字句中的子查询(查询结果为多行子查询(视为一张表))
//查询显示业主编号,业主名称,业主类型名称,条件为业主类型为”居民”,先查业主编号,业主名称,业主类型名称(业主表,业主类型表)
select * from
(select o.id 业主编号,o.name 业主名称,ot.name 业主类型
from T_OWNERS o,T_OWNERTYPE ot
where o.ownertypeid=ot.id)
where 业主类型='居民'
③ select字句中的子查询(必须为单行子查询)
//列出业主信息,包括 ID,名称,所属地址。将addressid替换成select语句起别名为addressname
select id,name,
(select name from t_address where id=addressid) addressname
from t_owners
//列出业主信息,包括 ID,名称,所属地址,所属区域(地址表中有区域id)
select id,name,
(select name from t_address where id=addressid) addressname,
(select (select name from t_area where id=areaid) from
t_address where id=addressid) adrename
from t_owners;
6.分页查询
//分页查询台账表 T_ACCOUNT,每页10条记录,需要用到伪列 ROWNUM 和嵌套查询
//第一页rownum后面的运算符只能是<或者<= rownum的值是通过逐行扫描产生的 当使用大于或等于符号时,rownum的值还没有产生(扫描一行有值,rownum才会增加)
select rownum,t.* from T_ACCOUNT t where rownum<=10
//可通过子查询查询第二页 将rownum的结果作为一个表 对这个表进行查询
select * from
(select rownum r,t.* from T_ACCOUNT t where rownum<=20)
where r>10//基于排序的分页(三层嵌套)
//分页查询台账表 T_ACCOUNT,每页 10 条记录,按使用字数降序排序
//rownum的生成时机,在表扫描的时候生成,order by会在扫描后再进行排序运算,产生rownum值后再进行排序所以会出现乱序现象
select * from
(select rownum r,t.* from
(select * from T_ACCOUNT order by usenum desc) t
where rownum<=20)
where r>10
6.单行函数
① 字符函数(字符串相关)
ASCII 返回对应字符的十进制值
CHR 给出十进制返回字符
CONCAT 拼接两个字符串,与 || 相同
INITCAT 将字符串的第一个字母变为大写
INSTR 找出某个字符串的位置
INSTRB 找出某个字符串的位置和字节数
LENGTH 以字符给出字符串的长度
LENGTHB 以字节给出字符串的长度
LOWER 将字符串转换成小写
LPAD 使用指定的字符在字符的左边填充
LTRIM 在左边裁剪掉指定的字符
RPAD 使用指定的字符在字符的右边填充
RTRIM 在右边裁剪掉指定的字符
REPLACE 执行字符串搜索和替换
SUBSTR 取字符串的子串
SUBSTRB 取字符串的子串(以字节)
SOUNDEX 返回一个同音字符串
TRANSLATE 执行字符串搜索和替换
TRIM 裁剪掉前面或后面的字符串
UPPER 将字符串变为大写
//dual是伪表 标准语句select后必有from 可使用伪表伪表无真实意义可测试函数
//求字符串长度 LENGTH
select length('ABCD') from dual;
//求字符串的子串 SUBSTR (原字符串,从第几位截取(从1开始),截取字符数)
select substr('ABCD',2,2) from dual;
//字符串拼接 CONCAT CONCAT内只能有两个串,想拼接多个需要嵌套或者||(拼接符号)
select concat('ABC','D') from dual;
select concat(concat('ABC','D'),'EF') from dual;
select 'ABC'||'D' from dual;
② 数值函数(对数值进行操作)
ABS(value) 绝对值
CEIL(value) 大于或等于 value 的最小整数
COS(value) 余弦
COSH(value) 反余弦
EXP(value) e 的 value 次幂
FLOOR(value) 小于或等于 value 的最大整数
LN(value) value 的自然对数
LOG(value) value 的以 10 为底的对数
MOD(value,divisor) 求模
POWER(value,exponent) value 的 exponent 次幂
ROUND(value,precision) 按 precision 精度 4 舍 5 入
SIGN(value) value 为正返回 1;为负返回-1;为 0 返回 0. SIN(value) 余弦
SINH(value) 反余弦
SQRT(value) value 的平方根
TAN(value) 正切
TANH(value) 反正切
TRUNC(value,按 precision) 按照 precision 截取 value
VSIZE(value) 返回 value 在 ORACLE 的存储空间大小
//四舍五入函数 ROUND 默认从整数开始 可通过逗号进行小数保留
select round(100.456) from dual //100
select round(100.567) from dual //101
select round(100.567,2) from dual //100.57
//截取函数 TRUNC 默认从整数开始 可通过逗号进行小数保留
select trunc(100.567) from dual //100
select trunc(100.567,2) from dual //100.56
//取模 MOD 10和3的余数
select mod(10,3) from dual //1
③ 日期函数
ADD_MONTHS 在日期 date上增加 count个月
GREATEST(date1,date2,. . .) 从日期列表中选出最晚的日期
LAST_DAY( date ) 返回日期 date 所在月的最后一天
LEAST( date1, date2, . . .) 从日期列表中选出最早的日期
MONTHS_BETWEEN(date2, date1) 给出 Date2 - date1 的月数(可以是小数)
NEXT_DAY( date,’day’) 给出日期 date之后下一天的日期,这里的 day为星期,如: MONDAY,Tuesday等。
NEW_TIME(date,’this’,’other’) 给出在 this 时区=Other 时区的日期和时间
ROUND(date,’format’) 未指定 format 时,如果日期中的时间在中午之前,则将日期中的时间截断为 12 A.M.(午夜,一天的开始),否则进到第二天。时间截断为 12 A.M.(午夜,一天的开始), 否则进到第二天。
TRUNC(date,’format’) 未指定 format 时,将日期截为 12 A.M.( 午夜,一天的
开始).
//用 sysdate 这个系统变量来获取当前日期和时间
select sysdate from dual
//加月函数 ADD_MONTHS :在当前日期基础上加指定的月 往后数是+ 往前数是-(用负数)
select add_months(sysdate,2) from dual
//求所在月最后一天 LAST_DAY
select last_day(sysdate) from dual
//日期截取 TRUNC
select sysdate from dual //2023/9/20 星期三 上午09:30:59
//按日截取,保留日的部分(星期几),把时间截掉
select TRUNC(sysdate) from dual //2023/9/20 星期三
//按月截取,mm代表月,把日截掉,获得当月第一天
select TRUNC(sysdate,'mm') from dual //2023/9/1 星期五
//按年截取,yyyy代表年,把月截掉,获得当年第一天
select TRUNC(sysdate,'yyyy') from dual //2023/1/1 星期日
//按小时截取,hh代表小时,获得当前小时
select TRUNC(sysdate,'hh') from dual //2023/9/20 星期三 上午09:00:00
//按分钟截取,mi代表分钟,获得当前分钟,(无法按秒截取)
select TRUNC(sysdate,'mi') from dual //2023/9/20 星期三 上午09:39:00
④ 转换函数
CHARTOROWID 将 字符转换到 rowid 类型
CONVERT 转换一个字符节到另外一个字符节
HEXTORAW 转换十六进制到 raw 类型
RAWTOHEX 转换 raw 到十六进制
ROWIDTOCHAR 转换 ROWID 到字符
TO_CHAR 转换日期格式到字符串
TO_DATE 按照指定的格式将字符串转换到日期型
TO_MULTIBYTE 把单字节字符转换到多字节
TO_NUMBER 将数字字串转换到数字
TO_SINGLE_BYTE 转换多字节到单字节
//数字转字符串 TO_CHAR (靠右显示是数字靠左是字符串,字符串可以拼接)
select TO_CHAR(1024) from dual //1024
select TO_CHAR(1024)||'分' from dual //1024分
select 1024||'分' from dual//数字也能拼接它会自动转换 拼空串也行
//日期转字符串 TO_CHAR (需要规定日期格式,可以通过拼接获得想要的格式)
select TO_CHAR(sysdate,'yyyy-mm-dd') from dual //2023-9-20
select TO_CHAR(sysdate,'yyyy')||'年'||TO_CHAR(sysdate,'mm')||'月' from dual //2023年9月
select TO_CHAR(sysdate,'yyyy-mm-dd hh:mi:ss') from dual
//字符串转日期 TO_DATE (需要指定日期的书写格式) //2023/9/20 星期三
//查询时无法直接写日期,但是可以写日期字符串,然后作为条件传入
select TO_DATE('2023-09-20','yyyy-mm-dd') from dual
//字符串转数字TO_NUMBER(靠右显示,数字可以加减,字符串会自动转数字,不是数字会报错)
select to_number('100') from dual //100
select to_number('100')+10 from dual //110
select '100'+10 from dual //110(加0也可转数字)
⑤ 其他函数
//空值处理函数 NVL 当检测到值为null时自动转换为其他值(若第一个参数为null,返回参数二,若参数一不为null,返回成参数一)
select NVL(NULL,0) from dual
//显示价格表中业主类型 ID 为 1 的价格记录,如果上限值为 NULL,则显示 9999999
//若需要转换的列为数字,则参数二不能为非数字的字符串,此时可用nvl2函数
select PRICE,MINNUM,NVL(MAXNUM,9999999)
from T_PRICETABLE where OWNERTYPEID=1//空值处理函数 NVL2(检测的值,如果不为 null的值,如果为 null的值)
//显示价格表中业主类型 ID为 1的价格记录,如果上限值为 NULL,显示“不限”(字符串)
select PRICE,MINNUM,NVL2(MAXNUM,to_char(MAXNUM) , '不限')
from T_PRICETABLE where OWNERTYPEID=1//条件取值 decode(条件的值,等于值1则返回翻译值1,等于值2则返回翻译值2)(oracle)
//语法decode(条件,值 1,翻译值 1,值 2,翻译值 2,...值 n,翻译值 n,缺省值)
//【功能】根据条件返回相应值,缺省值可以省略,参数个数为偶数则最后一位为缺省值,参数个数为奇数则没有缺省值,若条件没匹配上,参数个数为奇数返回null偶数返回缺省值,若有多个值匹配成功则返回第一个成功的(按顺序走的)
select decode(100,1,2,3,4,100,200)from dual; //200
//显示下列信息(不要关联查询业主类型表,直接判断 1 2 3 的值
select name,decode(ownertypeid,1,'居民',2,'行政事业单位',3,'商业') as 类型 from T_OWNERS
//sql1999上面语句可用case(条件)when(如果)then(那么)else(缺省)语句实现,end结束
select name ,(case ownertypeid
when 1 then '居民'
when 2 then '行政事业单位'
when 3 then '商业'
else '其它'
end
) from T_OWNERS
//还有另外一种写法:(更复杂的需求使用下面的方法)
select name,(case
when ownertypeid= 1 then '居民'
when ownertypeid= 2 then '行政事业'
when ownertypeid= 3 then '商业'
else '其它'
end )
from T_OWNERS
7.行列转换
//按月份统计 2012 年各个地区的水费
//思路:首先查询总共的水费,设定查询年份,根据区域id分组,将id提前面做select子查询,根据区域id查询对应区域名起别名,通过case对总水费进行划分起别名,then将条件设置为1月
select (select name from T_AREA where id= areaid ) 区域,
sum( case when month='01' then money else 0 end) 一月,
sum( case when month='02' then money else 0 end) 二月,
sum( case when month='03' then money else 0 end) 三月,
sum( case when month='04' then money else 0 end) 四月,
sum( case when month='05' then money else 0 end) 五月,
sum( case when month='06' then money else 0 end) 六月,
sum( case when month='07' then money else 0 end) 七月,
sum( case when month='08' then money else 0 end) 八月,
sum( case when month='09' then money else 0 end) 九月,
sum( case when month='10' then money else 0 end) 十月,
sum( case when month='11' then money else 0 end) 十一月,
sum( case when month='12' then money else 0 end) 十二月
from T_ACCOUNT where year='2012' group by areaid
//按季度统计 2012 年各个地区的水费
select (select name from T_AREA where id= areaid ) 区域,
sum( case when month>='01' and month<='03' then money else
0 end) 第一季度,
sum( case when month>='04' and month<='06' then money else
0 end) 第二季度,
sum( case when month>='07' and month<='09' then money else
0 end) 第三季度,
sum( case when month>='10' and month<='12' then money else
0 end) 第四季度
from T_ACCOUNT where year='2012' group by areaid
8.分析函数
//RANK 相同的值排名相同,排名跳跃
//对T_ACCOUNT 表的usenum 字段进行排序,相同的值排名相同,排名跳跃
//将降序规则放入over中,rank() over(order by usenum desc)这个整体算一列
select rank() over(order by usenum desc) 排名,usenum from T_ACCOUNT
//DENSE_RANK 相同的值排名相同,排名连续
//对T_ACCOUNT 表的usenum 字段进行排序,相同的值排名相同,排名连续
select dense_rank() over(order by usenum desc),usenum from T_ACCOUNT
//ROW_NUMBER 返回连续的排名,无论值是否相等
//对T_ACCOUNT 表的usenum 字段进行排序,返回连续的排名,无论值是否相等
select row_number() over(order by usenum desc),usenum from T_ACCOUNT
//用 row_number()分析函数实现的分页查询相对三层嵌套子查询要简单的多
select * from
(select row_number() over(order by usenum desc )
rownumber,usenum from T_ACCOUNT)
where rownumber>10 and rownumber<=20
9.集合运算
集合运算就是将两个或者多个结果集组合成为一个结果集
UNION ALL(并集),返回各个查询的所有记录,包括重复记录。
UNION(并集),返回各个查询的所有记录,不包括重复记录。
INTERSECT(交集),返回两个查询共有的记录。
MINUS(差集),返回第一个查询检索出的记录减去第二个查询检索出的记录之后剩余的记录。a的结果集中减去ab的交集
//UNION ALL 不去掉重复记录(1-10+重复记录)将下面的结果集顺序排在上面的结果集下面
select * from t_owners where id<=7
union all
select * from t_owners where id>=5
//UNION 去掉重复记录(1-10)
select * from t_owners where id<=7
union
select * from t_owners where id>=5
//交集运算(两个结果集的重复部分)
select * from t_owners where id<=7
intersect
select * from t_owners where id>=5
//差集运算(上面的结果集减去下面的结果集,跟顺序有关)
select * from t_owners where id<=7
minus
select * from t_owners where id>=5
//用 minus 运算符来实现分页(通过差集实现分页查询)
select rownum,t.* from T_ACCOUNT t where rownum<=20
minus
select rownum,t.* from T_ACCOUNT t where rownum<=10
10.总结
//1.收费日报单(总)
//统计某日的收费,按区域分组汇总
select (select name from T_AREA where id= areaid ) 区域,
sum(usenum)/1000 "用水量(吨)" ,sum(money) 金额
from T_ACCOUNT
where to_char(feedate,'yyyy-mm-dd')='2012-05-14'
group by areaid
//2.收费日报单(收费员)
//统计某收费员某日的收费,按区域分组汇总
select (select name from T_AREA where id= areaid ) 区域,
sum(usenum)/1000 "用水量(吨)" ,sum(money) 金额
from T_ACCOUNT
where to_char(feedate,'yyyy-mm-dd')='2012-05-14'
and feeuser=2
group by areaid
//3.收费月报表(总)
//统计某年某月的收费记录,按区域分组汇总
select (select name from T_AREA where id= areaid ) 区域,
sum(usenum)/1000 "用水量(吨)" ,sum(money) 金额
from T_ACCOUNT
where to_char(feedate,'yyyy-mm')='2012-05'
group by areaid
//4.收费月报表(收费员)
//统计某收费员某年某月的收费记录,按区域分组汇总
select (select name from T_AREA where id= areaid ) 区域,
sum(usenum)/1000 "用水量(吨)" ,sum(money) 金额
from T_ACCOUNT
where to_char(feedate,'yyyy-mm')='2012-05' and feeuser=2
group by areaid
//5.收费年报表(分区域统计)
//统计某年收费情况,按区域分组汇总
select (select name from T_AREA where id= areaid ) 区域,
sum(usenum)/1000 "用水量(吨)" ,sum(money) 金额
from T_ACCOUNT
where to_char(feedate,'yyyy')='2012'
group by areaid
//6.收费年报表(分月份统计)
//统计某年收费情况,按月份分组汇总
select to_char(feedate,'mm') 月份,sum(usenum)/1000 使用吨数,sum(money) 金额
from T_ACCOUNT
where to_char(feedate,'yyyy')='2013'
GROUP BY to_char(feedate,'mm')
ORDER BY to_char(feedate,'mm')
//7.收费年报表(分月份统计)
//统计某年收费情况,按月份分组汇总
select '用水量(吨)' 统计项,sum (case when to_char(feedate,'mm')='01' then usenum else 0 end )/1000 一月,sum (case when to_char(feedate,'mm')='02' then usenum else 0 end )/1000 二月,sum (case when to_char(feedate,'mm')='03' then usenum else 0 end )/1000 三月,sum (case when to_char(feedate,'mm')='04' then usenum else 0 end )/1000 四月,sum (case when to_char(feedate,'mm')='05' then usenum else 0 end )/1000 五月,sum (case when to_char(feedate,'mm')='06' then usenum else 0 end )/1000 六月,sum (case when to_char(feedate,'mm')='07' then usenum else 0 end )/1000 七月,sum (case when to_char(feedate,'mm')='08' then usenum else 0 end )/1000 八月,sum (case when to_char(feedate,'mm')='09' then usenum else 0 end )/1000 九月,sum (case when to_char(feedate,'mm')='10' then usenum else 0 end )/1000 十月,sum (case when to_char(feedate,'mm')='11' then usenum else 0 end )/1000 十一月,sum (case when to_char(feedate,'mm')='12' then usenum else 0 end )/1000 十二月
from T_ACCOUNT
where to_char(feedate,'yyyy')='2013'
UNION ALL
select '金额(元)' 统计项,sum (case when to_char(feedate,'mm')='01' then money else 0 end ) 一月,sum (case when to_char(feedate,'mm')='02' then money else 0 end ) 二月,sum (case when to_char(feedate,'mm')='03' then money else 0 end ) 三月,sum (case when to_char(feedate,'mm')='04' then money else 0 end ) 四月,sum (case when to_char(feedate,'mm')='05' then money else 0 end ) 五月,sum (case when to_char(feedate,'mm')='06' then money else 0 end ) 六月,sum (case when to_char(feedate,'mm')='07' then money else 0 end ) 七月,sum (case when to_char(feedate,'mm')='08' then money else 0 end ) 八月,sum (case when to_char(feedate,'mm')='09' then money else 0 end ) 九月,sum (case when to_char(feedate,'mm')='10' then money else 0 end ) 十月,sum (case when to_char(feedate,'mm')='11' then money else 0 end ) 十一月,sum (case when to_char(feedate,'mm')='12' then money else 0 end ) 十二月
from T_ACCOUNT
where to_char(feedate,'yyyy')='2013'
//8.统计用水量,收费金额(分类型统计)
//根据业主类型分别统计每种居民的用水量(整数,四舍五入)及收费金额 ,如果该类型在台账表中无数据也需要列出值为 0 的记录
//分析:这里所用到的知识点包括左外连接、sum()、分组 group by 、round() 和nvl()
select ow.name,
nvl( round(sum(usenum)/1000),0) "用水量(吨)" , nvl( sum(money),0) 金额
from T_OWNERTYPE ow ,T_ACCOUNT ac
where ow.id=ac.ownertype(+)
group by ow.name
//9.统计每个区域的业主户数,并列出合计
select ar.name 区域,count(ow.id) 业主户数
from T_AREA ar ,T_OWNERS ow,T_ADDRESS ad
where ad.id=ow.addressid and ad.areaid=ar.id
group by ar.name
union all
select '合计',count(1) from T_OWNERS
//10.统计每个区域的业主户数,如果该区域没有业主户数也要列出 0
select ar.name 区域,count(owad.id) 业主户数
from T_AREA ar ,
(
select ow.id,ow.name,ad.areaid from T_OWNERS ow,T_ADDRESS ad where ow.addressid=ad.id
)
owad
where ar.id=owad.areaid(+)
group by ar.name
11.解锁用户
alter user scott account unlock;//解锁用户scott 可用于测试的用户(自带的)
alter user scott identified by tiger//修改密码
//通过user的edit中勾选Account locked设定是否被锁定