sql的基础语句-单行函数,dual,数字函数,日期函数,表连接,集合运算,分组报表,单行子查询,多行子查询

3. 单行函数

3.1 转换函数

select ascii(‘A‘),chr(65) from dual;

select to_char(1243123),1231451 from dual;
靠左边的就是字符串,靠右边的就是数字

select to_char(123512a121) from dual;   --错误的写法,没有引号表示数字,但是数字里面包含了字母,不合法的输入值

select to_number(‘123141211‘) from dual;

select to_number(‘12314a1211‘) from dual;  --不合法的输入值

select to_date(‘20140610121212‘,‘yyyy-mm-dd hh24:mi:ss‘) from dual;

不合法的输入值:
select to_date(‘20141310121212‘,‘yyyy-mm-dd hh24:mi:ss‘) from dual;

select to_date(20140610121212,‘yyyy-mm-dd hh24:mi:ss‘) from dual;  --日期不加引号,数字类型

将日期转换为固定格式字符串
select to_char(sysdate,‘yyyy/mm/dd hh24:mi:ss‘) from dual;

select to_char(sysdate,‘yyyymmdd‘) from dual;

select to_number(to_char(sysdate,‘yyyymmdd‘)) from dual;

3.2 字符串的运算

(1)字符串的连接

select concat(‘123124‘,‘asdfda‘) from dual;    --只能传两个参数,但是||可以不断拼接

select ‘123124‘||‘asdfda‘ from dual;

(2)求长度

select length(‘adsfasgsadfasdf‘) from dual;

(3)截取串

select substr(‘asdfasdfasdfasdf‘,5,4) from dual;
从左向右第5位开始向后截取4个字节长度

select substr(‘asdfasdfasdfasdf‘,-5,4) from dual;
从右向左第5位开始向后截取4个字节长度

select length(substr(‘asdfasdfasdfasdf‘,-5,7)) from dual;    --截取完为止

(4)求子串的位置

select instr(‘asdfasdfasdfasdf‘,‘asdf‘,3,1) from dual;
从左向右第3位开始,第1次出现‘asdf’的索引位置

select instr(‘asdfasdfasdfasdf‘,‘asdf‘,3,2) from dual;
从左向右第3位开始,第2次出现‘asdf’的索引位置

select instr(‘asdfasdfasdfasdf‘,‘asdf‘,-3,2) from dual;         --9 (红色的为第一个,***开始为第二个,也就是第五个a是第二个,然后顺序再从右边第四个开始算起为1,所以也就是第九位) ;
从右向左第3位开始,第2次出现‘asdf’的索引位置
意思是说从右边的第三位开始算起,也就是从右边的第四位开始由1开始,然后第二次出现字符创的位置仍然是从左边开始的,也就是 a s d f a  s d f a,但是数字就是从右边算起
                       9 8 7 6 5 4 3 2 1
select instr(‘asdfasdfasdfasdf‘,‘asdf‘,-3,1) from dual;         --13
从右向左第3位开始,第1次出现‘asdf’的索引位置

(5)大小写的转换

select upper(‘asdfasgas‘),lower(‘GHJAJDGJ‘) from dual;

select lower(ename),lower(job) from emp;

(6) 替换

select replace(‘asdfasdfasdfasdf‘,‘asdf‘,‘H‘) from dual;

(7) 补足字符串

select lpad(‘asdf‘,20,‘*‘),rpad(‘asdf‘,20,‘*‘) from dual;

(8)去空格

select trim(‘     sadf      ‘) as a,ltrim(‘      asdf       ‘) as b,rtrim(‘      asdf       ‘) as c from dual;

(9)去中间的空格

select replace(‘   asdf  sdf  dfasdf  sdf    ‘   ,   ‘ ‘   ,   ‘‘    ) as a from dual;
                      ‘ 字符串  ’,分隔符   ‘ ’匹配条件 ‘’匹配结果

asdfsdfdfasdfsdf

###########################################################################################

4.数字函数

(1) 小数点后1位四舍五入

select round(2.76,1) from dual;

(2) 对整数四舍五入

select round(2.76) from dual;

(3)向上取整,ceil表示天花板

select ceil(4.3) from dual;

(4)向下取整,floor表示地板

select floor(4.8) from dual;

(5)求余数

select mod(10,3) from dual;

(6)截断

select trunc(10.454212348211,2),trunc(21154.1454211,-2) from dual;
注意:第二个参数是正数,截断小数点后面的两位
      第二个参数是负数,截断小数点前面的两位

##########################################################################################

5.日期函数

(1)截断日期

select trunc(to_date(‘20140610‘,‘yyyy-mm-dd‘),‘dd‘),trunc(to_date(‘20140610‘,‘yyyy-mm-dd‘),‘mm‘),
       trunc(to_date(‘20140610‘,‘yyyy-mm-dd‘),‘yyyy‘) from dual;

select trunc(to_date(‘20140610121212‘,‘yyyy-mm-dd hh24:mi:ss‘),‘hh‘),
       trunc(to_date(‘20140610121212‘,‘yyyy-mm-dd hh24:mi:ss‘),‘mi‘) from dual;

(2) 两个日期之间的天数  =  两个日期相减

select sysdate - to_date(‘20130610095000‘,‘yyyy-mm-dd hh24:mi:ss‘) from dual;

(3) 月份前后推

select add_months(sysdate,-12),add_months(sysdate,3) from dual;

第二个参数为负数,往前推
第二个参数为正数,往后推

(4) 算两个日期间隔的月数

select months_between(sysdate,to_date(‘20130610100000‘,‘yyyy-mm-dd hh24:mi:ss‘)) from dual;

例子:

计算入职时间年数的分布:

A:1年以内
    B:1~3年
    C:3~5年
    D: 5年以上

select rs1,count(*) from
     (select empno,(case when rs<=1 then ‘BELOW 1‘
                    when rs>1 and rs<3 then ‘1~3‘
                    when rs>=3 and rs<5 then ‘3~5‘
                    when rs>=5 then ‘over 5‘ end) as rs1
       from(
        select empno,round((months_between(sysdate,hiredate)/12)) as rs
          from emp
        )
     )group by rs1;

(5) decode函数
   
    F=decode(p1,p2,p3,p4,p5...,pn)
   含义:如果p1 = p2,F=p3
     如果p1 = p4,F=p5
         .....
     如果都不满足,F=pn

select decode(deptno,10,‘dept10‘,20,‘dept20‘,30,‘dept30‘,‘dept40‘) as x  from dept;
=
  select (case when deptno=10 then ‘dept10‘
             when deptno=20 then ‘dept20‘
             when deptno=30 then ‘dept30‘
             else ‘dept40‘ end
        ) as x
  from dept;

(6)nvl函数

nvl(comm,9999) -- 如果第一个参数为null,就显示第二个参数

示例:求当第一个数为null的时候,值取9999,否则等于原值

select empno,nvl(comm,9999) as x,decode(comm,null,9999,comm) as y,(case when comm is null then 9999 else comm end) as z  from emp;

###########################################################################################

6.表的连接

6.1等值连接

select b.deptno,a.ename from dept b (inner) join emp a on(a.deptno=b.deptno)
等值连接其实就是内连接

6.2左连接

select b.deptno,a.ename from dept b left (outer) join emp a on(a.deptno=b.deptno);
dept -- 主表
emp  -- 副表
编写方式:主表 left join 副表,保证主表的数据不丢失

6.3右连接

select b.deptno,a.ename from emp a right join dept b on(a.deptno=b.deptno);
dept  -- 主表
emp   -- 副表
编写方式:副表 right join 主表,保证主表的数据不丢失

oracle语法:将左右连接统一表示
select b.deptno,a.ename from emp a, dept b where a.deptno(+)=b.deptno;
select b.deptno,a.ename from emp a, dept b where b.deptno=a.deptno(+);
(+)的对面的表就是主表
dept表是主表
emp 表是副表

注意:
  A:如果副表上有过滤条件的时候,怎样满足左右连接的效果

select b.deptno,a.ename from dept b left join emp a on(a.deptno=b.deptno) where a.sal>1000;
为了加过滤条件,把主表的数据丢了,此时失去左连接的意义

select b.deptno,a.ename from dept b left join emp a on(a.deptno=b.deptno and a.sal>1000);
=
select b.deptno,a.ename from dept b,emp a where a.deptno(+)=b.deptno and a.sal(+)>1000;

B:主表上有过滤条件,不存在这个问题

数学原理:

左连接 :   A∪(A∩B)
等值连接:  A∩B

6.4多表关联

select * from a,b,c,d where a.x=b.x and b.y=c.y and c.z=d.z;

特殊的连接:笛卡尔积
  select * from a,b

6.5非等值连接

select e.ename,s.grade,e.sal
  from emp e,salgrade s
 where e.sal between s.losal and s.hisal;

salgrade:薪资等级表

6.6自连接

查询所有员工的直接上司的对应关系,表示成“员工名称 work for 上司名称”,一般用在有层级关系的表上面
  select worker.ename ||‘ work for ‘||manager.ename
  from emp worker,emp manager
 where worker.mgr=manager.empno;

##########################################################################################

7 集合运算

7.1 求差集

A. not exists操作和not in 操作

select b.deptno,b.dname,b.loc from dept b
 where not exists(select a.deptno from emp a where a.deptno=b.deptno);
=
select b.deptno,b.dname,b.loc from dept b
 where b.deptno not in(select a.deptno from emp a where a.deptno=b.deptno);

B. minus操作

select b.deptno from dept b
minus
select a.deptno from emp a;

7.2 求交集
 
 A exists操作 和 in操作

select b.deptno,b.dname,b.loc from dept b
 where  exists(select a.deptno from emp a where a.deptno=b.deptno);
=
select b.deptno,b.dname,b.loc from dept b
 where b.deptno in(select a.deptno from emp a where a.deptno=b.deptno);

B 等值连接

select distinct b.deptno,b.dname,b.loc from emp a,dept b where a.deptno=b.deptno;

7.3 求并集

A 左右连接(其中一个集合是另外一个集合的子集)

select b.deptno,a.ename from dept b left join emp a on(a.deptno=b.deptno);

B union操作

select b.deptno from dept b    --合并后去重
union
select a.deptno from emp a;

select b.deptno from dept b     --合并之后不去重
union all
select a.deptno from emp a;

7.4 求全集

select * from emp;

7.5 求子集
 
 select * from emp where ename like ‘T%‘;

7.6 求补集

select * from emp where ename not like ‘T%‘;

7.7 求映射

select ename,job from emp where ename like ‘T%‘;
在操作ename集合的时候,同时查询job字段映射的值

###########################################################################################

8.分组报表

select b.deptno,b.dname,nvl(floor(avg(a.sal)),0) as x,nvl(sum(a.sal),0) as y,nvl(min(a.sal),0) as z,nvl(max(a.sal),0) as l
  from emp a,dept b
 where a.deptno(+)=b.deptno
 group by b.deptno,b.dname
 order by b.deptno,b.dname;

having 字句  --  对聚合函数的结果进行过滤

select b.deptno,b.dname,nvl(floor(avg(a.sal)),0) as x,nvl(sum(a.sal),0) as y,nvl(min(a.sal),0) as z,nvl(max(a.sal),0) as l
  from emp a,dept b
 where a.deptno(+)=b.deptno
 group by b.deptno,b.dname
 having avg(a.sal)>2000
 order by b.deptno,b.dname;

注意:having字句一定要放在order by的前面,group by的后面

##########################################################################################

9.单行子查询还有多行子查询

(1) 单行子查询:返回一行的子查询

需求:显示scott员工姓名、薪水、部门号并且与其同部门的人相同信息也显示出来

select ename,sal,deptno from emp
    where deptno=(select deptno from emp where ename=‘SCOTT‘)
  =
   select ename,sal,deptno from emp
    where deptno in (select deptno from emp where ename=‘SCOTT‘)
 
 (select deptno from emp where ename=‘SCOTT‘)返回单行,叫做单行子查询。 =、in 叫做单行操作符

(2) 多行子查询:返回多行的子查询

需求:显示部门10所有岗位job在全公司对应相同岗位人的姓名、薪水、部门号
   
select ename,sal,deptno from emp
where job in (select job from emp where deptno=10)
in 在这里是作为多行操作符使用

select ename,sal,deptno from emp
where job = (select job from emp where deptno=10)  
错误的写法,=是单行操作符

A 在多行子查询中使用any操作符
 
  需求:显示全公司工资高于部门10任一员工工资的员工的姓名、薪水、部门号

select ename,sal,deptno from emp
where sal > any(select sal from emp where deptno=10)
>是单行操作符,而子查询是多行的,用any来解决语法冲突,满足‘任一‘这种需求

B 在多行子查询中使用all操作符

需求:显示全公司工资高于部门20所有员工工资的员工的姓名,薪水,部门号
  select ename,sal,deptno from emp where sal > all(select sal from emp where deptno=20)
>是单行操作符,而子查询是多行的,用all来解决语法冲突,满足‘所有‘这种需求

注意:
 1.子查询中不能写order by
 2.多行子查询不能用单行操作符匹配
 3.单行子查询可以匹配多行操作符
 4.子查询必须写在括号里面
 5.子查询要放在比较运算符后面

10. 嵌套子查询(多个子查询)

select ename,sal,deptno from emp
 where sal > (select sal from emp where empno=7876) and job = (select job from emp where empno=7369);

时间: 2024-10-12 12:38:04

sql的基础语句-单行函数,dual,数字函数,日期函数,表连接,集合运算,分组报表,单行子查询,多行子查询的相关文章

sql 的基础语句

USE day15; -- 创建表CREATE TABLE teacher( id INT, NAME VARCHAR(20))-- 查看所有表SHOW TABLES; DESC student; DROP TABLE student; CREATE TABLE student( id INT, NAME VARCHAR(20), gender VARCHAR(2), age INT) -- ********一.增删改数据********* ----- 1.1 增加数据-- 插入所有字段.一定依

oracle 内置函数(三)日期函数

日期函数概要: 系统时间 日期操作 一.系统时间 sysdate:还是西方的格式,我们一般需要to_char(date,'yyyy-mm-dd hh24:mi:ss') next_day:当前日期的下一个礼拜几的日期 example:求当前时间的下一个礼拜一的日期: last_day(date):取当前时间的月的最后一天:用于判断当前月28.29.30.31天 months_between:求两个时间的月份差 extract:分别获取当前时间的年.月.日

sql的基础语句-sql的查询语句select

SQL查询语句介绍--select语句 1.简单的select查询语句 1.1 查行 SQL> select * from emp; 1.2 查列 SQL> select empno,ename from emp; 1.3 关联查询 oracle的语法: select  a.*,b.*  from emp a,dept b where a.deptno=b.deptno; 通用的语法: select  a.*,b.* from emp a join dept b on(a.deptno = b

sql的基础语句-select语句中出现的操作符号

2. select语句中出现的操作符号 2.1 合并操作符select a.ename||' '||to_char(sal) from emp a; 2.2 消除重复的行 select distinct deptno from emp; 2.3 空格.空串.null的区别 select ascii(' '),ascii(null),ascii('') from dual; 区别:  从显式上看,空串跟null在数据库中存储的值是一样的,但是NULL可以赋给任何数据类型,而空串只能赋给字符串类型

Sql Server -更新语句,修改的字段是日期时间型,修改其中的月份

update T_Sys_Partner set EXPIREDATE = convert(nvarchar,year(EXPIREDATE))+'-'+'6' + right(convert(nvarchar(19),EXPIREDATE ,120),12) WHERE MONTH(ExpireDate) = 4

MYSQL常用函数(时间和日期函数)

CURDATE()或CURRENT_DATE() 返回当前的日期 CURTIME()或CURRENT_TIME() 返回当前的时间 DATE_ADD(date,INTERVAL int keyword)返回日期date加上间隔时间int的结果(int必须按照关键字进行格式化),如:SELECTDATE_ADD(CURRENT_DATE,INTERVAL 6 MONTH); DATE_FORMAT(date,fmt) 依照指定的fmt格式格式化日期date值 DATE_SUB(date,INTER

Oracle函数-单行函数-数字、日期、日期处理函数

函数的分类 单行函数:一个input对应一个output,input和output存在一一对应的关系 如lower 组函数:多个input,但是只对应一个output.如 sum() ============================================================== 单行函数 特点: 每行返回一个结果,输入输出存在一一对应的关系 能嵌套使用 ,一个函数的输出能做另外一个函数的输入 如:select lowner(upper('aa')) from dua

Oracle—SQL基础语句

1 --去除重复行:distinct 2 --作用范围:是后面所有字段的组合 3 select distinct deptno sal from emp; 4 SELECT * FROM emp ORDER BY sal; 5 --(DATE类型)的条件 6 SELECT * FROM emp WHERE hiredate ='17-12月-80'; 7 --使用like模糊查询(%代表0或多个字符,_代表一个字符,特殊字符用ESCAPE标示符查询) 8 SELECT * FROM emp WH

sql注入基础

有好多人都只知道有sql注入漏洞这种漏洞,也知道怎么用一些工具来利用漏洞,但是却不知道SQL注入漏洞的原理.为了帮助初学者理解sql注入的原理,我写下了这篇文章,希望能对大家有所帮助. 什么是SQL注入: SQL注入是攻击者通过把恶意SQL命令插入到Web表单的输入域或页面请求的查询字符串中,来达到欺骗服务器执行恶意的SQL命令的一种攻击方式.(数据与代码没有完全分离) Sql注入漏洞产生原理: 上面我们提到SQL注入的产生原因是数据和代码没有完全分离产生的.下面我们来看看SQL注入漏洞具体的产