MySQL数据库

来源:互联网 发布:无敌淘宝王全文免费 编辑:程序博客网 时间:2024/04/28 07:49

一、数据库概念

   1、什么是数据库?

      数据库就是用来存储和管理数据的仓库。

      数据库存储数据的优点:

  • 可存储大量数据;
  • 方便检索;
  • 保持数据的一致性、完整性;
  • 安全,可共享;
  • 通过组合分析,可产生新数据。

   2、数据库的发展历程

  • 没有数据库,使用磁盘文件存储数据;
  • 层次结构模型数据库;
  • 网状结构模型数据库;
  • 关系结构模型数据库,使用二维表格来存储数据;
  • 关系-对象模型数据库;

      MySQL就是关系型数据库。

   3、常见数据库

  • Oracle:甲骨文(最高)
  • DB2:IBM
  • SQL Server:微软
  • Sybase:赛尔斯
  • MySQL:甲骨文

   4、理解数据库

  • RDBMS = Manager(管理员) + Database(仓库);
  • database = N个table;
  • table = 表结构(定义表的列名和列类型) + 表记录(一行一行的记录);

      我们现在所说的数据库,泛指 " 关系型数据库管理系统(RDBMS - Relational DataBase Management System) " ,即数据库服务器。

      当我们安装了数据库服务器后,就可以在数据库服务器中创建数据库,每个数据库中还可以多张表。

      数据库表就是一个多行多列的表格,在创建表时,需要指定表的列数、以及列名称、列类型等信息,而不用指定表格的行数,行数是没有限制的。

      当表格创建好之后,就可以想表格中添加数据了,向表格添加数据是以行为单位的。

   5、应用程序与数据库

     


二、安装MySQL数据库

   1、安装MySQL:参考

   2、MySQL目录结构

      MySQL的数据存储目录为data,data的目录通常在C:\Documents and Settings\All Users\Application Data\MySQL\MySQL Server 5.1\data位置。在data下的每个目录代表一个数据库。

      MySQL的安装目录:

  • bin目录下都是可执行文件;
  • my.ini是MySQL的配置文件。

三、基本命令

   1、启动和关闭MySQL服务器

  • 启动:net  start  mysql
  • 关闭:net  stop  mysql

      在启动MySQL服务后,打开Windows任务管理器,会有一个名为mysqld.exe的进程运行,所以mysqld.exe才是MySQL服务器程序。

   2、客户端退出登陆MySQL

      在启动MySQL服务器后,我们需要使用管理员登陆MySQL服务器,然后对服务器进行操作。登陆MySQL需要使用MySQL的客户端程序mysqld.exe

  • 登陆:mysql  -u root  -p 123  -h localhost

             -u:后面的root是用户名,这里使用的是超级管理员root;

             -p:后面的123是密码,这是安装MySQL时指定的密码;

             -h:后面给出的localhost是服务器的主机名,他是可以省略的;

  • 退出:quit 或 exit;

      在登陆成功后,打开Windows任务管理程序,会有一个名为mysqld.exe的进程运行,所以mysqld.exe是客户端程序。

四、SQL语句

   (一)、SQL概述

      1、什么是SQL?

      SQL(Structured  Query  Language)是 " 结构化查询语言 " ,它是对关系型数据库的操作语言,可以应用到所有关系型数据库中,例如:MySQL、Oracle、SQL Server等。SQL标准有:
  • SQL-92:1992年发布的SQL语言标准;
  • SQL-1999:1999年发布的SQL语言标准;
  • SQL-2003:2003年发布的SQL语言标准。

      这些标准就与JDK的版本一样,在新的版本中总要有一些新的语法变化,不同时期的数据库对不同标准做了实现。

      虽然SQL可以用在所有关系型数据库中,但很多数据库还都有标准之后的语法,我们可以称之为 " 方言 " 。例如MySQL中的limit语句就是MySQL的方言,其他数据库不支持。当然Oracle或SQL Server都有自己的方言。

      2、语法要求

  • SQL语句可以单行或多行书写,以分号结尾;
  • 可以用空格和缩进来增强语句的可读性;
  • 关键字不区分大小写,建议使用大写;

   (二)、分类

  • DDL(Data  Definition  Language):数据定义语言,用来定义数据库对象:库、表、列等;
  • DML(Data  Manipulation  Language):数据操作语言,用于操作数据库记录;
  • DCL(Data  Contrl  Language):数据控制语言,用来定义访问权限和安全级别;
  • DQL(Data  Query  Language):数据查询语言,用来查询记录;

   (三)、DDL

      1、基本操作

  • 查看所有数据库名称:SHOW  DATABASES
  • 切换数据库:USE  mydb(切换到mydb数据库)

      2、操作数据库

  • 创建数据库:CREATE  DATABASE  [IF NOT EXISTS]  mydb

            例如:CREATE DATABASE mydb,创建一个mydb数据库,如果这个数据库已存在,那么会报错;

            例如:CREATE DATABASE IF NOT EXISTS mydb,在名为mydb数据库不存在时创建,这样可以避免报错。

  • 删除数据库:DROP  DATABASE  [IF  EXISTS]  mydb

            例如:DROP DATABASE mydb,删除一个mydb的数据库,如果这个数据库不存在,那么会报错;

            例如:DROP DATABASE IF EXISTS mydb,就算mydb不存在,也不会报错。

  • 修改数据库编码:ALTER  DATABASE  mydb  CHARACTER  SET  utf8

            修改mydb数据库的的编码为utf8,注意在MySQL中所有的UTF-8编码都不可以使用 " - " ,即UTF-8要写为utf8。

      3、数据类型

        MySQL与Java一样,也有数据类型,MySQL中数据类型主要应用在列上。

        常用类型:

分类

类型

M

UNSIGNED

ZEROFILL

范围

说明

 

 

 

 

 

bit

yes

no

no

1~64b

bit(2)表示2个二进制位,取值范围0~3

tinyint

yes

yes

yes

1B

标记UNSIGNED时,范围为0~255。当标记ZEROFILL时,同时表示标记了UNSIGNED。当位数不足M时,添加前导0。例如tinyint(5),当值为123时,那么会添加2个前导零,即00123

smallint

yes

yes

yes

2B

同上

mediumint

yes

yes

yes

3B

同上

int

yes

yes

yes

4B

同上

integer

yes

yes

yes

4B

int完全相同

bigint

yes

yes

yes

8B

同上

 

 

 

 

 

char

yes

no

no

255B

固定长度字符串类型。char(4),当数据长度为2时,会在后面添加2个空格补位。

varchar

yes

no

no

65535B

可变长度字符串。varchar(4),当数据长度为2时,不会添加空格补位。占3个字节,其中一个字节用来记录长度。当数据长度大于255时,记录长度就需要2个字节了。

tinytext

yes

no

no

28--1B

可变长度字符串。

text

no

no

no

216-1B

同上。

mediumtext

no

no

no

224-1B

同上。

longtext

no

no

no

232-1B

同上。

 

 

 

 

binary

yes

no

no

255B

固定长度二进制类型。binary(10),当数据为5B时,会添加5B来补位。即长度为10B

varbinary

yes 

no

no

255B

可变长度二进制类型。varbinary(10),当数据为5B时,不会补位,长度为6B,其中1B用来记录长度。

tinyblob

no

no

no

28--1B256B

可变长度二进制类型。

blob

no

no

no

216-1B64K

同上

mediumblob

no

no

no

224-1B16M

同上

longblob

no

no

no

232-1B4G

同上

 

 

 

 

float

yes

yes

yes

±3.4E38

float(5,2)表示长度为5,其中2位小数。与Javafloat精度相同!

double

yes

yes

yes

±1.79E308

同上。

numeric

yes 

yes 

yes

小数点前后有效位之和不大于65位。

使用与floatdouble相同,但存储方式不同,把9位十进制数压缩成4个字节来存储。相当与把浮点数当成字符来保存,但进行了压缩。比floatdouble更安全可靠。不会出现精度缺失的问题。

decimal

yes

yes

yes

65

MySQLdecimalnumeric是完全相同的。二者在表示钱时,很有用。

bool

no

no

no

no

表示布尔值,但真实上是使用tinyint(1)表示的。当值为0时表示假,当值为非0时表示真。-128也是真。

boolean

no

no

no

no

bool完全相同。

 


date

no

no

no

no

yyyy-mm-dd

datetime

no

no

no

no

yyyy-mm-dd hh:mm:ss

timestamp

yes

no

no

no

时间戳,用在记录插入与更新自动记录时间。

year

yes

no

no

no

year(2),表示两位的年

time

no

no

no

no

只表示时间


       4、操作表

  • 创建表:CREATE  TABLE  表名(列名  列类型,列名  列类型,...);
  • 查看当前数据库所有表名称:SHOW  TABLES;
  • 查看指定表的创建语句:SHOW  CREATE  TABLE  emp;
  • 查看表结构:DESC  emp;
  • 删除表:DROP  TABLE  emp;
  • 修改表

             【1】添加列:ALTER  TABLE  stu  ADD(classname  varchar(100));

             【2】修改列类型:ALTER  TABLE stu  MODIFY  gender  char(2);

             【3】修改列名:ALTER  TABLE  stu  CHANGE  gender  sex char(2);

             【4】删除列:ALTER  TABLE  stu  DROP  classname;

             【5】修改表名称:ALTER  TABLE  stu  RENAME TO student;


   (四)、DML

      1、插入数据

  • 语法1:INSERT  INTO  表名(列名1,列名2,...)VALUES(值1,值2,...)
  • 语法2:INSERT  INTO  表名  VALUES(值1,值2,...),因为没有表示插入的列,表示按照创建表时的顺序插入

        注意:所有字符串数据必须使用单引用。

      2、修改数据

  • 语法:UPDATE  表名  SET  列名1=值1,...  [ WHERE  条件 ]

      3、删除数据

  • 语法1:DELETE  FROM  表名  [ WHERE 条件 ]
  • 语法2:TRUNCATETABLE  表名

        虽然TRUNCATE和DELETE都可以删除表的所有记录,但是原理不同,DELETE效率没有TRUNCATE高。

        TRUNCATE其实属于DDL语句,因为他是先DROP  TABLE,再CREATE  TABLE,而且TRUNCATE删除的记录是无法回滚的,但DELETE删除的记录是可以回滚的。

   (五)、DCL

      1、创建用户

  • 语法:CREATE USER  用户名@地址  IDENTIFIED  BY  ' 密码 '

      2、给用户授权

  • 语法:GRANT  权限1,权限2,...  ON  数据库 . *  TO  用户名

      3、撤销权限

  • 语法:REVOKE  权限1,权限2,...  ON  数据库 . *  FROM  用户名

      4、查看用户权限

  • 语法:SHOW  GRANKS  FOR  用户名

      5、删除用户

  • 语法:DROP  USER  用户名

      6、修改用户密码

  • 语法:USE  mydb;

                         UPDATE  USER  SET  PASSWORD=PASSWORD( ' 密码 ' )  WHERE  User= ' 用户名 ' AND  Host= ' IP ' ;

                         FLUSH  PRIVILEGES;


五、数据查询语法(DQL)


   DQL就是数据查询语法,数据库执行DQL语句不会对数据进行改变,而是让数据库发送结果集给客户端。

   语法:

              SELECT  列名称

              FROM  表名称

              WHERE  条件

              GROUP  BY  结果分组

              HAVING  分组后的条件

              ORDER  BY  排序

              LIMIT  对结果限定


   1、基础查询

  • 查询所有列:SELECT  *  FROM  stu
  • 查询指定列:SELECT  name ,age  FROM  stu

   2、条件查询

       条件查询就是在查询时给出WHERE子句,在WHERE子句中可以使用如下运算符及关键字:

  • 运算符:=、!=、<>(相当于!=)、>、<>=、<=
  • BETWEEN ... AND ...
  • IN
  • IS  NULL
  • AND
  • OR
  • NOT

   3、模糊查询

       当想查询姓名中带a字母的学生,需要用到模糊查询,模糊查询需要使用关键字LIKE。

  • " _ " 表示匹配任意一个字母;
  • " % " 表示匹配0~n个任意字母;

   4、字段控制查询

  • 去除重复记录:SELECT  DISTINCT  sal  FROM  emp
             两行或两行以上记录中,列上的数据都相同。
  • 求和:SELECT  sal+comm  FROM  emp    
             因为sal和comm两列的类型都是数值型,所以可以做加法运算。如果sal或comm中有一个字段不是数值类型,那么会错。
  • 空字符串运算:SELECT  sal+IFNULL(comm,0)  FROM  emp

             因为任何东西和null相加结果都是null,所以使用函数IFNULL(列名,0)将null转为数值0。

  • 给列名起别名:SELECT sal+IFNULL(comm,0) AS total FROM emp

             为了数据美观,给复杂的运算结果起个别名,其中AS可以省略。

   5、排序

  • 按升序排列:

             SELECT  *

             FROM  stu

             ORDER  BY  age  ASC;

             不写ASC默认为升序,但是建议写上,便于阅读。

  • 按降序排列:

             SELECT  *

             FROM  stu

             ORDER  BY  age  DESC;

  • 复合排序:

             SELECT  *

             FROM  stu

             ORDER  BY  age  DESC,sal  ASC;

   6、聚合函数

  • COUNT:统计指定列中不为null的记录行数
  • MAX:计算指定列的最大值,如果指定列是字符串,那么使用字符串排序运算
  • MIN:计算指定列的最小值,如果指定列是字符串,那么使用字符串排序运算
  • SUM:计算指定列的数值和,如果指定列不是数值类型,那么计算结果为0
  • AVG:计算指定列的平均值,如果指定列不是数值类型,那么计算结果为0

   7、分组查询

           SELECT  deptno, SUM(sal)

           FROM  emp

           GROUP  BY deptno

           HAVING  SUM(sal) > 9000;

       当需要分组查询时,使用GROUP  BY子句,分组后还有条件时,需要使用HAVING。

   8、LIMIT

       limit用来限定查询结果的起始行,以及总行数。主要用于分页查询

         SELECT * FROM emp LIMIT 0, 5;

      注意:起始行从0开始,即第一行开始。


六、完整性约束

    完整性约束是为了表的数据的正确性,如果数据不正确,那么一开始就不能添加到表中。

   1、主键

       当某一列添加了主键约束之后,那么这列的数据就不能重复出现。这样每行记录其主键列的值就是这一行的唯一标识。

       主键的值不能为null,也不能重复;

       指定主键约束使用PRIMARY  KEY关键字。

  • 创建表:定义列时指定主键

             CREATE  TABLE  stu(

                   id  CHAR(6)  PRIMARY  KEY

                   name  VARCHAR(20),

                   age  INT

             );

  • 创建表:定义列之后独立创建主键

             CREATE  TABLE  stu(

                   id  CHAR(6),

                   name  VARCHAR(20),

                   age  INT,

                   PRIMARY  KEY(id)

             );

  • 修改表时指定主键

             ALTER  TABLE  stu

             ADD  PRIMARY  KEY(id);

  • 删除主键(只是删除主键约束,而不是删除主键列)

             ALTER  TABLE stu  DROP  PRIMARY  KEY;


   2、主键自增长

        MySQL提供了主键自动增长的功能,这样用户就不用再为是否有主键重复了而烦恼。当主键设置为自动增长后,在没有给出主键值时,主键的值会自动增长,而且是最大主键值+1,也就不会出现重复主键的问题。

  • 创建表时设置主键自增长(主键必须是整形才可以自增长)

             CREATE  TABLE  stu(

                   id  CHAR(6)  PRIMARY  KEY  AUTO_INCREMENT

                   name  VARCHAR(20),

                   age  INT

             );

  • 修改表时设置主键自增长

            ALTER  TABLE  stu  CHANGE  id  id  INT  AUTO_INCREMENT;

  • 修改表时删除主键自增长

            ALTER  TABLE  stu  CHANGE  id  id  INT;

   3、非空

        指定非空约束的列不能没有值,也就是说在插入记录时,对添加了非空约束的列一定要给值,在修改记录时不能把非空列的值设为null。

  • 指定非空约束

             CREATE  TABLE  stu(

                   id  CHAR(6)  PRIMARY  KEY  AUTO_INCREMENT,

                   name  VARCHAR(20) NOT  NULL

                   age  INT

             );

            当name字段指定为非空后,在想stu表插入记录时,必须给name字段指定值,否则会报错。

   4、唯一

        还可以为字段指定唯一约束。当为字段指定唯一约束后,那么字段的值必须是唯一的。

         CREATE TABLE tab_ab(

                 sid INT PRIMARY KEY AUTO_INCREMENT,

                 sname VARCHAR(10) UNIQUE

          );

   5、外键

       主外键是构成表和表关联的唯一途径。

       外键是另一张表的主键,例如员工表和部门表间的关联,员工表中的部门编号字段就是外键,是相对部门表的外键。

      

  • 创建user表,指定uid为主键列:

             CREATE TABLE user(

                    uid  INT  PRIMARY  KEY  AUTO_INCREMENT,

                    uname  VARCHAR(20)  UNIQUE  NOT  NULL

              );

 

  • 创建section表,指定id为主键列,id为相对user表的id列的外键:

             CREATE  TABLE  section(

                   sid  INT  PRIMARY  KEY  AUTO_INCREMENT,

                   sname VARCHAR(30),

                   u_idINT,

                   CONSTRAINT  fk_t_user  FOREIGN  KEY(u_id)   REFERENCES   user(uid)

              );

  • 修改section表,指定u_id为相对user表的uid列的外键:

             ALTER TABLE t_section 

             ADD CONSTRAINT fk_t_user 

             FOREIGN KEY(u_id) 

             REFERENCES t_user(uid)

  • 修改section表,删除u_id的外键约束:

            ALTER TABLE section

            DROP FOREIGN KEY fk_t_user

   6、表与表之间的关系
  • 一对一:例如t_person表和t_card表,即人和身份证。这种情况需要找出主从关系,即谁是主表,谁是从表。人可以没有身份证,但身份证必须要有人才行,所以人是主表,而身份证是从表。设计从表可以有两种方案:

    Ø 在t_card表中添加外键列(相对t_user表),并且给外键添加唯一约束;

    Ø 给t_card表的主键添加外键约束(相对t_user表),即t_card表的主键也是外键。

  • 一对多(多对一):最为常见的就是一对多!一对多和多对一,这是从哪个角度去看得出来的。t_user和t_section的关系,从t_user来看就是一对多,而从t_section的角度来看就是多对一!这种情况都是在多方创建外键!

  • 多对多:例如t_stu和t_teacher表,即一个学生可以有多个老师,而一个老师也可以有多个学生。这种情况通常需要创建中间表来处理多对多关系。例如再创建一张表t_stu_tea表,给出两个外键,一个相对t_stu表的外键,另一个相对t_teacher表的外键。

七、编码

   1、查看MySQL编码

         SHOW  VARIABLES  LIKE   ' char% ' ;

        

      因为当初安装时指定了字符集UTF-8,所以所有的编码都是UTF8。

  • character_set_client:你发送的数据必须与client指定的编码一致,服务器会使用该编码来解读客户端发送过来的数据。
  • character_set_connection:通过该编码与client一致,该编码不会导致乱码。当执行的是查询语句时,客户端发送过来的数据会先转换成connection指定的编码。但只要客户端发送过来的数据与client指定的编码一致,那么转换就不会出现问题。
  • character_set_database:数据库默认编码,在创建数据库时,如果没有指定编码,那么会使用database编码。
  • character_set_server:MySQL服务器默认编码。
  • character_set_results:响应的编码,即查询结果返回给客户端的编码,这说明客户端必然使用result指定的编码来解码。

   2、控制台编码

       修改character_set_client、character_set_results、character_set_connection为GBK,就不会出现乱码。但其实只需要修改character_set_client和character_set_results 。

       控制台的编码只能是GBK,而不能修改为UTF8。

       这样就出现一个问题,客户端发送的数据是GBK,而character_set_client为UTF8,这就说明客户端数据到了服务器端一定会出现乱码,既然不能修改控制台的编码,那么只能修改character_set_client为GBK了。

  • 修改character_set_client变量:set character_set_client=gbk

  • 修改character_set_results变量:set character_set_results=gbk

       设置编码只对当前链接有效,这说明每次登陆MySQL提示符后都要去修改这两个编码,,但可以通过修改配置文件来处理这一问题。

       配置文件路径:D:\MySQL\MySQL Server 5.1\ my.ini

      


   3、MySQL工具

       使用MySQL工具是不会出现乱码的,因为会在每次链接时都修改character_set_clientcharacter_set_resultscharacter_set_connection的编码。


八、MySQL数据库备份与还原

   1、生成SQL脚本

       在控制台使用mysqldump 可以生成指定数据库的脚本文本,但要注意脚本文本中只包含数据库的内容,而不会存在创建数据库的语句。所以在回复数据库时,还需要自己手动创建一个数据库之后再去恢复数据。

  • mysqldump  -u用户名  -p密码  数据库名>生成的脚本文件路径

      

       注意,mysqldump命令是在Windows控制台下执行,无需登录mysql!!!

   2、执行脚本文件

        执行SQL脚本需要登录MySQL,然后进入指定的数据库,才可以执行SQL脚本。

       执行SQL脚本不只是用来回复数据库,也可以在平时编写SQL脚本,然后使用执行SQL脚本来操作数据库。(大家都知道,在小黑屏下编写SQL语句时,就算发现了错误,也不能修改了。所以建议大家使用文件来编写SQL代码,然后执行)

  • source  c:\mydb.sql

        

        注意,在执行脚本时,需要先行核查当前数据库中的表是否与脚本文件中的语句有冲突。(例如,在脚本文件中存在CREATE  TABLE  a的语句,而当前数据库中已经存在了a表,那么就会报错)

  • mysql  -u用户名  -p密码  数据库<要执行的脚本文件路径

        

        注意,这种方式无需登录。

九、多表查询

   多表查询有如下几种:

        l 合并结果集

        l 连接查询

               Ø 内连接

               Ø 外连接

                     ² 左外连接

                     ² 右外连接

                     ² 全外连接(MySQL不支持)

               Ø 自然连接

        l 子查询


   (一)、合并结果集

       1、作用:合并结果集,就是把两个SELECT语句的查询结果合并到一起。

       2、两种方式:

  • UNION:去除重复记录,例如:SELECT  *  FROM  t1  UNION  SELECT  *  FROM  t2;

            

  • UNION  ALL:不去除重复记录,例如:SELECT  *  FROM  t1  UNION  ALL  SELECT  *  FROM  t2;

             

       3、要求:被合并的两个结果集,列数、列类型必须相同。


   (二)、连接查询

        连接查询就是,求出多个表的乘积,例如t1连接t2,那么查询出的结果就是t1*t2。

       

        连接查询会产生笛卡尔积,假设集合A={a,b},集合B={0,1,2},则两个集合的笛卡尔积为{(a,0),(a,1),(a,2),(b,0),(b,1),(b,2)}

       

        通常要查询的多个表之间都存在关联关系,那么需要主外键去除重复信息。

  • SELECT * FROM emp,dept WHERE emp.deptno=dept.deptno;


      1、内连接

           内连接的特点:查询结果必须满足条件。

            SELECT * 

            FROM emp e 

            INNER JOIN dept d 

            ON e.deptno=d.deptno;

      2、外链接(左连接、右连接)

           外连接的特点:查询出的结果存在不满足条件的可能。

  • 左连接

             SELECT * FROM emp e 

             LEFT OUTER JOIN dept d 

             ON e.deptno=d.deptno;

          左连接是先查询出左表,然后查询右表,右表中满足条件的显示出来,不满足条件的显示为null
  • 右连接

              SELECT * FROM emp e 

              RIGHT OUTER JOIN dept d 

              ON e.deptno=d.deptno;

           右连接就是先把右表中所有记录都查询出来,然后左表满足条件的显示,不满足显示NULL

     连接查询心得:

         连接不限与两张表,连接查询也可以是三张、四张,甚至N张表的连接查询。通常连接查询不可能需要整个笛卡尔积,而只是需要其中一部分,那么这时就需要使用条件来去除不需要的记录。这个条件大多数情况下都是使用主外键关系去除。

        两张表的连接查询一定有一个主外键关系,三张表的连接查询就一定有两个主外键关系,所以在大家不是很熟悉连接查询时,首先要学会去除无用笛卡尔积,那么就是用主外键关系作为条件来处理。如果两张表的查询,那么至少有一个主外键条件,三张表连接至少有两个主外键条件。


   (三)、自然连接

          大家也都知道,连接查询会产生无用笛卡尔积,我们通常使用主外键关系等式来去除它,而自然连接无需你去给出主外键等式,它会自动找到这一等式。

  • SELECT * FROM emp NATURAL JOIN dept;
  • SELECT * FROM emp NATURAL LEFT JOIN dept;
  • SELECT * FROM emp NATURAL RIGHT JOIN dept;

   (四)、子查询

          子查询就是嵌套查询,即SELECT中包含SELECT,如果一条语句中存在两个,或两个以上SELECT,那么就是子查询语句了。

  • 子查询出现的位置:

                  WHERE后,作为条件的一部分;

                  FROM后,作为被查询的表;

  • 当子查询出现在WHERE后作为条件时,还可以使用如下关键字:

                  ANY;

                  ALL;

  • 子查询结果集的形式:

                  单行单列(用于条件)

                  单行多列(用于条件)

                  多行单列(用于条件)

                  多行多列(用于表)


练习:

1. 工资高于甘宁的员工。

分析:

查询条件:工资>甘宁工资,其中甘宁工资需要一条子查询。

 

第一步:查询甘宁的工资

SELECT sal FROM emp WHERE ename='甘宁'

 

第二步:查询高于甘宁工资的员工

SELECT * FROM emp WHERE sal > (${第一步})

 

结果:

SELECT * FROM emp WHERE sal > (SELECT sal FROM emp WHERE ename='甘宁')

 

l 子查询作为条件

l 子查询形式为单行单列

 

2. 工资高于30部门所有人的员工信息

分析:

查询条件:工资高于30部门所有人工资,其中30部门所有人工资是子查询。高于所有需要使用all关键字。

 

第一步:查询30部门所有人工资

SELECT sal FROM emp WHERE deptno=30;

 

第二步:查询高于30部门所有人工资的员工信息

SELECT * FROM emp WHERE sal > ALL (${第一步})

 

结果:

SELECT * FROM emp WHERE sal > ALL (SELECT sal FROM emp WHERE deptno=30)

 

l 子查询作为条件

l 子查询形式为多行单列(当子查询结果集形式为多行单列时可以使用ALLANY关键字)

 

3. 查询工作和工资与殷天正完全相同的员工信息

分析:

查询条件:工作和工资与殷天正完全相同,这是子查询

 

第一步:查询出殷天正的工作和工资

SELECT job,sal FROM emp WHERE ename='殷天正'

 

第二步:查询出与殷天正工作和工资相同的人

SELECT * FROM emp WHERE (job,sal) IN (${第一步})

 

结果:

SELECT * FROM emp WHERE (job,sal) IN (SELECT job,sal FROM emp WHERE ename='殷天正')

 

l 子查询作为条件

l 子查询形式为单行多列

 

4. 查询员工编号为1006的员工名称、员工工资、部门名称、部门地址

分析:

查询列:员工名称、员工工资、部门名称、部门地址

查询表:empdept,分析得出,不需要外连接(外连接的特性:某一行(或某些行)记录上会出现一半有值,一半为NULL值)

条件:员工编号为1006

 

第一步:去除多表,只查一张表,这里去除部门表,只查员工表

SELECT ename, sal FROM emp e WHERE empno=1006

 

第二步:让第一步与dept做内连接查询,添加主外键条件去除无用笛卡尔积

SELECT e.ename, e.sal, d.dname, d.loc 

FROM emp e, dept d 

WHERE e.deptno=d.deptno AND empno=1006

 

第二步中的dept表表示所有行所有列的一张完整的表,这里可以把dept替换成所有行,但只有dnameloc列的表,这需要子查询。

第三步:查询dept表中dnameloc两列,因为deptno会被作为条件,用来去除无用笛卡尔积,所以需要查询它。

SELECT dname,loc,deptno FROM dept;

 

第四步:替换第二步中的dept

SELECT e.ename, e.sal, d.dname, d.loc 

FROM emp e, (SELECT dname,loc,deptno FROM dept) d 

WHERE e.deptno=d.deptno AND e.empno=1006

 

l 子查询作为表

l 子查询形式为多行多列

 


0 0
原创粉丝点击