• Oracle下SQL学习笔记


    主机字符串:as sysdba

    alter user scott account unlock;//解锁scott,不会就谷歌检索

    DML语句,增、删、查、改

    select语句:
    熟悉表结构 desc emp;

    number(4) 4位数字类型
    number(7,2) 7位数字,2位小数
    varchar2(10) 10位可变长度字符串
    date 日期类型

    select * from salgrade s;select s.* from salgrade s;

    select ename, sal * 12 as "Annual Salary" from emp;//有空格时使用双引号;双引
    号内容显示 保持原样;这里给列去别名,也只能有双引号,不能使用单引
    号‘AnnualSalary'

    select 3*4 from dual;//一行的表dual

    0不是空值null,任何含有空值的表达式的值都是空值

    coalesce(comm,0)

    字符串连接,连接列值: || 字符串用单引号;不能用双引号 || “abC”
    select ename||sal from emp;

    select ename || 'asdf' from emp;//结果中,单引号包含的字符串还是小写:
    JANESasdf

    去除重复值:
    select distinct deptno from dept;//修饰多个字段,去除重复的组合
    select distinct job,comm from emp;//结果中clerk ,null 只保留了一个


    where 过滤条件,and or not 连接多个条件
    select * from emp where empno=7782;//等值判断
    select * from emp where deptno <> 10;//不等于
    select ename from emp where eanme > "CBA"//字符串比较
    select ename, sal from emp where sal between 800 and 1000;//包含等于
    select ename, comm from emp where comm is not null;//是否是空值
    ename in('SMITH', 'TOM')
    sal not in (800,1500)
    日期处理:1.按照相关特定格式写 2.日期函数
    select ename, hiredate from emp where hiredate > '28-4月-1999';

    模糊查询,通配符 %零个或者多个,_ 一个字母,一个汉字占2个
    select ename from emp where ename like ‘%ALL%’;

    转义字符,默认的 指定转义字符 not like'%$%A%' escape '$';

    排序,可以按多个字段排序
    降序select deptno from dept order by deptno desc ;默认升序asc ascent 上升
    descent 下机
    select ename, sal from emp where sal > 1000 order by sal, ename desc;

    SQL函数;接收实参,字段名。
    对字符串操作: lower() upper() select lower(upper(ename)) from emp;
    substr(ename,2,3) 截子串 从第2个字符开始截,一共截3个

    chr(65) 结果是65对于的ascii码
    select ascii('A') from dual;

    round(23.65,-1) 四舍五入到十位,round 圆,大约
    select round(12.3347,2) from dual; 四舍五入小数点后2位

    对数字格式转换,用得较少
    select to_char(sal,'$99,999.9999') from emp;//指定格式转换数字,9代表一位数字
    to_char(sal,'L00000.0000)//L本地货币

    对日期(包含日期、时间)转换,把日期转换成字符串,用得很多
    select to_char(hiredate,'yyyy-mm-dd hh:mi:ss') from emp;
    select to_char(sysdate,'yyyy-mm-dd hh:mi:ss') from dual;//sysdate 当前时间
    select to_char(sysdate,'yyyy-mm-dd hh24-mi-ss') from dual;//yyyy mm dd等自由组
    合,24进制

    to_date() 把字符串转换成日期
    select ename, hiredate from emp
    where hiredate > to_date('1982-2-28 17:23:59', 'yyyy-mm-dd hh24:mi:ss');

    to_number()把字符串转换成相关数字
    to_number('$1,223.00', '$9,999.99);
    select sal from emp where sal > to_number('$1,888.22','$9,999.99')

    nvl(comm,0) 把空值转换成数值 coalesce(comm,0)
    单行函数,有多少条记录就有多少条输出

    重点:组函数,多行函数:多条记录座位输入,只产生一个输出
    max(sal)只有一个最大值,但是可能对于多条记录
    min(sal) avg(sal) sum(sal) count(*)求表中记录数

    select count(*) from emp where deptno=10;

    count某一个字段,如果不是空值,就算一个
    select count(comm) from emp;
    select count(distinct deptno) from emp;

    每个部门的平均薪水 group by 分组函数;
    出现在select列表中的字段,没有出现在组函数里,就必须出现在group by 里,才能产
    生唯一值,匹配起来。

    select deptno, avg(sal) from emp group by deptno;
    按照两个字段分组,就是安装两个字段的组合来分组
    select deptno,job,max(sal) from emp group by deptno,job;

    薪水最高的人的名字(子查询)
    select ename, sal from emp
    where sal = (select max(sal) from emp);


    where对单条记录进行过滤,不能对分组group by的现在,先执行where再分组
    select avg(sal),deptno from emp
    where sal >1500
    group by deptno;

    having,对分组进行限制
    select avg(sal),deptno from emp group by deptno
    having avg(sal) >2000

    先取数据select 再 where限制 再分组group by 再having限制分组 再order by 排序

    薪水大于1200的雇员,按部门分组,分组平均薪水大于1500,查询分组的平均工资,按工
    资倒序排列
    select avg(sal),deptno from emp
    where sal >1200
    group by deptno
    having avg(sal) >1500
    order by avg(sal) desc

    子查询
    求工资比平均工资高的人
    select ename,sal from emp
    where sal > (select avg(sal) from emp);

    每个部门挣钱最多的名字,部门名称?(作连接的表有相同的属性名,需要.指明表)
    select ename,emp.deptno,sal from
    emp join(select max(sal) max_sal,deptno from emp group by deptno) t
    on(emp.deptno=t.deptno and emp.sal=t.max_sal);

    每个部门平均薪水等级?? select ... from (.. join .. on..)
    (取别名是给某个子查询形成的表取名,两张表要连接,要包含连接条件中出现的属性列
    ,故意select * from salgrade,为了突出这样才包含on条件中的losal和hisal属性)
    select t1.avg_sal,t1.deptno,t2.grade from
    ((select avg(sal) avg_sal, deptno from emp group by deptno) t1
    join(select * from salgrade) t2
    on(t1.avg_sal between t2.losal and t2.hisal));

    select avg_sal, grade from
    (select avg(sal) avg_sal,deptno from emp group by deptno)
    t join salgrade
    on(t.avg_sal between losal and hisal);

    自连接,取别名,当成两张表(连接后存在重复列)
    select t1.empno, t1.ename, t1.mgr, t2.ename mgr_name from emp t1, emp t2
    where t1.mgr=t2.empno;

    交叉连接 cross join
    select ename,dname from emp cross join dept;//
    这样连接不行:select ename,dname from emp join dept;要么指明连接条件,要cross
    join
    select ename, dname from emp, dept//笛卡尔乘积(行的所有可能组合)
    where emp.deptno=dept.deptno;

    where中不出现连接条件,只写过滤条件。读起来更清楚,SQL1999标准
    select ename,dname from emp join dept on
    (emp.deptno=dept.deptno);
    select ename,dname from emp join dept using(deptno);//不推荐使用;假设两张表
    都有字段deptno,且类型一样。

    select ename,grade from emp join salgrade on(emp.sal between salgrade.losal
    and salgrade.hisal);

    三张表连接
    select ename,dname,grade
    from emp e join dept d on(e.deptno=d.deptno)
    join salgrade s on(e.sal between s.losal and s.hisal)
    where ename >'CLERK';

    外连接:
    左外连接会把左边那张表的多余数据(不能产生连接数据)拿出来 left (outer) join
    右外连接 right (outer) join
    全外连接 full join//1992不支持

    部门平均薪水等级? //between 小的值 and 大的值
    select deptno,avg(grade) avg_grade from
    (select ename,deptno,sal,grade from
    emp e join salgrade s
    on(e.sal between s.losal and s.hisal)
    ) group by deptno;//

    雇员中有哪些人是经理人?
    select distinct t2.ename mgr_name from
    ((select mgr from emp)t1 join
    (select ename,mgr,empno from emp)t2
    on (t1.mgr=t2.empno));

    select distinct ename mgr_name from emp
    where empno in(select mgr from emp);//编号出现在mgr中就是经理人

    不用组函数,求薪水最高值?(全部两两比较,笛卡尔乘积…,自连接)
    select sal from emp
    where sal not in(select t1.sal from (emp t1 join emp t2 on(t1.sal<t2.sal)));

    平均薪水最高的部门的编号?(平均薪水部门编号->平均薪水最大值->部门编号)
    select t.deptno ,t.avg_sal max_avg_sal from
    (select avg(sal) avg_sal,deptno from emp group by deptno) t
    where avg_sal=
    (select max(avg_sal) from
    (select avg(sal) avg_sal,deptno from emp group by deptno));

    平均薪水最高的部门的名称?
    select dname from dept
    where deptno =( );

    求平均薪水的等级最低的部门的部门名称
    select deptno from
    (
    select t.avg_sal,s.grade,t.deptno from
    ((select avg(sal) avg_sal,deptno from emp group by deptno) t
    join
    salgrade s
    on(avg_sal between s.losal and s.hisal))
    )where avg_sal =
    (select min(grade)
    from
    (select t.avg_sal,s.grade,t.deptno from
    ((select avg(sal) avg_sal,deptno from emp group by deptno) t
    join
    salgrade s
    on(avg_sal between s.losal and s.hisal))));

    第一步: 平均薪水,等级,部门编号
    select avg_sal,grade,deptno from
    ((select avg(sal) avg_sal,deptno from emp group by deptno)
    join
    salgrade s
    on(avg_sal between s.losal and s.hisal))
    在这个表的基础上求最低薪水等级,最低等级对应的部门编号,部门编号对应的部门名称
    (select套select)
    select dname,deptno from dept
    where deptno=(select deptno from
    (select avg_sal,grade,deptno from
    ((select avg(sal) avg_sal,deptno from emp group by deptno)
    join
    salgrade s
    on(avg_sal between s.losal and s.hisal)))
    where grade=
    ( select min(grade) from
    (select avg_sal,grade,deptno from
    ((select avg(sal) avg_sal,deptno from emp group by deptno)
    join
    salgrade s
    on(avg_sal between s.losal and s.hisal)))));

    组函数可以嵌套,最多可以嵌套两层,因为嵌套两层后输出必然为单行
    select max(avg(sal)) from emp group by deptno;

    创建视图(视图是虚表,实际数据还在原表中)create view as
    create view v_dept_avg_sal_info as
    select deptno,grade,avg_sal from
    (select avg(sal) avg_sal, deptno from emp group by deptno) t
    join salgrade s on(t.avg_sal between s.losal and s.hisal);

    授权grant
    登陆 conn sys/zwj as sysdba;
    grant create table,create view to scott;
    conn scott/zwj;

    部门经理中平均薪水最低的部门的名称?
    select dname from dept
    where deptno =
    (
    select deptno from
    (
    select deptno, avg(sal) avg_sal from emp
    where job='MANAGER'
    group by deptno
    )
    where avg_sal =
    (
    select min(avg(sal)) min_avg_sal from emp
    where job='MANAGER'
    group by deptno
    )
    );

    比普通员工最高薪水还要高的经理人名称?
    select ename as "Sal_big_than_Staff" from emp where
    empno in(select mgr from emp where mgr is not null)
    and sal >
    (
    select max(sal) max_staff_sal from emp
    where empno not in(select mgr from emp where mgr is not null));//mgr中有空值,
    如果不除去,结果不对

    求薪水最高的前5名雇员?(rownum <=5 限制返回行数,但是不能直接select where
    order by ,这样就直接只取了表的前五行,然后按sal排序)
    select * from
    (
    select ename,sal from emp
    order by sal desc
    )
    where rownum <=5;

    求薪水最高的第6到第10名雇员?(求差集函数minus,子查询not in)
    select * from
    (
    select * from
    (
    select ename,sal from emp
    order by sal desc
    )
    where rownum <=10
    minus
    select * from
    (
    select ename,sal from emp
    order by sal desc
    )
    where rownum <=5
    )order by sal desc;

    执行效率。理论上……;实际执行,数据库可能做优化

    表空间
    创建一个新用户,建立新的表空间,再导入表
    create user test identified by test default tablespace users quota 10M on
    users;
    授权
    grant create session, create table, create view to test;
    1.备份scott
    exp, 登陆, 导出文件(按默认,各种回车……)
    imp
    test/test //登陆该新创建用户
    输入用户名scott,导入的是scott下面的东西,导出文件中有可能包含多个用户导出的东
    西,只需要导入scott导出的东西

    rollback//回滚
    create table emp2 as select * from emp;

    insert
    1.按属性列默认顺序,插入全部属性的值
    insert into dept2 values(50,'game','Chang Sha');
    2.指明字段,没指明的属性默认空值
    insert into dept2(loc,deptno) values('Bei Jing',60);
    3.插入子查询,要求:子查询的结果和被插入表的结构一样
    insert into dept2
    (select * from dept2);

    Oracle伪字段rownum(首先把rownum加到表字段上),只能< 或 <=,不能和大于一起

    select rownum,ename from emp;

    select ename from(select rownum ,ename from emp) where rownum >10;

    select rownum, ename, sal from emp
    order by sal desc;//观察rownum,rownum先加到字段上,再排序

    在排好序的表基础上,rownum
    select rownum, ename,sal from
    (select ename,sal order by sal desc)
    where rownum <=10

    第26集
    创建表,定义表级约束,...foreign key references (sno)
    create table sc(sno number(2) ,cno number(1), scgrade number(2),
    foreign key (sno) references s(sno),foreign key (cno) references c(cno),
    primary key(sno,cno));

    没选过“黎明”老师的所有学生姓名?
    select sname from s
    where sno not in( select sno from sc where cno in
    (select cno from c where c.cteacher = '黎明'));

    下面这样逻辑不对,虽然3个表连接起来,但是有学生某门课程选的老师不是黎明,而
    他又选了黎明教的那门课:Lily Math 黎明 59;Lily Compu Smith 56 这样第二条记录
    中老师不是黎明,把Lily给选了出来
    select s.sname,c.cname,c.cteacher, sc.scgrade from s
    join sc on(s.sno = sc.sno) join c
    on (sc.cno=c.cno) where
    c.cteacher <> '黎明';

    两门以上不及格学生姓名
    select sname from
    s join
    (
    select sc.sno,count(*) fail_class_num from sc
    where scgrade <60
    group by sc.sno
    having count(*) >1 //此处可以having这个
    )t on s.sno = t.sno;

    既选修了1号又选修了2号课程的所有学生姓名(交集,、、、in、、、,差集minus,
    not in并集 union/union all包括重复的项目)
    select sname from s
    where s.sno in
    (select sc.sno from sc where cno = 1 and sno in(select sno from sc where cno =
    1));

    update emp2 set sal=sal*2, ename=ename||'-' where deptno = 10;

    delect from dept2 //全部删了
    where deptno = 20;

    DDL数据定义语句,建表(create table),建视图(create view),删除表(drop
    table)。DCL:grant

    事务-transaction,要么全完成,要么不完成(账户转账)。
    一个transaction起始于一条dml语句,正常终止于commit(提交)、遇到DDL语句
    (create)、DCL语句(grant...to)、正常断开(敲exit)自动提交,一敲rollback所
    有修改回退了,如果commit提交完成,上面的transaction已经完成,再rollback无效。
    不能回退了。
    非正常断开(断电、直接关闭窗口……),自动回滚。

    数据库常用对象(表、视图)

    create table(字段名 数据类型,……)
    char(8):定长字符串,固定占8位(效率更高,定位快,类似数组;浪费空间,拿空间
    换时间)
    number(8,3):整个数字一共8位,3位小数
    date:日期,年月日时分秒
    long变长字符串,2G ,存图片,数据库存文件名(数据在硬盘上),一篇文章
    varchar2:变长字符串,最多4K,4096字节 1Byte 8bit;
    varchar2(20)可存十个字符


    五个约束条件:非空,唯一,主键,外键,check;约束可以取名字;字段级约束,表级
    约束。check约束用得少,一般在java这边效验过了。

    取值唯一可以插入空值,空值不认为是重复的。

    约束:constraint 约束名 约束类型 加约束的字段
    create table stu(
    id number(6),
    name varchar2(20) constraint stu_name_nn not null,
    sex number(1),
    age number(3),
    sdate date,
    grade number(3) default 1,
    class number(4) references class(class_id),
    email varchar2(50),
    constraint stu_name_email_uni unique(email,name)
    );

    insert into stu values(123456,'Tom',1,22,to_date
    ('19900101','yyyymmdd'),2,4212,'abc@126.com');

    主键primary key:not null,唯一标识一个记录 。建在数字上,速度快

    外键:涉及到两个字段,被参考字段必须是主属性,参考字段

    create talbe class
    (
    class_id number(4) primary key,
    name varchare2(20)
    );

    被参考,不能删除。


    select distinct t1.name from(
    (select name,sum(pcount) red_sum_count from product
    where color='红色' and pcount is not null group by name) t1
    join
    (select name,sum(pcount) blue_sum_count from product
    where color='蓝色' and pcount is not null
    group by name) t2
    on(t1.name=t2.name and t1.red_sum_count > t2.blue_sum_count ));

    取了别名之后,不能用t1.name,只能t1.产品
    select t1.产品, t1.红色, t2.蓝色 from(
    (select name 产品,sum(pcount) 红色 from product
    where color='红色'
    group by name)t1
    join
    (select name 产品,sum(pcount) 蓝色 from product
    where color='蓝色'
    group by name) t2 on(t1.产品=t2.产品))


    换一种写法:
    select t1.name 产品, t1.红色, t2.蓝色 from(
    (select name ,sum(pcount) 红色 from product
    where color='红色'
    group by name)t1
    join
    (select name 产品,sum(pcount) 蓝色 from product
    where color='蓝色'
    group by name) t2 on(t1.name=t2.产品));

    alter 修改表结构(或者删了重新建一遍,插入数据一般会保存这些sql语句,删除测
    试时插入的几条数据没关系)
    add方式添加新列和完整性约束
    drop方式,删除指定完整性约束添加或删除指定的列
    change方式,修改某些列 alter table stu change id to s_id varchar2(12);
    modify方式,修改某些列的数据类型

    alter table t_name drop (name);//删除属性
    desc stu;

    alter table stu add(add varchar2(20));//添加属性

    alter table stu modify(addr varchar2(15));//修改后要能容纳原来数据才能修改成功

    alter table stu drop constraint stu_class_fk;//删除约束

    alter table stu add constraint stu_class_fk foreign key(class) references
    class(id);添加约束

    alter table stu add unique(id);

    删除表drop table stu;

    忘了约束的名字怎么办?

    user_tables 数据字典表
    select view_name from user_tables;
    talbe_name
    constraint_name from user_constraints;
    index_name from user_indexs;
    数据字典表的表,dictionary(字典)
    desc dictionary;

    索引 create index ……on …… drop index …… 不要轻易创建索引
    create index idx_stu_email on stu(email)//多个字段,为多个字段的组合创建索引
    ,查找时的效率更高,读的效率高,插入删除效率低了(要把索引插入索引表,索引要占
    用大量空间)
    drop index idx_name;

    视图(视图就是一个子查询),表结构改了,视图也要维护代价;视图可以简化查询,
    (视图,外模式,用户角度)提供安全;数据还在原表中;视图是可以更新数据的,实际
    上是跟新原表的数据,不过很少这么用,比如视图来自多个表,容易出错。
    create view v$_student
    as
    select……

    Oracle独特的东西:序列sequence(SqlServer里面:identity),不间断的,一般是
    用来作主键。一般一个sequence对应一个表,这么用,虽然一个sequence也可以用在其他
    表。

    并发,多个线程插入第101个帖子时
    create sequence seq_article1;//第一次执行为1,第二次执行为2……;取名要见名知意

    select seq.nextval from dual;//(内部做了线程同步)

    insert into article values(seq.nextval,……);

    表,依附在表上的约束,视图(用途很多,但是有维护代价,不轻易建),索引(牢牢
    记住,面试题,建立索引),序列sequence(Oracle特有,mysql:autoincrement,自动
    递增)……

    数据库设计三范式(很有用,但是该打破的时候要打破;范式主要目标消除冗余数据)
    第一范式:要有主键;列不可分(不含有表中表)。
    部分依赖:非主属性,依赖部分主键(拆分表,查询时需要作连接)
    传递依赖:

    弄清需求:
    板块、帖子、回复、用户

  • 相关阅读:
    将数据保存在线程中
    OpenSmtp 的代码修正,支持中文和HTTP代理连接
    枚举.NET的基本类型
    通过HTTP代理连接到目的的协议
    程序出现了异常:应用程序无法启动,因为应用程序的并行配置不正确
    关于最近的一篇文章
    检测TextBox的回车键事件
    程序跳过trycatch地崩溃
    给程序加上UAC控制的几个链接
    Sql Server附加数据库的时候出现Operating system error 5: "5(Access is denied.)" 的错误
  • 原文地址:https://www.cnblogs.com/yongwangzhiqian/p/3598739.html
Copyright © 2020-2023  润新知