暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

MySQL入门第三课:SQL基础

MySQL笔记 2021-04-18
382

1.基本语法结构  SELECT *|{[DISTINCT] column|expression [alias],...} ;  -->确定处理的行


  1.  FROM table;        -->处理哪个表格


    -->大写字母是指令,不可以省略,|表示选项互斥,[]表示可选选项,可以不写,不在[]内的小写字母需要用实际操作的内容代替


    -->*表示全部列


    -->空值不是零或空格,是指当前未知或暂不可用的值,用null代替,任何数与null运算均得到null


  1.别名


    1.作用是重命名列标题,便于计算和管理。


    2.紧跟在列明后面,在列名与别名之间有可选的关键词as


    若包含特殊符号或空格或要区分大小写,则需要加双引号以字符的形式写入,


  2.链接运算符  ||


    1.用于合成列,可以合成多个列,可以在合成时加入其他列


    eg  job_id ||'.'||name AS "Employees"\


  3.distinct  -->消除重复行


    select distinct department_id ,job_id


    from employees


  2.检索  


  1.使用where语句限制返回的行,where跟在from语句后面


  2.日期的默认格式DD-MON-RR,字符串和日期必须含在''内,数字通常不包含在引号中


  3.所有的字符搜索都是区分大小写的,where子句中不能使用别名


  4.范围限定


    1.between and  介于两个值之间的数,包含这两个值


    eg  select last_name ,salary 


    from employees


    where salary between 2500 and 5000;


      -->前面的数必须比后面的小


    2.in  与值列表中的任一值匹配


    eg  select employee_id, last_name ,salary ,maneger_id


      from employees


      where manager_id in (100,101,102)


      where last_name in ('hartstein','vargas');   


    3.like  与某个字符模式匹配


    1.若要匹配的内容中有_,需要将_用\取消其通配符的作用,然后写escape '\'


    eg  select last_name ,hire_date


      from employees


      where hire_date like '%\_95' escape '\';


    4.is null  空值


      select manager_id


      from employees


      where manager _id is null


  5.运算符


    1.AND  两部分均为真才会返回true


    2.or  或


    3.not  若下面的条件为假则返回真


    4.可以通过加括号来改变默认的运算顺序


  6.排序  order by 后面加排序的列,若有多个,就按照排序的先后顺序写即可


    order by语句在select语句的最后


    ASC  升序


    DESC  降序


  3.单行函数


  1.字符函数


    1.lower  -->将字符串转换为小写


    2.upper  -->转换为大写


    3.initcap  -->将每个单词的第一个字母转换为大写,其余字母小写,故空格后的第一个字母会改为大写


    eg  SELECT 'The job id for '||UPPER(last_name)||' is '||LOWER(job_id) AS "EMPLOYEE DETAILS"


      FROM employees;


    eg  SELECT employee_id, last_name, department_id


      FROM employees


      WHERE LOWER(last_name) = 'higgins';  -->因为录入时未规范大小写,故在匹配时全转化为小写


    4.concat  -->将值联系到一起,尽可以使用两个参数,故要连接多个需要多层嵌套,不如||好用


    eg  concat ('hello', 'world')  


    5.substr  -->抽取确定长度的字符串


    eg  substr('helloword',1,5)


      -->括号内第一个数字是截取开始位置,第二个是截取长度,开始位如果是负数,则为倒数第几位,


    6.length  -->以数值的形式展示字符串的长度


    eg  length('helloworld')


    7.instr  -->查找制定自的的数字的的位置


    eg  instr ('helloworld' 'w')


    8.lpad  -->按右对齐补齐字符值


    eg  lpad (salary 10 '*')


    9.rpad  -->按左对齐补齐字符值


    eg  rpad (salary 10 '*')


    10.trim  -->从字符串中截去头部或尾部的字节


    -->因为在用trim截取时要输入截取的方向,故更常使用rtrim和ltrim


  2.数字函数


    1.round  -->四舍五入,保留n位小数,若未写n则不保留整数,若n为负数,则为小数点左边的位数


    2.trunc    -->去尾法保留n位小数


    3.mod  -->取余,mod(m,n)  -->返回值为m除以n之后的余数


    -->dual表示为了满足from语句而存在的特殊的表,目的是便于操作


  3.日期函数


    1.操作的单位是天,加减都是以天为单位,小时除以24即可实现添加到日期中,可以通过简单的加减实现日期的变化


    2.months_between(date1,date2)  -->两个日期之间的月数


    3.add_months(date, n)  -->将日历月份添加到日期中


    eg  select employee_id, hire_date,


      months_between (sysdate ,hire_date) yenure,


      add_months(hire_date ,6) revien,


      next_day(hire_date,'friday'),lastday(hire_date)


    from employees


    where months_between (sysdate ,hire_date) <36  


  4.若 SYSDATE = '25-JUL-95'


     ROUND(SYSDATE,'MONTH')  --> 01-AUG-95


     ROUND(SYSDATE ,'YEAR')  --> 01-JAN-96


     TRUNC(SYSDATE ,'MONTH')  --> 01-JUL-95


     TRUNC(SYSDATE ,'YEAR')   --> 01-JAN-95


  5.显示数据类型转换


    1.to_number (char , [格式])    -->将包含数字的字符串一可选的格式转化为数字


    2.to_date (char [格式])    -->将代表日期的字符串按照指定格式转化为日期值,如果省略了格式,默认为DD-MON-YY  


    3.to_char (number | date ,[ 格式 ])  -->按指定格式转化字符


  6.NVL函数


    1.NVL  将空值转化为实际值,可以使用的类型为日期,字符和数字


    NVL(commission_pct,0)


    NVL(hire_date,'01-JAN-97')


    NVL(job_id,'No Job Yet')


    2.nvl2  -->NVL2(expr1, expr2, expr3)


      -->nvl2会检查第一个表达式,若不为空,则返回第二个表达式,若为空,则返回第三个表达式


    3.NULLIF   -->NULLIF (expr1, expr2)


      -->比较两个表达式,若他们相等,但会空值,若不相等,返回第一个值


    4.coalesce  -->COALESCE (expr1, expr2, ... exprn)


      -->依次检查是否为空,输出第一个不为空的表达式


  7.条件表达式


    1.  CASE expr   WHEN comparison_expr1 THEN return_expr1


      WHEN comparison_expr2 THEN return_expr2


      WHEN comparison_exprn THEN return_exprn


      ELSE else_expr


    END


  4.显示多个表的数据


  1.嵌套循环  


    1.等值连接  -->两表关联列的比较运算符是等号


        -->关联列必须来自于两个不同的表


    传统写法


    select e.ename ,e.sal ,d.deptno ,d.dname


    from scott.emp e ,scott.dept d


    where e.deptno=d.deptno


    -->较短的表为驱动表,较大的表为被驱动表,利用相同的列进行匹配,每次匹配都会扫描全部表


    -->两个表想要实现拼接查看,需要有一列内容相同,可以时间匹配连接


    -->mysql仅有一种链接方式  -->嵌套循环


    -->驱动表扫描一次,被驱动表扫描的次数等于驱动表的行数


    -->因为在循环时要重复扫描,严重影响了数据库运行速度,故mysql的扫描速度低于oracle


    标准写法


    1.自然连接  -->数据路自动扫描关联的表,将同名同类型的列自动连接


      select ename ,sal ,deptno ,dname


      from scott.emp natural join scott.dept


      -->不能制定关联列


      -->只支持等式链接


      -->两表必须存在同名列


    2.join using


      select ename ,sal ,deptno ,dname


      from scott.emp join scott.dept using(deptno)


      -->只支持等式链接


      -->两表必须存在同名列


    3.join on


      select ename ,sal ,deptno ,dname


      from scott.emp e join scott.dept d on deptno=deptno


      -->支持等式与非等式连接,故需要注明select的是哪个表中的列,可以指定关联列


    2.非等值连接    


    SELECT e.last_name, e.salary, j.grade_level


    FROM employees e, job_grades j


    WHERE e.salary  BETWEEN j.lowest_sal AND j.highest_sal;


  2.外连接  -->强制显示所有的列


    1.传统写法  -->将(+)写到想要显示全部数据的表中列的对面


      select a.name ,sal ,d.deptno ,d.dname


      from scott.emp e ,scott.dept d


      where e.deptno(+)=d.deptno


    2.标准写法  -->join关键字位于两表中间,使用left right制定显示那种表的全部数据


      select *


      from scott.dept d 


      left join scott.emp e on e.deptno=d.deptno


      -->全显示左边的列的数据


  3.全链接  


  4.笛卡尔积  -->多表关联,关联条件至少为表的个数-1


    -->若关联中出现笛卡尔积,则说明关联错误,可以通过F5查看错误


  5.自连接


  1.count  -->count (*) count (1)  -->统计的是行数


    -->count(列)  -->统计的是非空行数


      -->分组函数遇见null会跳过


  2.分组  -->在select子句中,如果有列没有被分组函数所包含,则这个列必须出现在group by子句中


    -->当需求是平均或者每。。。时,都要用到分组函数


    1.排序分组算法(很少见)  -->通常是升序排列


    select deptno ,job ,min(sal),max(sal),sum(sal),count(sal)


    from scott.emp


    group by deptno ,job


      -->计算select中的值,依照group by中的类别对其分组    


    2.哈希分组算法  


  3.  select deptno ,avg(sal)  


    from scott.emp


    where deptno=10


    group by deptno


    having avg(sal) > 2000


    order by deptno


  5.子查询  


    1.嵌套执行


    eg1  查看所有比Abel工资高的员工


    select last_name ,salary


    from employees


    where salary > (


    select salary


    from employees


    where last_name = 'Abel');


    eg2  查看所有包含员工的部门


    select departmend_id ,department_name


    from departments t


    where department_id in (Select department_id from employees);


    eg3  查看公司比部门id为10的任何人工资都高的员工


    select *


    from employees


    where salary > any (select salary from employees where departmens_id=10)


    eg4  select *


    from employees


    where salary > (select max (salary) from employees where departmens_id=10)


    eg5   查询不是管理者的员工-->没有出现在manager_中的员工


    select *


    from employees


    where employee_id not in (


    select manager_id


    from employees


    );


  相关子查询  -->在子查询中引用了相关主查询的列


    select *


    from employees zhu


    where zhu.salary > (select avg(salart)


        from employees zi


        where zhu.department_id=zi.department_id);


    -->用in函数写


    select department_id ,department_name


    from departments zhu


    where department_id in (select departmentI from employees);


    -->用exists


    select department_id ,department_name


    from departments zhu


    where exists (select 1 


      from employees zi


      where 


      department_id in (select departmentI from employees);


  7.替代变量


  1.需要在sqlplus中操作


    在linux中,sqlplus hr/hr即可进入软件


  8.数据操作


  1.insert into 表名 [列名] values (对应值)


    eg  create table insert_test (c1 number ,c2 number);


    insert into test_insert values(1,11);  


      -->如果不能提供所有列的值,则需要写列名,建议在写数据时写列表名,方便日后管理


  2.insert in insert_test(c2,c3)


    select employees_id ,department_id


    from employees


  3.更新列  update   table    -->表的名字


    set  column=value[,column=value,...]  -->column表中要填充的列名,value是该列相应的值或子查询


    [where   condition]    -->condition指要更新的行,他有列名表达式、常数、子查询和比较运算符组成


  eg  update test_insert


    set c2=c2+10000 ,c1=5555


    where c3 >50


  4.create table test_update


    as select * from employees  -->创建一张一模一样的表


  eg update test_update


    set sal=(select avg(sal) from test_update)


    where sal > (select avg(sal) from test_update)


    -->将工资高于平均的人的工资改为平均


2.数据库事务处理


  1.事务的四大特性  -->原子性  -->两个进程绑定进行,必须同时成功或同时失败


      -->一致性  -->


      -->持久性  -->事务提交后,事务就永久存在


      -->隔离性  -->事物的中间状态其他回话不可见,也不受其他会话影响


  2.一致读  


  当前读  


  3.创建表  create table dept 


    ( deptno number(2),  -->number为该列的数据类型,括号内为最大字符数


      dname  varchar2(14),


      loc  varchar2(13));


    table created


  -->select * from tab$  -->用于查看数据库中有哪些表 


3.约束


  1.not null   -->非空约束  


  eg  creste table test_not_null (c1 number .c2 number not null)


    -->作用是使某个表的某列不能存空值


  eg  -->也可以不再创建时设置非空,在后续操作时加


    creste table test_not_null1 (c1 number .c2 number)


    alter table test_not_null1 modify c2 not null;


    -->通过alter table 。。。modify。。设置


    -->对于已经含有空值的列,不能再设置非空,会报错


  2.unique  -->唯一约束  -->设置了唯一约束的同一列内不能有重复值


  eg1  create table test_unique (c1 number unique,c2 number )


  eg2  create table test_unique2 (c1 number ,c2 number ,CONSTRAINT aaa)  -->若不标注constraint的值,则系统随机分配,若标注了就设置成标准的名字


  3.primary key约束  -->非空约束+唯一约束(主键约束一个表只能有一个)


  eg1  create table test_pk (c1 number primary key ,c2 number);


  eg2  alter table test_pk add constraint pk2 primary key (c2) ;


      表名  约束     约束名   约束类型 作用于哪个列


  eg3  联合主键


    create table test_pk2 (c1 number ,


      c2 nimber ,


      c3 number ,


      constraint pk_multi primary key(c1 ,c2)


  4.foreign key  -->外键约束


    -->被引用的表被称为父表,引用的成为子表


  eg  create table emp as select * from scott.emp


    create table dept as select * from scott.dept


    alter table dept add constraint pk_dept_deptno primary key (deptno)    -->先在父表中创建主键


    alter table emp add constraint fk_emp_depttno foreign key (deptno) reference dept(deptno)  -->在子表中创建以dept为父表,指向deptno列的外键


    -->若父表中无要加入的值,则不能加入


    -->若子表中有父表中对应的值,则父表中对应的值不能删除


    删除模式  no action  -->重复不可删除


      cascade  -->父表和子表中相关值的行一起删掉  


  5.check  -->用于定义一个每行都必须满足的条件


  eg  alter table emp add constraintck_sal check (sal > 0)


4.视图


  1.视图是一个有名字的select语句


  2.作用


  -->保护数据


    create view for_sec ad select empno .ename ,deptno from emp


    创建一个新的表格只含有需要的提供的列,


    select * from for_sec


    相当于执行了一条查询语句(select empno .ename ,deptno from emp)


  -->简化代码


  eg  create view v_avg_sal as 


    select deptno ,avg(sal) a_sal


     from emp


    group by deptno;    -->创建过程


    select * from v_avg_sal where deptno='10';  -->使用创建的视图


  3.创建视图


  create [or replace ] [force |enforce ]  view (alias ) as  condition


  -->默认是enforce,通常会省略 ,force的作用是:如果后面的表不存在,使用enforce不可以执行,如果用force可以先创建,后面在创建表格


  -->view后接要创建的视图的名字,as后接具体的操作,通常为一个select ..from...加筛选的语句


  4.可以在视图上进行DML操作


  若在最后加with read 则不能进行dml操作,只能读  


  eg1.  创建一个视图给deptno10的头,仅可以查看10的内容,但可以操作数据


    create view dept10 as select * from emp where deptno=10;


  with check option  -->在视图中操作后的数据,仍然存在视图中,


    creste view dept10 as 


    select * from emp where deptno=10 with check option;


  -->不可以修改


  5.删除视图  drop view alias


  6.内联视图  -->where子句中的嵌套查询为子查询,from子句中潜逃的查询为内联视图


  eg  -->查询部门名称、部门薪水


    select dname ,a_sal


     from (select deptno ,avg(sal) a_sal


    from emp 


    group by deptno) a_sal dept


     where a_sal.deptno=dept.deptno


  eg  select * 


    from emp zhu


    where zhu.sal > (select avg(sal) from emp zi where zhu.deptno=zi.deptno)


   eg  select *


    from emp e, 


    (select deptno , avg(sal) a_sal


    from emp 


    group by deptno) nlst


     where e.deptno =nlst.deptno


     and e.sal>a_sal


  7.伪列  -->表中不存在但是可以查询


  eg  -->对于因为执行优先级造成的执行先后的问题,可以用内联视图解决


    select rownum ,xx.*


    from (


    select e.*


    from emp e


    order by sal) xx


    where rownum <=3


  eg  select *


    from 


    (select rownum rn ,xx.*


    from


    (select e.*


    from employees e


    order by employees_id) xx


    )


    where rn between 4 and 6


  8.生成序列


  create sequence swq3 incremen by 3 start with 8


    -->创建序列,从8开始,每次增加3


  select seq3.nextval from dual;  


    -->可以用于查看


  create sequence swq3 incremen by 3 start with 8 maxvalue 20


    -->创建序列,序列最大值是20,若增加到超过20,则报错


  create sequence swq3 incremen by 3 start with 8 maxvalue 20 cycle


    -->循环,若增加到超过20则从1开始重新循环


  create sequence swq3 incremen by 3 start with 8 minvalue 3 maxvalue 20 cycle


    -->最小值为3的循环,若增加到超过20则从3开始重新循环


  9.索引


  1.创建索引  


    create index idxl on dept(dname);  -->单列索引


    create index idx2 on dept(dname,loc);  -->多列索引


    create index idx3 on dept(substr (dname,3));  -->函数索引


  2.删除


    drop index idx3  


  3.查看  


    select * from user_indexes ;


  10.同义词  -->一个有名字的别名


    create synonym e for employees


    drop synonym e


  公共同义词  -->不需要授权,大家都可以用


    create public synonym e for scott.emp


5.用户


  1.创建  create user 用户名 indentified by 密码


    eg  create user u1 identified by u11  


  查看所有用户  


    select * from dba_users;


  2.修改密码  alter user u1 identified by u11


  3.赋予权限  


    1.系统权限  -->能创建其他用户、创建任何表、删除除系统表外的任意表等


    GRANT create session, create table,


      create sequence, create view  -->创建会话、表、序列、视图的权限


    TO  scott;    -->将上面的四个权限授予scott


    2.对象权限  -->会根据对象的不同而变化


      -->对象的所有者对器具有全部权限,所有者可以将属于他的对象的权限授予其他用户


      eg  GRANT  object_priv [(columns)]  -->object_priv 要授予的对象权限  columns  制定授予权限的表或视图中的列  all 制定所有的对象权限


      ON     object      -->ON object   授予权限的对象,可以为表等具体内容


      TO     {user|role|PUBLIC}    -->to 授予给谁  user 用户 role 角色 public 所有用户


      [WITH GRANT OPTION] ;    -->允许被授予者将对象权限授予其他用户和角色,不加则不允许


    -->select * from ROLE_SYS_PRIVS    -->查看授予角色的系统权限,可以通过where查看制定角色


    3.撤销对象权限  -->revoke  -->grant 改为remoke  to 改为 from


      eg  


      REVOKE select, insert


      ON departments


      FROM scott;


      Revoke succeeded.      


  4.角色  -->权限相同的用户的集合,将权限授予角色,再将角色授予用户,则用户即有权限


    1.创建角色


    create role manager


    2.将权限授予角色


    grant create table ,create view 


    to manager 


    3.将角色授予用户


    grant manager to dehaan ,kochhar;


      mysql 中的sql语句      


1.要进行全连接,需要先进行一次左连接再做一次右连接


  select emp.* ,dd.* 


  from employees emp letf join department_id dd on emp.deptno=dd.deptno


       right join   department_id dd on emp.deptno=dd.deptno


2.union all   -->将两个结果合并成一个结果集


  select * from scott.emp


  union all 


  select * from scott.emp


  union all


  select * from scott.emp  -->会将三个结果依次输出


文章转载自MySQL笔记,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论