1. 什么是数据库

  1. 狭义:存储数据的仓库
  2. 广义:可以对数据存储和管理的软件以及数据本身
  3. 另一说法:数据库是表、关系、操作组成

    2. 为什么需要数据库

  4. 几乎所有的应用软件的后台都需要数据库

  5. 数据库存储数据占用空间小,容易持久保存
  6. 存储比较安全
  7. 容易维护和升级
  8. 数据库移植比较容易
  9. 简化对数据的操作
  10. 为将来学Oracle做准备
  11. B/S架构里面包含数据库

    3. 数据库的安装和卸载

  12. SQL2000,解决挂起问题

  13. SQL2005,参见安装视频

    4. 预备知识

    4.1 学习数据库必须先学习数据库原理

    是,所以视频会讲解

    4.2 学习SQL2005必须先学习一门编程语言吗

    不需要,但是懂会有助于学习SQL2005中的TL_SQL

    4.3 数据结构和数据库的区别

    1. 数据库是在应用软件级别研究数据的存储和操作—外层、硬盘
    2. 数据机构是在系统软件级别研究数据的存储和操作—内层

      4.4 什么是连接

      前台客户端和后台数据库的纽带

      4.5 有了编程语言为什么还需要数据库

    3. 对内存数据操作时是编程语言的强项,但对硬盘数据操作时是编程语言的弱项

    4. 对硬盘数据操作却是数据库的强项,是数据库研究的核心问题

      4.6 建议初学者从三个方面学习数据库

    5. 数据库是如何存储数据的

      1. 了解字段、记录、表、
      2. 知道约束(主键、外键、维一键、非空、check、default、触发器)
    6. 数据库是如何操作数据的
      1. 明白指令(insert、update、delete、TL_SQL)
      2. 掌握储存过程、函数、触发器
    7. 数据库是如果显示数据的

      1. 熟练应用select(重点中的重点)

        5. 必备的一些操作

        5.1 如何建立数据库

    8. 了解数据库:后缀mdf是数据文件,后缀ldf是日志文件

    9. 系统数据库:默认4个库,不要增删改查,放置不动即可
    10. 选中数据库,右键新建数据库,赋予名字,点击确定即可

      5.2 如果删除数据库

      选中数据库,右键删除数据库,DATA文件夹中mdf和ldf文件一并删除

      5.3 如果附加和分离数据库

    11. 选中需要分离的数据库,右键任务-分离,勾选删除连接、更新数据信息后确定

    12. 选中数据库,右键附加,添加在DATA中找到分离的mdf文件,确定即可

      5.4 如何登陆用户名和命名

      5.5 如何创建用户

      6. 数据库是如何解决数据存储问题的

      6.1 表的相关数据

      6.1.1 字段

      模拟一个事物的某一个静态特征

      6.1.2 记录

      字段的组合,表示的是一个具体的事物

      6.1.3 表

      记录的组合,表示的是同一类型事物的集合

      6.1.4 表、字段和记录的关系

      字段是事物的属性,记录是事务本身,表是事务的集合

      6.1.5 列

      字段的另一张称谓

      6.1.6 属性

      字段的另一张称谓

      6.1.7 元祖

      记录的另一张称谓

      6.2 学会create table命令

      6.2.1 利用对象资源管理器新建表

      6.2.2 利用命令新建表

      说明:最后一个字段的后面建议不要写逗号

      6.2.2.1 创建一个dept表并赋值查询

      —创建表
      USE scott
      CREATE TABLE dept
      (
      deptno INT PRIMARY KEY
      ,dname NVARCHAR(20) NOT NULL
      ,loc NVARCHAR(50)
      );
      —赋值并查询
      INSERT INTO dept (deptno,dname,loc) VALUES
      (10,Accounting,NewYork)
      ,(20,Research,Dallas)
      ,(30,Sales,Chicago)
      ,(40,Operations,Boston)
      ,(50,Advertisement,BeiJing);
      SELECT * FROM dept;

      6.2.2.2 创建一个emp表并赋值查询

      —创建表
      USE scott
      CREATE TABLE emp
      (
      empno INT CONSTRAINT pk_emp_empno PRIMARY KEY
      ,ename NVARCHAR(20) NOT NULL
      ,iob NVARCHAR(20) NOT NULL
      ,mgr INT
      ,hiredate DATETIME NOT NULL
      ,sal INT NOT NULL
      ,comm INT
      ,deptno INT CONSTRAINT fk_dept_deptno FOREIGN KEY REFERENCES dept(deptno)
      );
      —赋值并查询
      INSERT INTO emp (empno,ename,iob,mgr,hiredate,sal,comm,deptno) VALUES
      (7369,SMITH,CLERK,7902,1981-12-17,800,NULL,20)
      ,(7499,ALLEN,SALESMAN,7698,1981-02-20,1600,300,30)
      ,(7521,WARD,SALESMAN,7698,1981-02-22,1250,500,30)
      ,(7566,JONES,MANAGER,7839,1981-04-02,2975,NULL,20)
      ,(7654,MARTIN,SALESMAN,7698,1981-09-28,1250,1400,30)
      ,(7698,BLAKE,MANAGER,7839,1981-05-01,2850,NULL,30)
      ,(7782,CLARK,MANAGER,7839,1981-06-09,2450,NULL,10)
      ,(7788,SCOTT,ANALYST,7655,1981-04-19,3000,NULL,20)
      ,(7839,KING,PRESIDENT,NULL,1981-11-17,5000,NULL,10)
      ,(7844,TURNER,SALESMAN,7698,1981-09-08,1500,0,30)
      ,(7876,ADAMS,CLERK,7788,1987-05-23,1100,NULL,20)
      ,(7900,JAMES,CLERK,7698,1981-12-03,950,NULL,30)
      ,(7902,FIRD,ANALYST,7566,1982-12-03,3000,NULL,10)
      ,(7934,MILLER,CLERK,7782,1982-01-23,1300,NULL,10);
      SELECT * FROM emp;

      6.2.2.3 创建一个salgrade表并赋值查询

      —创建表
      USE scott
      CREATE TABLE salgrade
      (
      grade INT CONSTRAINT pk_salgrade_grade PRIMARY KEY
      ,losal INT NOT NULL
      ,hisal INT NOT NULL
      );
      —赋值并查询
      INSERT INTO salgrade (grade,losal,hisal) VALUES
      (1,700,1200)
      ,(2,1201,1400)
      ,(3,1401,2000)
      ,(4,2001,3000)
      ,(5,3001,9999);
      SELECT * FROM salgrade;

      6.2.2.4 创建一个班级表

      CREATE TABLE banji
      (
      banji_id INT PRIMARY KEY
      ,banji_num INT NOT NULL
      ,banji_name NVARCHAR(100)
      )

      6.2.2.5 创建一个教师表

      CREATE TABLE jiaoshi
      (
      jiaoshi_id INT PRIMARY KEY
      ,jiaoshi_name NVARCHAR(100)
      )

      6.2.2.6 第三张表,用来模拟班级和教师的关系

      CREATE TABLE banji_jiaoshi_mapping
      (
      banji_id INT CONSTRAINT fk_banji_id FOREIGN KEY REFERENCES banji(banji_id)
      ,jiaoshi_id INT CONSTRAINT fk_jiaoshi_id FOREIGN KEY REFERENCES jiaoshi(jiaoshi_id)
      ,kecheng NVARCHAR(50)
      ,CONSTRAINT pk_banji_id_jiaoshi_id PRIMARY KEY (banji_id,jiaoshi_id,kecheng)
      )

      6.3 什么是约束

    13. 定义:对一个表中的字段操作的限制

    14. 分类:

      1. 主键约束:不允许重复元素,避免数据冗余;实体完整性
      2. 外键约束:保证了本事物所关联的其他事务一定是存在的;引用完整性
      3. check约束:保证事物属性的取值在合法的范围之内(emp_sal INT CHECK(emp_sal>=1000 AND emp_sal<=8000) )
      4. default约束:保证事物的属性一定有一个值(emp_sex NCHAR(1) DEFAULT (‘男’)—()可以省略)
      5. 唯一约束:保证事物属性的取值不允许重复,但允许其中有一列且仅有一列为空(emp_name NVARCHAR(20) UNIQUE NOT NULL)
      6. NOT NULL约束:要求用户必须为该属性赋一个值,否则语法出错

        6.4 表和约束的区别

    15. 数据库是通过表来解决事物的存储的问题

    16. 数据库是通过约束来解决事物取值的有效性和合法性的问题
    17. 建表的过程就是指定事物属性及其事物属性各种约束的过程

      6.5 什么是关系

    18. 定义:模拟表和表之间的联系

    19. 实现方式:通过设置不同形式的外键来体现表和表之间的不同关系
    20. 分类(假设是A表和B表):

      1. 一对一:既可以把表A的主键充当表B的外键,也可以把表B的主键充当表A的外键
      2. 一对多:把表A(一)的主键充当表B(多)的外键,或者是多的一方B表来添加外键
      3. 多对多:需要通过第三个表关联表A和表B的关系,表A和表B的主键做为第三个表的外键(比如班级是一个表,教师是一个表,班级和教师的关系也需要一张表)

        6.6 主键

    21. 定义:能够维一标示一个事物的一个字段或者多个字段的组合。

    22. 附注:

      1. 含有主键的表叫做主键表
      2. 主键通常都是整数,不建议用字符串(如果主键用于集群式服务,才可以考虑用字符串当主键)
      3. 主键的值通常都不允许修改,除非本记录被删除
      4. 主键不能为空值,
      5. 主键不要定义成id,而要定义成表名Id或是表名_id
      6. 主键一般用代理主键(一般是单独添加一个整型编号当主键字段),不要用业务主键
      7. IDENTITY标识列,主键自动增长,用户不需要为IDENTITY修饰的主键赋值
      8. IDENTITY(m, n) m表示初始值,n表示每次自动增加的值,m和n要么同时指定,要不都不指定
      9. IDENTITY(m, n) m和n若指定,默认值是(1,1)
      10. 数据类型是整型的列才能被定义成标识列,通常与PRIMARY KEY一起用作表的维一标识符
      11. 非主键也可以被定义成IDENTITY,但不推荐

        6.7 外键

    23. 定义:如果一个表中的若干个字段是来源于另外若干个表的主键,则若这干个字段就叫外键

    24. 附注:

      1. 外键是联系一个表和另一个表,体现事务与事务质检的关系
      2. 外键通常来自另外表的主键而不是唯一键,因为唯一键可能为NULL
      3. 含有外键的表交外键表,外键字段来自的哪一张表叫做主键表
      4. 如果要删除表,先删外检表再删主键表,若先删主键表会报错(导致外键表中的数据引用失败)

        6.8 查询【最重要,难度最大】

        6.8.1 计算列

        a. 事例:SELECT sal*12 AS “年薪” FROM emp;
        b. 注意:别名只能用双引号,不能用单引号括起来
        c. 概况:看懂一个程序分三步,第一步流程(执行语句先后顺序),第二步语句功能,最后找表实验一下

        6.8.2 distinct【不允许重复的】

        a. 事例:SELECT DISTINCT deptno FROM emp;—过滤掉重复的部门编号,只保留有区别的部门编号
        SELECT DISTINCT comm FROM emp;—去重后的奖金明细,若有多个NULL和0,只保留一个
        SELECT DISTINCT deptno,comm FROM emp;—将部门编号和奖金组合进行过滤
        SELECT deptno,DISTINCT comm FROM emp;—error,逻辑上有冲突

        6.8.3 between【在某个范围】

        a. 事例:SELECT FROM emp WHERE sal >= 1500 AND sal <= 3000; 等价于
        SELECT
        FROM emp WHERE sal BETWEEN 1500 AND 3000;—工资在1500到3000的员工的所有信息
        SELECT FROM emp WHERE sal < 1500 OR sal > 3000;—工资小于1500或大于3000的员工所有信息
        SELECT
        FROM emp WHERE sal NOT BETWEEN 1500 AND 3000; 等价于以上筛选

        6.8.4 in【属于若干个孤立的值】

        a. 事例:SELECT FROM emp WHERE sal IN (1500,3000);—工资是1500或是工资是3000的员工的所有信息
        SELECT
        FROM emp WHERE sal = 1500 OR sal = 3000; 等价于以上筛选
        SELECT FROM emp WHERE sal NOT IN (1500,3000);—工资即不是1500也不是3000的员工信息
        SELECT
        FROM emp WHERE sal <> 1500 AND sal <> 3000; 等价于以上筛选
        b. 说明:数据库中不等于有两种表达方式:!=、<> 推荐使用第二种
        对或取反是并且,对并且取反是或

        6.8.5 top【最前面的若干个记录】

        a. 事例:SELECT TOP 2 FROM emp;—查询员工表前两行的所有信息
        SELECT
        FROM emp WHERE ROWNUM < 3;—Oracle中查询员工表前两行的所有信息
        SELECT TOP 15 PERCENT FROM emp;—查询全部记录15%行的所有员工信息(有小数增加一条记录)
        SELECT TOP 4
        FROM emp WHERE sal BETWEEN 1500 AND 3000 ORDER BY sal DESC;
        —查询工资在1500到3000之间(包括1500和3000)的员工中工资最高的按降序排序的员工信息
        b. 说明:分页查询后边还会详细介绍

        6.8.6 null【没有值或是空值】

        a. 事例:SELECT FROM emp WHERE comm IS NULL;—查询奖金为空的所有员工的信息
        SELECT
        FROM emp WHERE comm IS NOT NULL;—查询奖金不为空的所有员工的信息
        SELECT ename,sal12+comm AS “年薪” FROM emp;—error
        SELECT
        ,sal*12+ISNULL(comm,0) AS “年薪” FROM emp;—查询员工的年薪等所有信息
        b. 说明:NULL不能参与<>、!=、=的运算,可以参与is、not is的运算
        NULL和0是不一样的,NULL表示空值、没有值,0表示一个确定的值
        NULL不能参与任何数学运算,否则结果只能为NULL
        ISNULL(comm,0)—如果comm是NULL,就返回0,否则返回comm
        任何类型的数据都允许为NULL

        6.8.7 order by【以某个字段排序】

        a. 事例:SELECT FROM emp ORDER BY sal;—查询所有的员工信息,按工资升序排序
        SELECT
        FROM emp ORDER BY deptno,sal;—查询所有员工信息,先按部门升序,再按工资升序
        SELECT * FROM emp ORDER BY deptno desc,sal;—查询所有员工信息,先部门降序,再工资升序
        b.说明:ORDER BY a,b —a,b都是升序
        ORDER BY a ,b DESC —a升序,b降序
        ORDER BY a DESC,b —a降序,b升序
        ORDER BY a DESC,b DESC —a降序,b降序
        asc是升序,默认可以不写,desc是降序
        为一个字段指定的排序标准并不会对另一个字段产生影响
        强烈建议为每一个字段指定排序的标准

        6.8.8 模糊查询【某个字段中含某个字符,搜索时使用】

        a. 格式:SELECT 字段的集合 FROM 表名 WHERE 某个字段的名字 LIKE 匹配的条件
        b. 事例:SELECT FROM emp WHERE ename LIKE ‘%A%’;—查询名字中含有字母A的所有的员工的信息
        SELECT
        FROM emp WHERE ename LIKE ‘A%’;—查询名字中首字母是A的所有的员工的信息
        SELECT FROM emp WHERE ename LIKE ‘%S’;—查询名字中尾字母是S的所有的员工的信息
        SELECT
        FROM emp WHERE ename LIKE ‘A%’;—查询名字中第二个字母是A的所有员工信息
        SELECT * FROM emp WHERE ename LIKE ‘
        [A-C]%’;—名字中第二个字母是A或B或C的员工信息
        SELECT FROM emp WHERE ename LIKE ‘_[^A-B]%’;—名字第二个字母不是A也不是B的员工信息
        SELECT
        FROM emp WHERE ename LIKE ‘%\%%’ ESCAPE ‘\’;—查询名字中含有符号%的员工信息
        SELECT * FROM emp WHERE ename LIKE ‘%_%’ ESCAPE ‘\’;—查询名字中含有符号的员工信息
        c. 说明:匹配的条件通常含有通配符
        匹配的条件必须用单引号括起来,不能省略,也不能用双引号
        通配符:% —表示任意0个或多个字符
        —表示任意单个字符
        [a-f] —a到f中的任意单个字符
        [a,f] —a或f中的任意单个字符
        [^a-c] —不是a、b、c中的任意单个字符
        其他符号:与(&)、非(~)、或(|)、异或(^)、转义字符()

        6.8.9 聚合函数【多行记录返回一个值,结合分组使用,不分组默认整体】

        a. 函数分类:单行函数:每一行返回一个值,比如LOWER()是单行函数
        多行函数:多行返回一个值,比如MAX()是多行函数(聚合函数属于多行函数)
        b. 聚合函数分类:MAX() —最大值
        MIN() —最小值
        AVG() —平均值
        COUNT() —求个数
        c. 事例:SELECT LOWER(ename) AS “小写姓名” FROM emp;—将员工名称字母转换成小写的并查询
        SELECT UPPER(ename) AS “大写姓名” FROM emp;—将员工名称字母转换成大写的并查询
        SELECT MAX(sal) AS “最多工资” FROM emp;—查询员工表中的最多工资
        SELECT COUNT() AS “个数” FROM emp;—查询员工信息表中的所有记录的个数,返回值是14
        SELECT COUNT(deptno) AS “部门个数” FROM emp;—查询员工信息表中的部门个数,返回值是14
        SELECT COUNT(DISTINCT deptno) FROM emp;—查询员工信息表中的不同的部门个数,返回值是3
        SELECT COUNT(comm) FROM emp;—查询员工奖金的个数,返回值是4,NULL值不会被统计
        SELECT MAX(sal) AS “最高工资”,MIN(sal) AS “最低工资”,COUNT(
        ) AS “员工数” FROM emp;
        d. 说明:COUNT(*) —返回表中所有记录的个数
        COUNT(字段名) —返回字段值非空的记录的个数,重复的记录也会被当做有效数据统计
        COUNT(DISTINCT 字段名) —返回字段不重复并且非空的记录的个数
        单行函数和多行函数不能混用

        6.8.10 group by【对表中记录按字段分组】

        a. 格式:GROUP BY 字段的集合
        b. 事例:SELECT deptno, AVG(sal) AS “平均工资” FROM emp GROUP BY deptno;—查询部门及其平均工资
        SELECT deptno, job, AVG(sal) AS “平均工资” FROM emp GROUP BY deptno, job ORDER BY deptno;
        —查询部门职业的平均工资,按部门分组
        c. 说明:使用了GROUP BY,则SELECT中只能出现分组后的整体信息,不能出现组内的详细信息
        GROUP BY a, b, c—先按a分组,若a相同按b分组,若b相同再按c分组,最终统计最小分组的信息

        6.8.11 having【对分组后的信息进行过滤】

        a. 事例:SELECT deptno, AVG(sal) AS “平均工资”
        FROM emp
        GROUP BY deptno
        HAVING AVG(sal) > 2000;
        —查询部门平均工资大于2000的部门编号及部门平均工资
        SELECT deptno, AVG(sal) AS “平均工资”
        FROM emp
        WHERE ename NOT LIKE ‘&A%’
        GROUP BY deptno
        HAVING AVG(sal) > 2000;
        —查询名字中不包含字母A的人员部门且部门平均工资大于2000的部门编号及平均工资
        SELECT deptno, AVG(sal) AS “平均工资”, COUNT(*) AS “部门人数”
        FROM emp
        WHERE sal > 1000
        GROUP BY deptno
        HAVING AVG(sal) > 2000;
        —查询工资大于1000且平均工资大约2000的部门编号,部门平均工资和部门人数
        b. 说明:

      5. SELECT语句基本结构包含8个子句,且这些子句的顺序是固定的,否则编译时出错

      6. SELECT语句基本结构:SELECT TOP 数字 字段名

INTO 表C —将查询结果定义到一个新表
FROM 表A
JOIN 表B
ON A、B表连接条件
WHERE 条件
GROUP BY 分组
HAVING 分组后过滤
ORDER BY 分组后排序

  1. 1. WHEREHAVING都是对数据过滤,只保留有效的数据,且子句中都不允许出现别名
  2. 1. WHERE是对原始的记录过滤,HAVING是对分组后的记录过滤,且WHERE必须放到HAVING前边
  3. 1. HAVING子句是用来对分组之后的数据进行过滤,因此使用HAVING时通常先使用GROUP BY子句
  4. 1. 若果没使用GROUP BY子句,但使用了HAVING,意味着HAVING把所有的记录当成一组进行过滤
  5. 1. HAVING子句出现的字段必须是分组之后组内的整体信息,不能是组内的详细信息
  6. 1. 尽管SELECT子句中可以出现别名,但是HAVING子句中不能出现,只能使用原始的字段名称

6.8.12 连接查询

6.8.12.1 定义:

将两个或两个以上的表按一定条件连接起来,从中检索出满足条件的数据

6.8.12.2 分类:

6.8.12.2.1 内连接【重难点】

  1. 1. SELECT ··· FROM A, B 的用法
  2. 1. 事例:SELECT * FROM emp, dept;--查询员工和部门表的所有字段
  3. 1. 说明:emp148列,dept53列,查询结果是7014*5)行118+3)列(笛卡尔积)
  4. 2. SELECT ··· FROM A, B WHERE ··· 的用法
  5. 1. 事例:SELECT * FROM emp, dept WHERE empno = 7369;--查询员工编号是7369的所有信息
  6. 1. 说明:查询结果是511
  7. 3. SELECT ··· FROM A JOIN B ON ··· 的用法
  8. 1. 事例:SELECT "E".ename AS "员工姓名", "D".dname AS "部门名称"

FROM emp “E”
JOIN dept “D” —JOIN是连接
ON “E”.deptno = “D”.deptno; —ON是连接条件
—查询员工表中的员工姓名和部门表中的部门名称
2.说明:查询结果是14行2列。JOIN必须和ON配套使用,有JOIN必要有ON
iv.SELECT ··· FROM A, B WHERE ··· 与 SELECT ··· FROM A JOIN B ON ··· 的比较

  1. 1. 事例:SELECT * FROM emp, dept WHERE emp.deptno = dept.deptno;等价于

SELECT * FROM emp JOIN dept ON emp.deptno = dept.deptno;—查询结果14行11列
—查询工资大于2000的员工姓名和部门的名称
SQL92实现方式 SQL99实现方式
SELECT “E”.ename, “D”.dname SELECT “E”.ename, “D”.dname
FROM emp “E”,dept “D” FROM emp “E”
WHERE “E”.sal > 2000 JOIN dept “D”
AND “E”.deptno = “D”.deptno; ON “E”.deptno = “D”.deptno
WHERE “E”.sal > 2000;
2.说明:第一个是SQL92标准,第二个是SQL99标准,推荐使用SQL99标准。 因为ON和WHERE可以做不同分工,ON指定连接条件, WHERE对连接之后的临时表的数据进行分析。
v. SELECT、FROM、WHERE、JOIN、ON、GROUP BY、ORDER BY、TOP、HAVING的混合使用

  1. 1. 事例:--把工资大约1500的所有员工,按部门分组,把部门平均工资大于2000的前2个部门的部门编号、部门名称、部门平均工资的等级输出,按等级降序排序

SELECT “T”.*, “S”.grade
FROM(
SELECT TOP 2 “E”.deptno, “D”.dname, AVG(“E”.sal) AS “avg_sal”
FROM emp “E”
JOIN dept “D”
ON “E”.deptno = “D”.deptno
JOIN salgrade “S”
ON “E”.sal BETWEEN “S”.losal AND “S”.hisal
WHERE “E”.sal > 1500
GROUP BY “E”.deptno, “D”.dname
HAVING AVG(“E”.sal) > 2000
ORDER BY AVG(“E”.sal) DESC
) “T”
JOIN salgrade “S”
ON “T”.”avg_sal” BETWEEN “S”.losal AND “S”.hisal;
等价于:
SELECT “T”.deptno, “D”.dname, “T”.”avg_sal”, “S”.grade
FROM dept “D”
JOIN (
SELECT TOP 2 deptno, AVG(sal) AS “avg_sal”
FROM emp
WHERE sal > 1500
GROUP BY deptno
HAVING AVG(sal) > 2000
ORDER BY “avg_sal” DESC
) “T”
ON “D”.deptno= “T”.deptno
JOIN salgrade “S”
ON “T”.”avg_sal” BETWEEN “S”.losal AND “S”.hisal;
vi. 习题:

  1. 1. --求出工资比2000大的每个部门的员工姓名、部门名称、薪水和薪水的等级

SELECT “E”.ename, “D”.dname, “E”.sal, “S”.grade
FROM emp “E”
JOIN dept “D”
ON “E”.deptno = “D”.deptno
JOIN salgrade “S”
ON “E”.sal >= “S”.losal AND “E”.sal <= “S”.hisal;
2.—求出每个员工的姓名,部门编号,薪水和薪水登记
SELECT “E”.ename, “E”.deptno, “E”.sal, “S”.grade
FROM emp “E”
JOIN salgrade “S”
ON “E”.sal >= “S”.losal AND “E”.sal <= “S”.hisal;
等价于
SELECT emp.ename, emp.deptno, emp.sal, salgrade.grade
FROM emp
JOIN salgrade
ON emp.sal BETWEEN salgrade.losal AND salgrade.hisal;
3.—查找每个部门的部门编号,该部门所有员工的平均工资及平均工资等级
SELECT “T”.deptno, “T”.avg_sal, “S”.grade
FROM (
SELECT deptno, AVG(sal) AS “avg_sal”
FROM emp
GROUP BY deptno
) “T”
JOIN salgrade “S”
ON “T”.avg_sal BETWEEN “S”.losal AND “S”.hisal;
—等价于
SELECT “T”., “S”.grade
FROM salgrade “S”
JOIN (
SELECT deptno, AVG(sal) AS “avg_sal”
FROM emp
GROUP BY deptno
) “T”
ON “T”.avg_sal BETWEEN “S”.losal AND “S”.hisal;
—等价于
SELECT “T”.deptno, “T”.avg_sal, “S”.grade
FROM salgrade “S”, (
SELECT deptno, AVG(sal) AS “avg_sal”
FROM emp
GROUP BY deptno
) “T”
WHERE “T”.avg_sal BETWEEN “S”.losal AND “S”.hisal;
4.—查找每个部门的编号,部门名称,该部门所有员工的平均工资及平均工资等级
SELECT “T”.deptno, “D”.dname, “T”.avg_sal, “S”.grade
FROM (
SELECT deptno, AVG(sal) AS “avg_sal”
FROM emp
GROUP BY deptno
) “T”
JOIN salgrade “S”
ON “T”.avg_sal BETWEEN “S”.losal AND “S”.hisal
JOIN dept “D”
ON “T”.deptno = “D”.deptno;
5.—查出emp表中所有领导的所有信息
SELECT
FROM emp
WHERE empno IN (SELECT mgr FROM emp);—6行
6.—查出emp表中所有非领导的所有信息
SELECT FROM emp
WHERE empno NOT IN (SELECT mgr FROM emp);—error(mgr中有NULL)
SELECT
FROM emp
WHERE empno NOT IN (SELECT mgr FROM emp WHERE mgr IS NOT NULL);—8行
7.—求出平均薪水最高的部门的编号和部门的平均工资
SELECT TOP 1 deptno, AVG(sal) AS “avg_sal”
FROM emp
GROUP BY deptno
ORDER BY AVG(sal) DESC;
—等价于
SELECT “E”.
FROM(
SELECT deptno, AVG(sal) AS “avg_sal”
FROM emp
GROUP BY deptno
) “E”
WHERE “E”.”avg_sal” =
(
SELECT MAX(“avg_sal” )
FROM (
SELECT deptno, AVG(sal) AS “avg_sal”
FROM emp
GROUP BY deptno
) “T”
);
8.—把工资最低员工排除后工资最低的前三人的姓名、工资、部门编号、部门名称、工资等级
SELECT TOP 3 “T”.ename, “T”.sal, “T”.deptno, “D”.dname, “S”.grade
FROM(
SELECT

FROM emp “E”
WHERE sal > (SELECT MIN(sal) FROM emp)
) “T”
JOIN dept “D”
ON “T”.deptno = “D”.deptno
JOIN salgrade “S”
ON “T”.sal BETWEEN “S”.losal AND “S”.hisal
ORDER BY “T”.sal ASC;
—等价于
SELECT TOP 3 “E”.ename, “E”.sal, “E”.deptno, “D”.dname, “S”.grade
FROM emp “E”
JOIN dept “D”
ON “E”.deptno = “D”.deptno
JOIN salgrade “S”
ON “E”.sal BETWEEN “S”.losal AND “S”.hisal
WHERE “E”.sal <> (SELECT MIN(sal) FROM emp)
ORDER BY “E”.sal ASC;
9.—输出姓名名称中不包含字母A的工资最高的前三名的员工的姓名,工资,工资等级和部门名称
SELECT TOP 3 “E”.ename, “E”.sal, “S”.grade, “D”.dname
FROM emp “E”
JOIN dept “D”
ON “E”.deptno = “D”.deptno
JOIN salgrade “S”
ON “E”.sal BETWEEN “S”.losal AND “S”.hisal
WHERE “E”.ename NOT LIKE ‘%A%’
ORDER BY “E”.sal DESC;
—等价于
SELECT TOP 3 T0.ename, T0.sal, T1.grade, T2.dname
FROM emp T0
JOIN salgrade T1
ON T0.sal BETWEEN T1.losal AND T1.hisal
JOIN dept T2
ON T0.deptno = T2.deptno
WHERE T0.ename NOT LIKE ‘%A%’
ORDER BY sal DESC;

6.8.12.2.2 外连接

  1. 1. 格式:LEFT JOINRIGHT JOIN

6.8.12.2.3 完全连接

  1. 1. 格式:FULL JOIN

6.8.12.2.4 交叉连接

  1. 1. 格式:CROSS JOIN

6.8.12.2.5 自连接

  1. 1. 定义:一张表自己和自己连接起来查询数据
  2. 1. 事例:--求薪水最高的员工信息

—自连接查询
SELECT FROM emp
WHERE empno NOT IN (
SELECT DISTINCT T0.empno
FROM emp T0, emp T1
WHERE T0.sal < T1.sal
);
—嵌套查询
SELECT
FROM emp
WHERE sal =(
SELECT TOP 1 sal
FROM emp
ORDER BY sal DESC
);
—聚合函数查询
SELECT * FROM emp WHERE sal = (SELECT MAX(sal) FROM emp);

6.8.12.2.6 联合【UNION】

  1. 1. 定义:表和表之间的数据以纵向的方式连接在一起
  2. 1. 事例:--输出每个员工的姓名,工资和上司的姓名

SELECT “E1”.ename, “E1”.sal, “E2”.ename AS “上司的姓名”
FROM emp “E1”
JOIN emp “E2”
ON “E1”.mgr = “E2”.empno
UNION
SELECT ename, sal, ‘已是最大BOSS’
FROM emp
WHERE mgr IS NULL
UNION
SELECT ename, sal, ‘未找到上司姓名’
FROM emp
WHERE mgr NOT IN (SELECT empno FROM emp);
iii. 说明:之前讲的连接都是横向连接,UNION联合是纵向连接
若干个SELECT子句要联合成功的话,需要满足两个条件:

  1. 1. 若干个SELECT子句输出的数据列数必须是相同的
  2. 1. 若干个SELECT子句输出的数据类型应该是兼容的

6.8.13 嵌套查询(oracle中讲)

6.8.14 分页查询

  1. 事例:—输出工资最高的前三个员工的所有信息

    SELECT TOP 3 FROM emp ORDER BY sal;—先执行ORDER BY ,再执行TOP
    —工资从高到底排序,输出工资是低4-6的员工的信息
    SELECT TOP 3
    FROM emp
    WHERE empno NOT IN (SELECT TOP 3 empno FROM emp ORDER BY sal DESC)
    ORDER BY sal DESC;
    —工资从高到底排序,输 出工资是低7-9的员工的信息
    SELECT TOP 3 FROM emp
    WHERE empno NOT IN (SELECT TOP 6 empno FROM emp ORDER BY sal DESC)
    ORDER BY sal DESC;
    —工资从高到底排序,输出工资是低10-12的员工的信息
    SELECT TOP 3
    FROM emp
    WHERE empno NOT IN (SELECT TOP 9 empno FROM emp ORDER BY sal DESC)
    ORDER BY sal DESC;
    —工资从高到底排序,输出工资是低13-15的员工的信息
    SELECT TOP 3 * FROM emp
    WHERE empno NOT IN (SELECT TOP 12 empno FROM emp ORDER BY sal DESC)
    ORDER BY sal DESC;

  2. 总结:—假设每页显示n条记录,当前要显示的是第m页,表名是A,主键是A_id

    SELECT TOP n FROM A
    WHERE A_id NOT IN (SELECT TOP (m-1)
    n A_id FROM emp);

    6.9 视图

    6.9.1 为什么需要视图
    简化查询,避免代码的冗余(避免书写重复的SQL语句)
    6.9.2 什么是视图
    视图从代码看是一个SELECT语句,从逻辑上看被当做一个虚拟表
    6.9.3 视图的格式

  3. 格式:CREATE VIEW v$_视图名称 AS SELECT 语句

  4. 说明:SELECT 语句的前面不能添加BEGIN,SELECT 语句的后面不能添

    6.9.4 视图的优点
    简化查询,争取数据的保密性
    6.9.5 视图的缺点
    增加了数据库维护的成本,简化了查询
    不能加快查询的速度

    6.10 事务

  5. 定义:一系列操作,要不全部执行成功,要么全部执行失败

  6. 特征:原子性、一致性、隔离性、持久性
  7. 事务是用来研究什么的:避免数据处于不合理的中间地带、转账
  8. 事务和线程关系:事务也是通过锁来解决很多问题的,线程同步就是通过锁来解决问题的
  9. 事务和第三方的关系:直接使用事务库的难度很大,一般是借用第三方的插件实现的