Oracle--2--单值函数,多表查询(联合查询)

Lesson3 Single Row Functions:单值函数

  • A:函数分为:

    • 单值函数:
      1. 字符函数
      2. 日期函数
      3. 转换函数
      4. 数字函数
    • 分组函数:
  • B:字符函数

    1、lower(字段名):字段中所有的字段值字符转化为小写
    	select lower(last_name)
       	from s_emp;
    
    2、upper(字段名):字段中所有的字段值都是为大写
    	select upper(last_name)
       	from s_emp;
    
    3、initcap(字段名):字段值的首字母大写
    	select initcap(last_name)
       	from s_emp;
    
    4、concat(args1,args2):连接字段和字段(字段和字符),使用嵌套达到多个字段或者多个字符相连接
        select first_name||last_name
        from s_emp;
    
        select concat(first_name,last_name)
        from s_emp;
    
        41、嵌套连接:first_name和'.'连接再和last_name连接
            select concat(concat(first_name,'.')last_name)
            from s_emp;
    
    5、substr(字段,字符下标):该字段字符值,字符下标从1开始,第3个下标截取(包括第3个)
    	select last_name,substr(last_name,3) 
    	from s_emp;
    
        51、字符下标可以为负数,字段值最后字符下标为-1
            select last_name,substr(last_name,-1) 
            from s_emp;
    
    6、substr(字段,字符下标,字符个数):该字段字符值,字符下标从1开始,第3个下标截取(包括第3个),截取2个字符
    	select last_name,substr(last_name,3,2)
    	from s_emp;
    
        61、从-3下标正着截取2个字符
            select last_name,substr(last_name,-3,2)
            from s_emp;
    
    7、length(字段):返回字符串的长度
    	select length(last_name)
    	from s_emp;
    
        71、返回字符串的长度,并根据字符长度排序
            select length(last_name) as name
            from s_emp order by 1;
    
            select length(last_name) as len
            from s_emp order by len;
    
    8、nvl(出现null的字段,数字(字符)):替换nullselect last_name,nvl(commission_pct,0)
    	from s_emp;
    
  • C:dual哑表:dual是一个虚拟表,没什么实际作用,使select语法完成;sys数据库管理员拥有,oracle保证dual里面永远只有一条记录。

    select upper('hello') from s_emp;
    
    select upper('hello') from dual;
    
    select 1+1 from dual;
    
  • D:数字函数:

    1round(数字,位数下标):小数点后保留args2位
    	select round(45.9234,2)
    	from dual;
    
        11、小数点后保留args2位,args2+1位按照四舍五入规则
            select round(45.9254,2)
            from dual;
    
        12、小数点后保留0select round(45.9254,0)
            from dual;
    
            select round(45.9254)
            from dual;
    
        13、保留到十位
            select round(45.9254,-1)
            from dual; 十位
    
        14、保留到百位
            select round(45.9254,-2)
            from dual;百位
    
    2、trunc(数字,位数下标):指定具体位数后面截掉
    	百位以后截掉
    	select trunc(45.9254,-2)
    	from dual;
    
        21、十位以后截掉
            select trunc(45.9254,-1)
            from dual;
    
        22、个位以后截掉+1(例如:电话计时)
            select trunc(45.9254,0)+1
            from dual;
    
        23、个分位以后截掉
            select trunc(45.9254,1)
            from dual;
    
        24、	百分位以后截掉
            select trunc(45.9254,2)
            from dual;
    
    3mod(被除数,除数):两数相除取余数
    	select mod(3,10)
    	from dual;
    
        3110%3=1
            select mod(10,3)
            from dual;
    
  • E:日期函数

    • 默认日期格式 DD-MON-YY(显示结果跟语言环境有关),包含时分秒只是没显示。

      • ‘06-9月-19’

      • ‘06-SEP-19’

        1、sysdate:系统当前时间,根据语言环境,按照指定格式显示
        	select sysdate
        	from dual;
        
            11、当前时间的后1select sysdate+1
                from dual;
        
            12、当前时间的后1个月(不一定是30,根据年份的具体月份的天数)
                select sysdate+30
                from dual;
        
            13、当前时间的后1年(闰年为366select sysdate+365
                from dual;
        
            14、当前时间的后1小时
                select sysdate+1/24
                from dual;
        
            15、当前时间的后1分钟
                select sysdate+1/(24*60)
                from dual;
        
        2、months_between(time1,time2):time1和time2的时间差几个月
            1
            select months_between(sysdate+30,sysdate) 
                from dual;
        
            21.967741935
                select months_between(sysdate+29,sysdate) 
                from dual;
        
            221.03225806
                select months_between(sysdate+31,sysdate) from dual;
        
        3、add_months(sysdate(固定格式时间字符),月份个数)
        	select add_months('06-9月-19',2)
        	from dual;
        	ADD_MONTHS('06-9月-19',2)
            06-11-19
        
           	31、当前时间减少2个月
                ADD_MONTHS('06-9月-19',-2)
                06-7-19
                select add_months('06-9月-19',-2)
                from dual;
        
        
        4、next_day(当前时间,'星期'):指离定星期的最近的一天
        	select next_day(sysdate,'星期五')
        	from dual;
        
        5、last_day(sysdate(固定时间字符)):指定时间的月份的最后一天
        	select last_day(sysdate)
        	from dual;
        	
        	51select last_day('06-9月-19')
                from dual;
        
        6round(字段)61、月份:1516select round(sysdate,'MONTH')
                from dual;
        
                select round(sysdate+16,'MONTH')
                from dual;
        
            62、年:6月舍7月进
        
                select round(sysdate,'YEAR')
                from dual;
        
                select round(sysdate-90,'YEAR')
                from dual;
        
            63、天:
                select round(sysdate,'DAY')
                from dual;
        
        7、trunc(时间,'YEAR'):当前时间一年最开始
            TRUNC(SYSDATE,
            --------------
            01-1-19
            select trunc(sysdate,'YEAR')
            from dual;
        
            72、指定时间的月份的第一天是
           	TRUNC(SYSDATE,
            --------------
            01-9-19
        	select trunc(sysdate,'MONTH')
        	from dual;
            
            73、指定时间天数的一个星期的第一天
            TRUNC(SYSDATE,
            --------------
            01-9-19
        	select trunc(sysdate,'DAY')
        	from dual;
        
        
  • F:转换函数:

    • rr:千年虫规则(只能确定当前时间的前后50年年份)
    1、to_char:将数字或者时间转化为字符
        11、时间转化为字符(有固定格式)
            yyyy:2019
            rrrr:2019
            yy:19
            rr:19(千年虫:遇到跨越世纪问题,yy是用两个字符保存年份的,所以yy无法确定19年是哪个世纪的,rr有自己的规则)
            mm:09 月份
            D:6一星期中的第几天(从星期日开始)
            DD:06一个月中的第几天
            DDD:249一年中的第几天
            YEAR:TWENTY NINETEEN英文
            MONTH9月(SEPTEMBER)英文
            mon:9月(sep)英文
            ddsp:six(一个星期中的第几天)英文
            ddspth:sixth(英文序列数的第几天(一个月的))
            DAY:全英文的星期
            DY:简写的英文星期
            hh:小时
            mi:分钟
            ss:秒
    
        12、测试常见的一些日期数据转换为字符串的格式
            select to_char(sysdate,'yyyy rrrr yy rr mm D DD DDD YEAR MONTH mon ddsp ddspth DAY DY')
            from dual;
    
            2019 2019 19 19 09 6 06 249 TWENTY NINETEEN 99月  six sixth 星期五 星期五
    
        1303 29 5332953select to_char(sysdate,'hh mi ss')
            from dual;
    
        1415 29 53152953秒(24小时制)
            select to_char(sysdate,'hh24 mi ss')
            from dual;
             select to_char(sysdate,'hh24 mi ss am')
            from dual;
    
        1507-09-19
            select to_char(sysdate,'dd-mm-yy')
            from dual;
    
        1619-09-07
            select to_char(sysdate,'yy-mm-dd')
            from dual;
            
        1717-9-19
        	select to_char(sysdate,'dd-mon-yy')
        	from dual;
    
        1807-09-19 15:34:40 下午(07-09-19 15:35:04 PM)
            select to_char(sysdate,'dd-mm-yy HH24:MI:SS AM')
            from dual;
            select to_char(sysdate,'dd-mm-yy hh24:mi:ss am')
            from dual;
    
    2、to_char数字转化为字符
    
    9:根据数字实际长度显示
    0:根据0所占位数显示
    $:美币货币符号
    L:本地货币符号
    .:小数点
    ,:位数,每三位字符有','
    fm:设置字符靠左对齐
    
        21、个位以前可显示6位实际长度,小数位显示固定两位,字符默认靠右
            TO_CHAR(SALARY,'$999,999.00')
            ------------------------
               $2,500.00
               $1,450.00
            select to_char(salary,'$999,999.00')
            from s_emp;
    
        22、靠左对齐
            TO_CHAR(SALARY,'FM$999,999.00')
            ------------------------
            $1,490.00
            $1,515.00
            select to_char(salary,'fm$999,999.00')
            from s_emp;
    
        23、本地钱币符号
            TO_CHAR(SALARY,'FML999,999.00')
            ------------------------------------------2,500.001,450.00
            select to_char(salary,'fmL999,999.00')
            from s_emp;
    
    3、to_number:字符转化为数字,进行计算
    	select to_number('1000')
    	from dual;
    
    
    
    4、to_date:固定日期格式字符串转化为日期
        41、中,英文环境下都可以
            MYDATE
            ------------
            10-DEC-19
            select to_date('10-12-2019','dd-mm-yy') as mydate
            from dual;
    
        42、中文环境下
            MYDATE
            --------------
            10-12-19
            select to_date('10-12月-2019','dd-month-yy') as mydate
            from dual;
             select to_date('10-12月-2019','dd-mon-yy') as mydate
            from dual;
    
        43、中文环境下
            MYDATE
            --------------
            09-12-19
            select to_date('2019/12月/9','yy/month/dd') as mydate
            from dual;
            select to_date('2019/12月/9','yy/mon/dd') as mydate
            from dual;
    
  • F:注意:以上函数可以嵌套使用

    • 格式:F3(F2(F1(arg0,arg1),arg2),arg3)
    • select substr(upper(concat(‘hello’,‘world’)),4,4)from dual;
    • 先把’hello’和’world’连接起来,再转换为字母大写然后再从第4个字符开始,连着截取4个字符

Lesson4 Displaying Data from Multiple Tables:多表查询

  • A:多表查询:又称联合查表,即一条sql语句涉及到的表有多张,数据通过特定的连接进行联合显示

  • B:笛卡尔积:在数学中,两个集合X和Y的笛卡尓积(Cartesian product),又称直积,表示为X × Y.

    • 假设集合A={a, b},集合B={0, 1, 2},则两个集合的笛卡尔积为{(a, 0), (a, 1), (a, 2), (b, 0), (b, 1), (b, 2)}。
    • 在数据库中,如果直接查询两张或者多张表的时候就会产生笛卡尔积:select last_name,dept_id from s_emp,s_dept;
  • C:连接查询:

    • a、内连接

      1. 等值连接

        11、s_emp和s_dept两张表的通过部门id进行等值连接
            select last_name,dept_id,name 
            from s_emp se,s_dept sd
            where se.dept_id=sd.id ;
        
        12select last_name,dept_id,s_dept.id,name
            from s_emp,s_dept
            where s_emp.dept_id=s_dept.id ;
        
        13、table1 inner join table2 on 条件
            select last_name,dept_id,s_dept.id,name
            from s_emp
            inner join s_dept
            on s_emp.dept_id=s_dept.id ;
        
      2. 不等值连接

        假设数据库中还有一张工资等级表:salgrade
        	工资等级表salgrade:
        		gradeName列表示等级名称
        		losal	 列表示这个级别的最低工资数
        		hisal    列表示这个级别的最高工资数
        
        		表中的数据类似于下面内容:
        		id  salgrade	losal hisal
        		1  	初级程序员    2000  4000
        		2  	中级程序员    4000  6000
        		
        例如:
        查询出员工的名字、职位、工资、工资等级名称
        		SELECT  e.last_name, e.title, e.salray, s.gradeName
        		FROM    s_emp e, salgrade s
        		WHERE   e.salray BETWEEN s.losal AND s.hisal
        
    • b、外连接:解决两张表关联时候,数据没有显示出来的三种情况

      前提:特点:新员工tom不在任何部门,新增部门st下面没有任何员工
      	insert into s_emp(id,last_name) values(26,'tom');
      	insert into s_dept(id,name) values(60,'st');
      	commit;
      
      1、左外链接:tom的dept_id为null,在等值连接的时候,s_emp表没有显示tom员工
      oracle自带左外连接s_emp.dept_id=s_dept.id(+)
      
      	11、t1 left outer join t2 on 等值连接条件
      	select last_name,dept_id,s_dept.id,name
      	from s_emp
      	left outer join s_dept
      	on s_emp.dept_id=s_dept.id ;
      
      	12、可以省略outer关键字
      	select last_name,dept_id,s_dept.id,name
      	from s_emp
      	left join s_dept
      	on s_emp.dept_id=s_dept.id ;
      
      	13、s_dept.id(+):该字段主键作为其他表的FK为空时候,显示FK为空表的字段(左外链接)。
      	select last_name,dept_id,s_dept.id,name
      	from s_emp,s_dept
      	where s_emp.dept_id=s_dept.id(+);
      
      2、右外连接:s_dept的PK主键id作为s_emp的FK外键dept_id;s_emp中一个dept_id值都没有st部门id
      oracle自带右外连接s_emp.dept_id(+) = s_dept.id
      
      	21、t1 right outer join t2 on 等值连接条件
      	select last_name,dept_id,s_dept.id,name
      	from s_emp
      	right outer join s_dept
      	on s_emp.dept_id=s_dept.id ;
      
      	22outer可以省略
      	select last_name,dept_id,s_dept.id,name
      	from s_emp
      	right join s_dept on s_emp.dept_id=s_dept.id ;
      
      	23、s_emp的外键dept_id中都没有s_dept中的部门id,显示这个部门id
      	select last_name,dept_id,s_dept.id,name
      	from s_emp,s_dept
      	where s_emp.dept_id(+) = s_dept.id;
      
      3、全连接:t1 full outer join t2 on 等值连接条件;
      		显示s_emp中没有dept_id的
      		显示s_emp中不包含s_dept主键id
      
      	select last_name,dept_id,s_dept.id,name
      	from s_emp
      	full outer join s_dept
      	on s_emp.dept_id=s_dept.id ;
      	
      	31outer可省略
      	select last_name,dept_id,s_dept.id,name
      	from s_emp
      	full join s_dept
      	on s_emp.dept_id=s_dept.id ;
      
    • c、自连接

      select id,last_name,manager_id from s_emp;
      s_emp表(自己再连接自己):id,manager_id进行等值连接
      例如:
          ID LAST_NAME       MANAGER_ID
      	 1 Velasquez
           2 Ngao                     1
           3 Nagayama                 1
           4 Quick-To-See             1
           5 Ropeburn                 1
           6 Urguhart                 2
           7 Menchu                   2
      1、两张表s_emp s1,s2,id可以作为manager_id
      	select s1.last_name,s1.manager_id,s2.id,s2.last_name
      	from s_emp s1,s_emp s2
      	where s1.manager_id=s2.id;
      
      	11、显示没有manager_id的员工(左连接显示领导)
      	select s1.last_name,s1.manager_id,s2.id,s2.last_name
      	from s_emp s1,s_emp s2
      	where s1.manager_id=s2.id(+);
      
      	12、将manager_id为null的显示为领导
      	select s1.last_name,s1.manager_id,s2.id,nvl(s2.last_name,'领导') as manager
      	from s_emp s1,s_emp s2
      	where s1.manager_id=s2.id(+);
      
      	13、显示manager_id不包含id的员工(右外连接不是领导的员工)
      	select s1.last_name,s1.manager_id,s2.id,s2.last_name
      	from s_emp s1,s_emp s2
      	where s1.manager_id(+)=s2.id;
      
      
  • D:查询结果集操作:如果有俩条sql语句,每一条sql都可以查询出一个结果,这个被称之为结果集。

    • 使用下面的关键字对2个结果集进行操作

      1. union:取两个结果集的并集
      2. union all:2个结果集放在一起显示出来
      3. minus:第1个结果集 减 第2个结果(两个结果集相同的部分)
      4. intersect:2个结果集的交集
    • 注意:两个结果集的查询的字段(列)要完全一致

      1union:2个结果集的并集
      	select last_name,dept_id,name
      	from s_emp,s_dept sd
      	where dept_id=sd.id(+)
      	union
      	select last_name,dept_id,name
      	from s_emp,s_dept sd
      	where dept_id(+)=sd.id;
      	
      2union all:2个结果集一起显示
      	select last_name,dept_id,name
      	from s_emp,s_dept sd
      	where dept_id=sd.id(+)
      	union all
      	select last_name,dept_id,name
      	from s_emp,s_dept sd
      	where dept_id(+)=sd.id;
      	
      3、minus:第1个结果集去除第2个结果集两者相同的部分
      	select last_name,dept_id,name
      	from s_emp,s_dept sd
      	where dept_id=sd.id(+)
      	minus
      	select last_name,dept_id,name
      	from s_emp,s_dept sd
      	where dept_id(+)=sd.id;
      	
      	31、只显示没有员工的部门st
      	select last_name,dept_id,name
      	from s_emp,s_dept sd
      	where dept_id(+)=sd.id
      	minus
      	select last_name,dept_id,name
      	from s_emp,s_dept sd
      	where dept_id=sd.id(+);
      
      4intersect:2个结果集的交集部分
      	select last_name,dept_id,name
      	from s_emp,s_dept sd
      	where dept_id=sd.id(+)
      	intersect
      	select last_name,dept_id,name
      	from s_emp,s_dept sd
      	where dept_id(+)=sd.id;
      

      where dept_id=sd.id(+)
      minus
      select last_name,dept_id,name
      from s_emp,s_dept sd
      where dept_id(+)=sd.id;

      31、只显示没有员工的部门st
      select last_name,dept_id,name
      from s_emp,s_dept sd
      where dept_id(+)=sd.id
      minus
      select last_name,dept_id,name
      from s_emp,s_dept sd
      where dept_id=sd.id(+);
      

      4、intersect:2个结果集的交集部分
      select last_name,dept_id,name
      from s_emp,s_dept sd
      where dept_id=sd.id(+)
      intersect
      select last_name,dept_id,name
      from s_emp,s_dept sd
      where dept_id(+)=sd.id;

      
      
      

你可能感兴趣的:(Oracle,Oracle单值函数,千年虫问题,多表查询(联合查询))