zoukankan      html  css  js  c++  java
  • 数据库SQL笔记

    一. 创建数据库和表

    1.创建数据库
    1 --创建数据库  
    2 create database StudentMS  
    3   
    4 --使用数据库  
    5 use StudentMS  
    6   
    7 --删除数据库  
    8 drop database StudentMS 

     2.创建表并设置主键(外键类似)

     1 --创建学生表 (属性:姓名、学号(pk)、学院、出生日期、性别、籍贯、系代号)  
     2 create table xs  
     3 (  
     4     name varchar(10) not null,  
     5     id varchar(10) not null,  
     6     xy varchar(10),  
     7     birthday datetime,  
     8     xb char(2),  
     9     jg varchar(8),
    10     xdh varchar(10) 
    11 )  
    12   
    13 --创建学生表主键:学号  
    14 alter table xs  
    15     add constraint  
    16 pk_xs primary key(id)  
    17   
    18   
    19 --创建表学生表外键:系代号   
    20 alter table xs  
    21     add constraint  
    22 fk_xs foreign key(xdh)  
    23 references xb (xdh)  

    3.插入数据

    1 insert into xs   
    2     (id, name, xb, birthday, xy, jg, xdh)   
    3 values('201530310038', '苏国强', '', '1993-09-11', '信息学院', '江苏省','021');   

    二. select查询操作

    1.通过日期计算年龄
    通过 (当前日期-出生日期) 两种方法:         1). year(getdate()) - year(birthday)         2). datediff(YY, birthday, getdate())  代码如下:
    1 select id as 学号, name as 姓名, year(getdate())-year(birthday) as 年龄, birthday as 出生日期  
    2 from xs;  
    3   
    4 select id as 学号, name as 姓名, datediff(YY,birthday,getdate()) as 年龄, birthday as 出生日期  
    5 from xs;

    2.获取某列所有不同的属性值 group by

    1 --方法1:group by 列分组  
    2 select xy from xs group by xy;  
    3   
    4 --方法2:列出不同的值  
    5 select distinct xy from xs;  

    统计不同学院的人数信息:select xy as 学院, count(*) as 总人数 from xs group by xy;

    PS:如果需要排序可以添加order by xy,而统计重名学生可通过having count(*)>1.

    3.查询字符串匹配like和多值属性判断
    1 --匹配姓名以"黄"开头的学生  
    2 select * from xs where name like '黄%';  
    3   
    4 --匹配学院包含"计算机"的学生  
    5 select * from xs where xy like '%计算机%';  
    6   
    7 --匹配姓名以"尚香"结尾的学生  
    8 select * from xs where name like '%尚香';  

    LIKE匹配某个字段的变量的方法:DL_BHXNZYMC like '%' || ZY_NAME ||'%'

    1 select T_WSTB_DLPYJBQKB.DL_BHXNZYMC, ZY_NAME   
    2 from T_WSTB_ZYJBQK, T_WSTB_DLPYJBQKB   
    3 where T_WSTB_DLPYJBQKB.DL_BHXNZYMC like '%' || ZY_NAME ||'%' 

    IN 操作符允许我们在 WHERE 子句中规定多个值,换种说法就是替换

    1 --用'河北省'替换'河南省'2 select * from xs where jg in ('河北省','河南省');  

    4.查询输出某列属性中的某个特定值
     1 select xy as 学院名称 from xs where xy='软件学院' group by xy;  

    5.子查询统计不同阶段学生总数
    使用子查询统计不同学院总人数、不同性别总人数和河北/河南学生总人数。

     1 --子查询统计人数  
     2 select a.a_num as 软院人数, b.b_num as 计院人数, c.c_num as 自动化人数,   
     3        d.d_num as 男生人数, e.e_num as 女生人数, f.f_num as 河北河南人数  
     4 from  
     5 (select count(*) as a_num from xs where xy='软件学院') a,  
     6 (select count(*) as b_num from xs where xy='计算机学院') b,  
     7 (select count(*) as c_num from xs where xy='自动化学院') c,  
     8 (select count(*) as d_num from xs where xb='') d,  
     9 (select count(*) as e_num from xs where xb='') e,  
    10 (select count(*) as f_num from xs where jg in ('河北省','河南省')) f;

    6.使用子查询按行动态输出学院相关信息
    获取每个学院总人数、男生总人数、小于等于25岁的总人数和生源地河北河南人数。
    这种方法通常是多个表之间的夸表查询,首先创建一个学院表:学院名称和学院代码。

     1 --创建学院表   
     2 create table table_xy  
     3 (  
     4     name varchar(10) not null,  
     5     id varchar(10) not null  
     6 );  
     7   
     8 --插入数据  
     9 insert into table_xy(id, name) values('001', '软件学院');  
    10 insert into table_xy(id, name) values('002', '计算机学院');  
    11 insert into table_xy(id, name) values('003', '自动化学院');  
    12 insert into table_xy(id, name) values('004', '法学院');  

    子查询SQL语句如下:

    1 select distinct name as 学院名称,   
    2 (select count(*) from xs where xs.xy=table_xy.name) as 总人数,  
    3 (select count(*) from xs where xs.xy=table_xy.name and xs.xb='') as 男生总数,  
    4 (select count(*) from xs where xs.xy=table_xy.name and datediff(YY,birthday,getdate())<=25) as 二十五岁人数,  
    5 (select count(*) from xs where  xs.xy=table_xy.name and xs.jg in ('河北省','河南省')) as 河北河南生源地  
    6 from table_xy;  

    7.Oracle数据库null设置成自定义值的方法
    1). nvl(expr1, expr2)
    若EXPR1是NULL,則返回EXPR2,否則返回EXPR1。nvl(person_name,“未知”)表示若person_name字段值为空时返回“未知”,如不为空则返回person_name的字段值。通过这个函数可以定制null的排序位置。 |
    2). decode(DEPARTMENT_NAME, null, 'NULL', DEPARTMENT_NAME)
    如果部门名称在表中值为null,则用NULL替代,也可设置为"空"各种自定义字符串。decode函数比nvl函数更强大,同样它也可以将输入参数为空时转换为一特定值。

    PS:而SQL Server中没有函数decode,但是其实质可以通过case when来实现和替代。


    8.Oracle计算百分比trunc方法
    核心SQL语句如下:to_char(trunc(NUM/ALL_NUM*100, 2)) || '%
    9.Oracle查询除法/运算
    使用trunc主要是小数点保留两位有效数字。

    1 select t1.ZFJGSL as 数量,  
    2         trunc( 1.0 * (select ITEM_VALUE from T_WSTB_YJBKBYSJYQK  
    3             where RECORD_YEAR=(to_char(sysdate, 'yyyy')-2) and FIRST_NUM='2' and SECOND_NUM='2') /  
    4             (select ITEM_VALUE from T_WSTB_YJBKBYSJYQK  
    5             where RECORD_YEAR=(to_char(sysdate, 'yyyy')-2) and FIRST_NUM='2' and SECOND_NUM='1') * 100,  
    6         2) as 比例  
    7 from   
    8 (select ITEM_VALUE as ZFJGSL from T_WSTB_YJBKBYSJYQK  
    9  where RECORD_YEAR=(to_char(sysdate, 'yyyy')-2) and FIRST_NUM='2' and SECOND_NUM='2') t1;

    10.Oracle统计某个属性逗号分隔值的个数
    如下图所示,学科大类中包括各个学科专业名称,通过逗号分隔,如何统计个数呢?

    SQL代码如下,Orcale使用length,其他是len函数:

    1 select DL_NAME as num1,  
    2     length(DL_BHXNZYMC)-length(replace(DL_BHXNZYMC,'',''))+1 as num2  
    3 from T_WSTB_DLPYJBQKB 

    运行结果如下所示:

     11.Oracle使用CASE WHEN替代子查询

     1 --子查询统计人数  
     2 select a.a_num as 软院人数, b.b_num as 计院人数, c.c_num as 自动化人数,   
     3        d.d_num as 男生人数, e.e_num as 女生人数, f.f_num as 河北河南人数  
     4 from  
     5 (select count(*) as a_num from xs where xy='软件学院') a,  
     6 (select count(*) as b_num from xs where xy='计算机学院') b,  
     7 (select count(*) as c_num from xs where xy='自动化学院') c,  
     8 (select count(*) as d_num from xs where xb='') d,  
     9 (select count(*) as e_num from xs where xb='') e,  
    10 (select count(*) as f_num from xs where jg in ('河北省','河南省')) f;  

    在Oracle中如果想减少代码量或者不适用子查询,可以CASE WHEN语句进行替代。

    1 SELECT COUNT(*) AS 总人数,  
    2     COUNT(CASE WHEN HIGHEST_DEGREE='博士'THEN 1 END) AS 博士人数,   
    3     COUNT(CASE WHEN HIGHEST_DEGREE='硕士'THEN 1 END) AS 硕士人数,   
    4     COUNT(*)-COUNT(CASE WHEN HIGHEST_DEGREE='博士'THEN 1 END)-COUNT(CASE WHEN HIGHEST_DEGREE='硕士'THEN 1 END) AS 其他学历  
    5 FROM T_WSTB_FULL_TIME_TEACHER   
    6 WHERE IS_FOREGOER='' and YEAR_START=to_char(sysdate,'yyyy')-1;  

    这段SQL语句表示求教师表IS_FOREGOER学科带头人且入校年份为2015年的总人数、博士人数、硕士人数和其他学历的人数。
    COUNT(CASE WHEN HIGHEST_DEGREE='博士' THEN 1 END) AS NUM2 表示当最高学历HIGHEST_DEGREE字段为'博士'时,统计数量加1。
    当然如果需要计算学院各个班级的总人口,可以采用使用下面的SQL:COUNT(CASE WHEN DW_NAME='软件学院' THEN NUM_STU END) AS NUM2
    也可以使用提到的CASE防止除法计算分母为0,ZS总数、SHSJ社会实践人数。即:round((case when ZS!=0 then SHSJ/ZS else 0 end),3) as bl

    12.Oracle子查询中使用a.* 统计所有字段
    这里是使用a.*统计所有字段,其中a表示子查询重命名的结果,给人以很清新的感觉,虽然有点华而不实吧!
    PS: 这部分代码是网上看到的,感觉非常不错,自愧不如,学习之~

     1 SELECT a.*, b.*   
     2 FROM   
     3 (SELECT SUM(DOMESTIC_TRAIN) + SUM(OVERSEA_TRAIN_TOTAL) AS zj,   
     4     SUM(DEGREE_PHD) AS qzgdbsx,   
     5     SUM(DOMESTIC_TRAIN) AS jnjxrcs,   
     6     SUM(OVERSEA_TRAIN_TOTAL) AS jwjxrcs   
     7  FROM TRAIN_INTERFLOW   
     8  where YEAR_START=to_char(sysdate,'yyyy')-2  
     9 ) a,   
    10 (SELECT SUM(PARTICIPANT_NUMBER) AS cyjglxkrcs   
    11  FROM EDU_REVOLUTION   
    12  where YEAR_START=to_char(sysdate,'yyyy')-2  
    13 ) b;  

    13.Oracle使用decode函数防止除法分母为0
    解决方法:使用函数decode,当分母为0时直接返回0,否则进行除法运算。
    select a/b from c; 修改成如下即可:select decode(b, 0, 0, a/b) from c;

     1 select decode  
     2 (  
     3     (select sum(BYSJY_BYS_NUM) from T_WSTB_YJBKBYSFZYBYJYQK t   
     4      where t.BYSJY_XNZY_CODE=T_WSTB_ZYJBQK.XNZY_CODE),  
     5     0,  
     6     0,  
     7     (select sum(BYSJY_JY_NUM) from T_WSTB_YJBKBYSFZYBYJYQK t   
     8      where t.BYSJY_XNZY_CODE=T_WSTB_ZYJBQK.XNZY_CODE) * 1.0  
     9         /  
    10     (select sum(BYSJY_BYS_NUM) from T_WSTB_YJBKBYSFZYBYJYQK t   
    11      where t.BYSJY_XNZY_CODE=T_WSTB_ZYJBQK.XNZY_CODE)  
    12 ) * 100 as JYL   
    13 from T_WSTB_ZYJBQK  

    当然也可以使用前面11提到的CASE防止分母为0,即:
    round((case when ZS!=0 then SHSJ/ZS else 0 end),3) as bl

    三. 总结
    最后希望文章对你有所帮助,这是一篇我的在线笔记,同时后面结合自己实际项目和SQL性能优化,将分享一些更为专业的文章~

    2016-10-30  14:24:46

  • 相关阅读:
    互联网中的公钥与私钥
    Apache的order、allow、deny
    Linux进程中TIME_OUT解析
    no xxx find in java.library.path
    检测 USB 设备拨插的 C# 类库:USBClassLibrary
    C# 实现的异步 Socket 服务器
    javascript制作公式编辑器,函数编辑器和图形绘制
    浏览器内部工作原理
    10 款基于 jQuery 的切换效果插件推荐
    DIV焦点事件详解 --【focus和tabIndex】​
  • 原文地址:https://www.cnblogs.com/george93/p/6013080.html
Copyright © 2011-2022 走看看