Oracle学习《一》
1. oracle数据分组进行取值
select * from (select a.*,rownum r from cc_quiz_round a ) s where s.r>5 and s.r<10
initcap 首字符大写
select initcap('tarena') from dual;
concat 连接字符串
select concat(first_name , last_name) from s_emp;等效于||
substr 求子串
select substr('this is a good day',2,3) from dual;--从第二位开始往后取三位,而不是从第二位取到第三位
select substr('tarenasd0603',-2) from dual; (取后两个字符)
SELECT ROUND(45.73) FROM DUAL;--四舍五入 只精确一位
SELECT TRUNC(89.88) FROM DUAL;--舍位
add('现在时间','value') value 系数是月数
SELECT ADD_MONTHS(SYSDATE,5) FROM DUAL;--在现在的基础上加5 months
SELECT ADD_MONTHS(SYSDATE,5*12) FROM DUAL;--在系统的时间上晚5年 这里的晚是指现在是10年,结果是15年
SELECT ADD_MONTHS(SYSDATE,-5*12) FROM DUAL;--系统的时间早5年 这里的早是指现在是10年,结果是05年
SELECT LAST_DAY(SYSDATE) FROM DUAL;--获取系统最后一天alter session set nls_language='AMERICAN';
SELECT NEXT_DAY(SYSDATE,'Friday') FROM DUAL;--"ORA-01846: 周中的日无效"SELECT ROUND(SYSDATE,'minute') FROM DUAL;
不是四舍五入,过了半旧留下,不过的省略 关键字包括 year month day SELECT TRUNC(SYSDATE,'DAY') FROM DUAL;
--例子:
本月月初的日期:
select last_day(add_months(sysdate, -1)) from dual;
本月的最后一秒:
select trunc(add_months(sysdate,1),'month') - 1/24/60/60 from dual
本周星期一的日期:
select trunc(sysdate,'day')+1 from dual
年初至今的天数:
select ceil(sysdate - trunc(sysdate, 'year')) from dual;
查看当前用户
select user from dual
取余数
select mod(ID,3) from cc_quiz_round
<1>.SYSDATE:返回系统日期
<2>.MONTHS_BETWEEN:返回两个日期间隔的月数
select months_between('02-2月-06','02-2月-06') from dual;
<3>.ADD_MONTHS:在指定日期基础上加上相应的月数
select add_months('02-2月-06',8) from dual;
<4>.NEXT_DAY:返回某一日期的下一个指定日期
select next_day('1-2月-12','星期一') next_day from dual;
<5>.LAST_DAY:返回指定日期当月最后一天的日期
select last_day('1-2月-12') last_day from dual;
<1>NVL(表达式1,表达式2)函数:该函数功能是空值转换,把空值转换为其他值,解决空值问题。如果表达式1为空,则表达式2就是要转换成的值。
注意:数据格式可以是日期、字符、数字,但数据类型必须匹配
select nvl(null,1) from dual;
select nvl(2,1) from dual;
www.2cto.com
<2>.NVL2(表达式1, 表达式2, 表达式3)函数:该函数是对第一个参数进行检查。如果第一个参数不为空,则输出第二个参数,如果第一个参数为空,则输出低三个参数,表达式1可以为任何数据类型。
select nvl2(null,1,2) from dual;
select nvl2(3,1,2) from dual;
<3>.NULLIF(表达式1,表达式2)函数:该函数主要完成两个参数的比较。当两个参数不相等时,返回值是第一个参数值;当两个参数相等时,返回值是空值。
select nullif(1,1) from dual;
<4>.COALESCE(表达式1, 表达式2, ... 表达式n)函数:该函数是对NVL函数的扩展。COALESCE函数功能是返回第一个不为空的参数,参数个数不受限制。
select coalesce(null,null,0,1) from dual;
<5>.CASE表达式:
SELECT last_name, commission_pct,
(CASE commission_pct
WHEN 0.1 THEN '低'
WHEN 0.2 THEN '中'
WHEN 0.3 THEN '高'
ELSE '无' www.2cto.com
END) Commission
FROM employees
WHERE commission_pct IS NOT NULL
ORDER BY last_name;
<6>.DECODE函数:
DECODE(字段|表达式, 条件1,结果1[,条件2,结果2…,][,缺省值])
select id,STATUS, decode(STATUS,0,'关闭',1,'开启') from cc_cw_config
复制表:create table emp_copy
As select * from emp;
但如果想复制表结构,不想复制数据:
Create table emp_copy
As select * from emp
Where 1=2;
, 情景查询
(1) decode()函数
decode(value_expression,search_value,result_value,default_value)
参数含义:
value_expression;表示将要与搜索值比较的值或表达式
search_value;表示将要搜索的值
result_value:表示search_value参数与value相等时value_expression参数的取值结果
default_value;表示search_value参数与value不相等时value_expression参数的取值结果
www.2cto.com
例句:select name ,sal,decode(deptno,’10’,’会计部’,’20’,’研发部’,’30’,’销售部’,’其他部门’) from emp
(2) case表达式
语法格式如下:
Case search_expression
When expression_1 then display_result_1
When expression_2 then display_result_2
……
When expression_n then display_result_n
Else default_display_result
End
参数意义如下:
search_expression:表示用于检索的表达式,一般情况下是表中的列名称
expression_1,……,expression_n:表示用于比较的表达式
display_result_1,……..,display_result_n:表示用于比较的表达式与search_expression参数匹配时应该显示的结果。
例句:select ename,sal,
Case deptno
When 10 then ‘会计部’
When 20 then ‘研发部’
Else ‘其他部门’
End
From emp;
与简单的case表达式相比,搜索表达式的每一个条件都可以不同,因此更加具有灵活性,搜索case表达式的语法格式如下:
Case www.2cto.com
When expression_1 then display_result_1
When expression_2 then display_result_2
……
When expression_n then display_result_n
Else default_display_result
End
例句:select ename.case
When hiredate<’1-7月-01’ then ‘老员工’
When hiredate>’1-7月-01’ and hiredate<=’1-7月-02’ then ‘普通员工’
When hiredate>’1-7月-02’ then ‘新员工’
End from emp;
触发器创建
create or replace trigger zhang_trg
before insert or update
on zhang_zh
referencing NEW as NEW OLD as OLD
for each row
declare
last_seq number;
last_insertVal number;
begin
---判断是否已经存在插入的值
if(:New."ID" is null)
then
select "ZH_SEQ".nextval into :new."ID" from dual;
else
---去序列中下一个值
select last_number -1
into last_seq
from user_sequences
where upper(sequence_name)=upper('ZH_SEQ');
去数据表中新增加的值
select :new."ID"
into last_insertVal
from dual;
---判断如果新加的值大于序列的值,继续去下一个值进行赋值
while(last_insertVal>last_seq)
loop
select "ZH_SEQ".nextval into last_seq
from dual;
end loop;
end if;
end ;
注 order by 后面若是中文,排序的标准时拼音
简单的说row_number()从1开始,为每一条分组记录返回一个数字,这里的ROW_NUMBER() OVER (ORDER BY xlh DESC) 是先把xlh列降序,再为降序以后的没条xlh记录返回一个序号。
示例:
xlh row_num
1700 1
1500 2
1085 3
710 4
row_number() OVER (PARTITION BY COL1 ORDER BY COL2) 表示根据COL1分组,在分组内部根据 COL2排序,而此函数计算的值就表示每组内部排序后的顺序编号(组内连续的唯一的)
---rank()over(order by 列名排序)的结果是不连续的,如果有4个人,其中有3个是并列第1名,那么最后的排序结果结果如:1 1 1 4
---dense_rank()over(order by 列名 排序)的结果是连续的,如果有4个人,其中有3个是并列第1名,那么最后的排序结果如:1 1 1 2
:分区与分组有什么区别?
?分区只是将原始数据进行名次排列(记录数不变),
?分组是对原始数据进行聚合统计(记录数变少,每组返回一条)。
注意:使用rank()over(order by 排序字段 顺序)排序的时候,空值是最大的
如果排序字段为null,可能造成在排序时将null字段排在最前面,影响排序的正确性。
所以建议将dense_rank()over(order by 列名 排序)改为dense_rank()over(order by 列名排序 nulls last)
这样只要排序字段为null,就会放在最后,而不会影响排序结果
三、group by后带rollup子句与group by后带cube子句区别
group by后带rollup子句与group by后带cube子句的唯一区别就是:
带cube子句的group by会产生更多的分组统计数据。
cube后的列有多少种组合(注意组合是与顺序无关的)就会有多少种分组。
select table_name,column_name,data_type,nullable,rank() over (partition by table_name order by data_type) from user_tab_columns
where table_name not like 'BIN$%'
select * from user_tab_columns
函数形式定义
create or replace function functionName(
---在此处也可以使用out 进行结果返回
arg in number, arg2 in varchar2,arg3 out number
)
---return 后面加要返回的结果类型
return varchar2 is
---各种参数,包括要返回的参数
resuleArg varchar2;
begin
resuleArg:='这个是返回的参数';
---最后记得用return 返回,记得类型要匹配
return (resuleArg);
end;