sql日常总结

版权声明:著作权归作者所有,未经作者同意不得转载。 https://blog.csdn.net/qq_33417321/article/details/82664164

一、sql基础

  1. 查询city字段以A或L或N开头的数据
SELECT * FROM Persons WHERE City LIKE '[ALN]%'
  1. 查询city字段不以A或L或N开头的数据
SELECT * FROM Persons WHERE City LIKE '[!ALN]%'
  1. 连接符
select concat(id,’的学号’,cardno,’的卡号’);  #Mysql语法
select 'hello'||'oracle' test from dual;   #Oracle语法(oracle也可以用上边的concat)
  1. 字符串
select substr('hello',0,3) from dual    --下标1与0效果一样   结果:hel
select length('hello') from dual   --结果:5
select replace('hello','l','x') from dual   --结果:hexxo
  1. 数值
select round(45.926,2) from dual  --45.93  四舍五入
select trunc(45.926,2) from dual  --45.92  截断
select mod(1600,300) from dual    --100
  1. 日期
select  ename,round((sysdate-hiredate)/7) from emp –入职周数
select ename,round(months_between(sysdate,hiredate)) from emp  --入职月数
select add_months(sysdate,3) from dual  --3个月后的日期   2018/3/26 21:29:19
  1. to_char函数
select ename,to_char(hiredate,'yyyy-mm-dd') from emp --1981--02—20
select ename,to_char(hiredate,'fmyyyy-mm-dd') from emp --1981-2-20
select to_char(sysdate,'yyyy-mm-dd hh :mi:ss') from dual—分钟是mi
  1. to_number函数
select to_number('10')+to_number('12') from dual --将字符串转换为数字
--查询1980和1985年入职的员工
select * from emp where to_char(hiredate,'yyyy')=1980 or to_char(hiredate,'yyyy')=1985
  1. to_date函数
select * from emp where hiredate between '1890-01-01' and '1982-12-31'  #mysql语法
#oracle不能像上边那样写,因为hiredate是日期类型,与字符串类型匹配不上
select * from emp where hiredate between to_date('1980-01-01','yyyy-mm-dd') and to_date('1980-12-31','yyyy-mm-dd')  #oracle语法
  1. decode函数(只有oracle有该函数)
select job, decode(job, 
'CLERK', '业务员',
'SALESMAN','销售员',
'其他'
) from emp;
#以下语法(case/when)可以替换是那个边的表达
select job,
case job 
   when 'CLERK' then '业务员'
   when 'SALESMAN' then '销售员'
     else '其他'
       end
from emp;
  1. 约束
create table  person(

pid number(5),
pname varchar2(30) not null,
gender number(1),
tele varchar2(11) ,

constraint pk_pid primary key(pid),-- constraint后是起的名字
constraint check_gender check(gender in(0,1)),--性别只能是1或2
constraint unique_key unique(tele)
)
  1. 外键
create table   orders(   --订单
oid number(5) primary key,
totalprice number(8,2)
)

create table orderdetail(  --订单项   键盘,鼠标是两个订单项,属于同一订单
oidid number primary key,
price number(8,2),
name varchar2(30),
oid number(5),--外键
constraint fk_orderdetail_orders foreign key(oid) references orders(oid)
);
  1. 聚合函数不能写在where之后
SELECT city FROM weather WHERE temp_lo = max(temp_lo); #语法错误,修改为如下写法是正确的
SELECT city FROM weather WHERE temp_lo = (SELECT max(temp_lo) FROM weather);  #语法正确
  1. where与having的区别
WHERE在分组和聚合计算之前选取输入行(它控制哪些行进入聚合计算);而HAVING在分组和聚合之后选取输出行。
因此,WHERE 子句不能包含聚合函数;因为试图用聚合函数判断那些行将要输入给
聚合运算是没有意义的。 相反,HAVING子句总是包含聚合函数。当然,你可以写不使用聚合的HAVING 子句,但这样做没什么好处,因为同样的条件用在WHERE阶段会更有效。

二、数据类型

  1. 浮点型
float(m,d);   #单精度浮点型    8位精度(4字节)     m总个数,d小数位
double(m,d);  #双精度浮点型    16位精度(8字节)    m总个数,d小数位
  1. char与varchar
char:
固定长度;例如某字段定义为10个长度,该字段存了一个汉字”是”,这个汉字占两个字符,剩下八个字符会自动填满;最大长度255,长度没有默认长度,必须显式指定长度
varchar2:
长度不固定,同上,剩下八个用不到的字符空间会释放出去。Varchar2与mysql里的varchar一样;最大长度3999(即可以放2000个中文或3999个英文),没有默认长度,必须指定长度;
  1. number
number:默认长度是8
number(3):存的最大数是999
number(3,2):存的最大数是9.99
  1. date:
相当于mysql里的datetype,mysql里的date只有年月日,datetype还包括时分秒
  1. timestamp:
也是日期类型,相对于date来说,精度高,最多可以保留到秒后9位小数
  1. long
相当于mysql里的longtext,即大文本,可以支持两个G
  1. clob:
可以放四个G内容
  1. blob:
可以放四个G内容,存放电影,图片等;
  1. 定点数
#浮点型在数据库中存放的是近似值,而定点类型在数据库中存放的是精确值。 
decimal(m,d) 参数m<65,指的是总个数;d<30且 d<m,指的是小数位个数。

三 、注意点

  1. union与union all
   UNION 结果集中的列名总是等于 UNION 中第一个 SELECT 语句中的列名。
  1. 删除数据——delete与truncate
delete from person where name=’tom’;# delete from person删除全部数据;
truncate person;  # 删除全部数据
delete:可以回滚,也可以闪回;
delete删除会产生磁盘碎片,且不释放空间;truncate不会产生磁盘碎片;
truncate先摧毁表结构,再重构表结构;delete只删除数据而已;
  1. savepoint事物保存点
insert into person(pid,pname,gender,tele) values('1','tom','1','13222229090');
savepoint a;
update  person set tele='1111111111' where   pid='1';
savepoint b;
select * from  person;
rollback to a;  #回滚到事物保存点a之前
  1. 视图 view
    视图可以理解为一个虚表,封装了一条复杂的查询语句,视图可以隐藏敏感列;
    语法:create view 视图名 as sql查询语句(最后是复杂的sql查询语句,可以用括号括起来)
先登录管理员用户,为当前用户(scott)提供创建视图的权限:grant create any view to scott;
create view person_view as (select pname from  person where  pid='1');#创建视图
select * from   person_view;--查出来的是姓名
#优点:隐藏敏感列:比如隐藏工资与奖金列
create view view_emp as(select empno,ename,job,mgr,hiredate,deptno from emp)
select * from    view_emp;
修改(update)视图的话,会将视图里涉及到的表数据修改,所以一般创建视图时将视图设计成只读:
create or replace  view person_view  as (select pname from  person where  pid='1') with read only;   #此时该视图就不能update了
  1. 序列——sequence
    auto increment语法只有mysql有,oracle没有;序列主要是做主键自增的,是独立于表之外的对象;
create sequence seq_person;   --创建序列,没有与任何表产生关系,独立于表之外
select seq_person.nextval from dual  --1  每执行一次,得到的结果依次加1
select seq_person.currval from dual   --查看当前的值
insert into person(pid,pname) values (seq_person.nextval,'tom');
# 序列一般单表单用,有几个表就创建几个序列,如果多个表操作同一张表的序列,容易出现断层;
创建序列的复杂语法如下:

create sequence test
minvalue 3        --最小值,默认是1
increment by 2    --步增值,默认1
start with 5      --起始值,默认1
maxvalue 20       --最大值,默认值是18个9。不做循环的话,超过最大值会报错
cycle             --循环  默认是nocycle
cache 5     --缓存,默认缓存的数是20(缓存在内存里),这里的值必须小于每次循环出来的数的个数
select test.nextval from dual;上边的复杂语法不能做主键自增,主键会冲突;即序列主要是做主键自增,也可以做其他事;
  1. 索引——index
    也是独立于表之外的对象;作用是提高查询效率(相当于书的目录);
使用索引规则:
1、表里的数据经常被修改的话,不适合建索引;
2、数据量小时不用建立索引;
3、某些字段不会被当成条件做查询时,没有必要建立索引

语法:create index 索引名 on 表名(字段名);
eg: create index index_emp_ename on emp(ename);
select * from   emp where ename='SMITH';  --建索引前后查询所花的时间:0.031  0.016
数据少的话效果不明显,下边创建500万条数据
create table  t_test(
tid number,
tname varchar2(30)
)
begin
  for i in 1..5000000
    loop
      insert into t_test values(i,'测试数据'||i);
    end loop;
end;
create index test_index on t_test(tname);
select * from  t_test where tname='测试数据4565558';#这样数据量大的话效果会很明显;

复合索引:对表里多个字段做索引
   create index index_emp on emp(ename,job);# 注意,此时只有将ename,job同时作为查询条件时才会用到索引,不然不会用到索引的,比如select * from   emp where job='' and hiredate=''是不会用到索引的;
  1. 同义词
给用户分配创建同义词的权限:grant create synonym to scott;
同义词相当于别名;

使用场景:一个用户下想访问另一个用户下的某张表,可以这样写:
select * from   scott.emp;
此时为了访问方便,可以建立同义词:create public synonym emp for scott.emp  --public 可以不写
以后查询时:select * from emp;
删除同义词:drop public synonym emp --如果上边加了public,这里也要加上
  1. 数据导入导出
    用于数据备份;
1、 exp system/root full=y; # 整库导出,基本不用;
2、按用户导入导出:把scott用户下的数据导入maltose01用户下:
注意:使用exp与imp这两个命令的话,电脑上必须安装oracle软件,所以下边的命令需要在虚拟机里执行
--先导出
exp scott/[email protected]:1521/orcl file='c:\scott.dmp'
--再将上边的数据导入到另一个用户
imp maltose01/[email protected]:1521/orcl file='c:\scott.dmp' full=y
3、按表导入导出(plSql工具右键表就能导出该表)
--先导出
exp scott/[email protected]:1521/orcl file='c:\scott.dmp' tables=emp,student,teacher
--再导入到另一个用户
imp maltose01/[email protected]:1521/orcl file='c:\scott.dmp' full=y  tables=emp,student,teacher

猜你喜欢

转载自blog.csdn.net/qq_33417321/article/details/82664164