sqliteMySQL基础

  人类在提高之历程遭到,创造了数字、文字、符号等来拓展数量的笔录,但是接受着咀嚼能力与创建能力的升级换代,数据量越来越老,对于数据的笔录与精确查找,成为了一个首要难题。

  计算机诞生后,数据开始于电脑中贮存并盘算,并统筹出了数据库系统。

  数据库系统缓解的题目:持久化存储,优化读写,保证数据的管用。

  当前使的数据库,主要分为两接近:

    文档型,如sqlite,就是一个文件,通过对文本之复制成功数据库的复制。

    服务型,如mysql、postgre,数据存储在一个大体文件中,但是得利用极限为tcp/ip协议连接,进行数据库的读写操作。

  当前物理的数据库都是按部就班E-R模型进行设计之(E表示entry,实体,R表示relationship,关系)。

三范式

  经过研究和针对应用被问题之总结,对于规划数据库提出了片标准,这些标准给名范式。

  第一范式(1NF):列不可拆分;

  第二范式(2NF):唯一标识;

  第三范式(3NF):引用主键。

  说明:后一个范式,都是在前面一个范式的底子及成立的。

数据库操作

  1、显示数据库

  切记在数据库的操作语句子之最终一定要加以一个子公司来收,否则便回车命令不会见尽得加一个分店才是完整的下令。

SHOW DATABASES;

  默认数据库来三独他们的企图分别是:
  mysql – 用户权限相关数据
  test – 用于用户测试数据
  information_schema – MySQL本身架构相关数据

sqlite 1sqlite 2

+--------------------+
| Database           |
+--------------------+
| information_schema |
| db1                |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.02 sec)

databases

  2、创建删除数据库

  也即是创办删除文件夹

create database db2 default charset utf8;

  默认数据库名称使用utf8编码格式,这样数据库是华语也堪正常显示采用。

  删除数据库时利用drop命令。

 drop database db2;

  3、使用数据库

mysql> use db1
Database changed

  4.出示当前数据库中享有的表明

sqlite 3sqlite 4

mysql> show tables;
+---------------+
| Tables_in_db1 |
+---------------+
| t1            |
| t2            |
+---------------+
2 rows in set (0.00 sec)

查看表

  5、用户管理

sqlite 5sqlite 6

 create user 'alex'@'192.168.1.1' identified by '123123';#只能在这台ip上登陆
 create user 'alex'@'192.168.1.%' identified by '123123';
 create user 'alex'@'%' identified by '123123';#%表示任意网段

始建用户

  创建了的用户是不曾其他权力操作的,必须使以grant授权下,用户才产生权力,并且后长用户是力不从心兼而有之grant的权位的,grant操作只有root用户可以下。

sqlite 7sqlite 8

grant select,insert,update  on db1.t1 to 'alex'@'%';
grant all privileges  on db1.t1 to 'alex'@'%';#所有权限除了grant
grant 权限 on 数据库
show grants for '用户'@'IP地址'                  -- 查看权限
grant  权限 on 数据库.表 to   '用户'@'IP地址'      -- 授权
revoke 权限 on 数据库.表 from '用户'@'IP地址'      -- 取消权限
库与表可以是*,表示所有

grant

sqlite 9sqlite 10

drop user '用户名'@'IP地址';

去用户

sqlite 11sqlite 12

rename user '用户名'@'IP地址'; to '新用户名'@'IP地址';;
#注意这里的分号

改用户

sqlite 13sqlite 14

set password for '用户名'@'IP地址' = Password('新密码')

改密码

  用户权限相关数据保存于mysql数据库的user表中,所以也足以一直针对该展开操作,但是非建议直接操作user表。

sqlite 15sqlite 16

对于目标数据库以及内部其他:
    数据库名.*           数据库中的所有
    数据库名.表          指定数据库中的某张表
    数据库名.存储过程     指定数据库中的存储过程
    *.*                所有数据库

*每当数据库名中

   流淌:数据库本质是socket链接的。

sqlite 17sqlite 18

用户名@IP地址         用户只能在改IP下才能访问
用户名@192.168.1.%   用户只能在改IP段下才能访问(通配符%表示任意)
用户名@%             用户可以再任意IP下访问(默认IP地址为%)

%在网段中

flush privileges,将数据读取到内存中,从而立即生效。

  于mysql中忘记密码怎么收拾?

sqlite 19sqlite 20

# 启动免授权服务端
mysqld --skip-grant-tables

# 客户端
mysql -u root -p

# 修改用户名密码
update mysql.user set authentication_string=password('666') where user='root';
flush privileges;

遗忘密码的操作

数据表操作

  1、创建表

create table 表名(
    列名  类型  是否可以为空,
    列名  类型  是否可以为空
)ENGINE=InnoDB DEFAULT CHARSET=utf8

  innodb支持工作,原子性操作,例:一正在数转发至外一样正,如果同在扣款成功,另一样在未收取就违背了工作操作,事务操作就是要其他一样着收款失败那么这次市不建,扣款也无见面发出。

  null代表可为空,not null表示不可以为空。

sqlite 21sqlite 22

mysql> create table t3(id int null,name char(10))engine=innodb default charset=utf8;
Query OK, 0 rows affected (0.34 sec)
mysql> insert into t3(name) value('jeff');
Query OK, 1 row affected (0.08 sec)
mysql> select * from t3;
+------+------+
| id   | name |
+------+------+
| NULL | jeff |
+------+------+
1 row in set (0.00 sec)

null

sqlite 23sqlite 24

默认值,创建列时可以指定默认值,当插入数据时如果未主动设置,则自动添加默认值
create table tb1(nid int not null defalut 2,num int not null)

默认值

sqlite 25sqlite 26

mysql> create table t4(id int auto_increment primary key,name char(10))engine=innodb default charset=utf8;
Query OK, 0 rows affected (0.25 sec)

mysql> insert into t4(name) value('jeff');
Query OK, 1 row affected (0.03 sec)

mysql> insert into t4(name) value('frank');
Query OK, 1 row affected (0.03 sec)

mysql> insert into t4(name) value('egon');
Query OK, 1 row affected (0.02 sec)

mysql> insert into t4(name) value('alex');
Query OK, 1 row affected (0.02 sec)

mysql> select * from t4;
+----+-------+
| id | name  |
+----+-------+
|  1 | jeff  |
|  2 | frank |
|  3 | egon  |
|  4 | alex  |
+----+-------+
4 rows in set (0.00 sec)

自增

  还有雷同种植办法呢得成功自增:

sqlite 27sqlite 28

create table tb1(nid int not null auto_increment,num int null,index(nid))

index()

  注意:1、对于自增列,必须是索引(含主键)。
2、对于自增可以设置步长和起始值

sqlite 29sqlite 30

show session variables like 'auto_inc%';
set session auto_increment_increment=2;
set session auto_increment_offset=10;

shwo global  variables like 'auto_inc%';
set global auto_increment_increment=2;
set global auto_increment_offset=10;

安自增

  主键是相同种特殊的唯一索引,不容许有空值,如果主键使用单个列,则它的价值必须唯一,如果是多列,则该构成要唯一。

  对于自增还有几接触要上:

sqlite 31sqlite 32

mysql> desc t7;
+-------+----------+------+-----+---------+----------------+
| Field | Type     | Null | Key | Default | Extra          |
+-------+----------+------+-----+---------+----------------+
| id    | int(11)  | NO   | PRI | NULL    | auto_increment |
| name  | char(10) | YES  |     | NULL    |                |
+-------+----------+------+-----+---------+----------------+
2 rows in set (0.00 sec)#查看每个字段的意思。

desc

  查看AUTO_INCREMENT字段可以知道创建的产一个实践之自增id是微。

sqlite 33sqlite 34

mysql> select * from t7;
+----+------+
| id | name |
+----+------+
|  1 | alex |
|  2 | egon |
|  3 | fu   |
+----+------+
3 rows in set (0.00 sec)
mysql> show create table t7 \G;
*************************** 1. row ***************************
       Table: t7
Create Table: CREATE TABLE `t7` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` char(10) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
#所以下一个行的id从4开始,即使delete还是从4开始,truncate会从1从新计数。

AUTO_INCREMENT

sqlite 35sqlite 36

mysql> alter table t7 AUTO_INCREMENT=20;
Query OK, 0 rows affected (0.18 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> show create table t7 \G;
*************************** 1. row ***************************
       Table: t7
Create Table: CREATE TABLE `t7` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` char(10) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
mysql> insert into t7(name) values('jeff');
Query OK, 1 row affected (0.08 sec)
mysql> select * from t7;
+----+------+
| id | name |
+----+------+
|  1 | alex |
|  2 | egon |
|  3 | fu   |
| 20 | jeff |
+----+------+
4 rows in set (0.00 sec)

alter自增

  关于MySQL的自增与幅度分为两种植,一种植是冲会话的0,只在这个会话有功力,在别的窗口或下一致糟糕登陆都没用了。另一样种是因全局的。

  这里的对话的概念就是同一次等登陆就是一样不成对话。

show session variables like 'auto_inc%';    查看全局变量
+--------------------------+-------+
| Variable_name            | Value |
+--------------------------+-------+
| auto_increment_increment | 1     |
| auto_increment_offset    | 1    |
+--------------------------+-------+

sqlite 37sqlite 38

set session auto_increment_increment=2;     设置会话步长
set session auto_increment_offset=10;
show global variables like 'auto_inc%';        查看全局变量
set global auto_increment_increment=2;         设置会话步长
set global auto_increment_offset=10;

会见讲话与幅度的安

  : 如果auto_increment_offset的价值大于auto_increment_increment的值,则auto_increment_offset的价为忽略。

sqlite 39sqlite 40

mysql> insert into t7(name) values('frank');
Query OK, 1 row affected (0.08 sec)
mysql> select * from t7;
+----+-------+
| id | name  |
+----+-------+
|  1 | alex  |
|  2 | egon  |
|  3 | fu    |
| 20 | jeff  |
| 30 | frank |
+----+-------+
5 rows in set (0.00 sec)

mysql> show session variables like 'auto_inc%';
+--------------------------+-------+
| Variable_name            | Value |
+--------------------------+-------+
| auto_increment_increment | 20    |
| auto_increment_offset    | 10    |
+--------------------------+-------+
2 rows in set, 1 warning (0.00 sec)

初始值与幅度

  sql的自增步长在开创的时刻还起字段规定,这样基于表的开场与幅度更客观。

sqlite 41sqlite 42

                CREATE TABLE `t5` (
                  `nid` int(11) NOT NULL AUTO_INCREMENT,
                  `pid` int(11) NOT NULL,
                  `num` int(11) DEFAULT NULL,
                  PRIMARY KEY (`nid`,`pid`)
                ) ENGINE=InnoDB AUTO_INCREMENT=4, 步长=2 DEFAULT CHARSET=utf8

sql伪代码

sqlite 43sqlite 44

create table tb1(nid int not null auto_increment primary key,num int null)
create table tb1(nid int not null,num int not null,primary key(nid,num))

主键创建有半点种植艺术

sqlite 45sqlite 46

drop table 表名

删除表

sqlite 47sqlite 48

delete from 表名#删除再添加还是从删除时的主键自增
truncate table 表名#删除后再创建从1开始自增

清空表

sqlite 49sqlite 50

添加列:alter table 表名 add 列名 类型
删除列:alter table 表名 drop column 列名
修改列:
        alter table 表名 modify column 列名 类型;  -- 类型
        alter table 表名 change 原列名 新列名 类型; -- 列名,类型
  
添加主键:
        alter table 表名 add primary key(列名);
删除主键:
        alter table 表名 drop primary key;
        alter table 表名  modify  列名 int, drop primary key;
  
添加外键:alter table 从表 add constraint 外键名称(形如:FK_从表_主表) foreign key 从表(外键字段) references 主表(主键字段);
删除外键:alter table 表名 drop foreign key 外键名称
  
修改默认值:ALTER TABLE testalter_tbl ALTER i SET DEFAULT 1000;

修改表

sqlite 51sqlite 52

示例:
1. 修改存储引擎
mysql> alter table service 
    -> engine=innodb;

2. 添加字段
mysql> alter table student10
    -> add name varchar(20) not null,
    -> add age int(3) not null default 22;

mysql> alter table student10
    -> add stu_num varchar(10) not null after name;                //添加name字段之后

mysql> alter table student10                        
    -> add sex enum('male','female') default 'male' first;          //添加到最前面

3. 删除字段
mysql> alter table student10
    -> drop sex;

mysql> alter table service
    -> drop mac;

4. 修改字段类型modify
mysql> alter table student10
    -> modify age int(3);
mysql> alter table student10
    -> modify id int(11) not null primary key auto_increment;    //修改为主键

5. 增加约束(针对已有的主键增加auto_increment)
mysql> alter table student10 modify id int(11) not null primary key auto_increment;
ERROR 1068 (42000): Multiple primary key defined

mysql> alter table student10 modify id int(11) not null auto_increment;
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

6. 对已经存在的表增加复合主键
mysql> alter table service2
    -> add primary key(host_ip,port);        

7. 增加主键
mysql> alter table student1
    -> modify name varchar(10) not null primary key;

8. 增加主键和自动增长
mysql> alter table student1
    -> modify id int not null primary key auto_increment;

9. 删除主键
a. 删除自增约束
mysql> alter table student10 modify id int(11) not null; 

b. 删除主键
mysql> alter table student10                                 
    -> drop primary key;

修改表的演示

sqlite 53sqlite 54

复制表结构+记录 (key不会复制: 主键、外键和索引)
mysql> create table new_service select * from service;
只复制表结构
mysql> select * from service where 1=2;        //条件为假,查不到任何记录
Empty set (0.00 sec)
mysql> create table new1_service select * from service where 1=2;  
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0
mysql> create table t4 like employees;

复制表

  基本数据类:

  MySQL的数据类型大致分为:数价值、时间跟字符串。

sqlite 55sqlite 56

bit[(M)]
            二进制位(101001),m表示二进制位的长度(1-64),默认m=1

        tinyint[(m)] [unsigned] [zerofill]

            小整数,数据类型用于保存一些范围的整数数值范围:
            有符号:
                -128 ~ 127.
            无符号:
                0 ~ 255

            特别的: MySQL中无布尔值,使用tinyint(1)构造。

        int[(m)][unsigned][zerofill]

            整数,数据类型用于保存一些范围的整数数值范围:
                有符号:
                    -2147483648 ~ 2147483647
                无符号:
                    0 ~ 4294967295

            特别的:整数类型中的m仅用于显示,对存储范围无限制。例如: int(5),当插入数据2时,select 时数据显示为: 00002

        bigint[(m)][unsigned][zerofill]
            大整数,数据类型用于保存一些范围的整数数值范围:
                有符号:
                    -9223372036854775808 ~ 9223372036854775807
                无符号:
                    0  ~  18446744073709551615

        decimal[(m[,d])] [unsigned] [zerofill]
            准确的小数值,m是数字总个数(负号不算),d是小数点后个数。 m最大值为65,d最大值为30。

            特别的:对于精确数值计算时需要用此类型
                   decaimal能够存储精确值的原因在于其内部按照字符串存储。

        FLOAT[(M,D)] [UNSIGNED] [ZEROFILL]
            单精度浮点数(非准确小数值),m是数字总个数,d是小数点后个数。
                无符号:
                    -3.402823466E+38 to -1.175494351E-38,
                    0
                    1.175494351E-38 to 3.402823466E+38
                有符号:
                    0
                    1.175494351E-38 to 3.402823466E+38

            **** 数值越大,越不准确 ****

        DOUBLE[(M,D)] [UNSIGNED] [ZEROFILL]
            双精度浮点数(非准确小数值),m是数字总个数,d是小数点后个数。

                无符号:
                    -1.7976931348623157E+308 to -2.2250738585072014E-308
                    0
                    2.2250738585072014E-308 to 1.7976931348623157E+308
                有符号:
                    0
                    2.2250738585072014E-308 to 1.7976931348623157E+308
            **** 数值越大,越不准确 ****

数值的品类

sqlite 57sqlite 58

char (m)
            char数据类型用于表示固定长度的字符串,可以包含最多达255个字符。其中m代表字符串的长度。
            PS: 即使数据小于m长度,也会占用m长度
        varchar(m)
            varchars数据类型用于变长的字符串,可以包含最多达255个字符。其中m代表该数据类型所允许保存的字符串的最大长度,只要长度小于该最大值的字符串都可以被保存在该数据类型中。

            注:虽然varchar使用起来较为灵活,但是从整个系统的性能角度来说,char数据类型的处理速度更快,有时甚至可以超出varchar处理速度的50%。因此,用户在设计数据库时应当综合考虑各方面的因素,以求达到最佳的平衡

        text
            text数据类型用于保存变长的大字符串,可以组多到65535 (2**16 − 1)个字符。

        mediumtext
            A TEXT column with a maximum length of 16,777,215 (2**24 − 1) characters.

        longtext
            A TEXT column with a maximum length of 4,294,967,295 or 4GB (2**32 − 1) characters.
PS:比longtxt还大的文件直接存入硬盘然后把路径写到数据库中。

        enum
            枚举类型,
            An ENUM column can have a maximum of 65,535 distinct elements. (The practical limit is less than 3000.)
            示例:
                CREATE TABLE shirts (
                    name VARCHAR(40),
                    size ENUM('x-small', 'small', 'medium', 'large', 'x-large')
                );
                INSERT INTO shirts (name, size) VALUES ('dress shirt','large'), ('t-shirt','medium'),('polo shirt','small');
只能从枚举中取出一个值
        set
            集合类型
            A SET column can have a maximum of 64 distinct members.
            示例:
                CREATE TABLE myset (col SET('a', 'b', 'c', 'd'));
                INSERT INTO myset (col) VALUES ('a,d'), ('d,a'), ('a,d,a'), ('a,d,d'), ('d,a,d');
从集合中取出任意个值。

字符串的类型

sqlite 59sqlite 60

DATE
   YYYY-MM-DD(1000-01-01/9999-12-31)

TIME
   HH:MM:SS('-838:59:59'/'838:59:59')

YEAR
    YYYY(1901/2155)
DATETIME

     YYYY-MM-DD HH:MM:SS(1000-01-01 00:00:00/9999-12-31 23:59:59    Y)

TIMESTAMP

      YYYYMMDD HHMMSS(1970-01-01 00:00:00/2037 年某时)
#datatime是使用最多的

光阴档次

  char(10)不满10各也强制占个成10个,这样以检索时进度又快,varchar(10)不必然长可绝多10号,这样做还省去空间,在操作时稍情况按ip本来就是定长,所以用char()更好,创建数据表或当优化的时节呢应有拿char()放到前面这样见面又便捷又快。

  使用now函数插入当前底时空以及日期。

insert into table values(now(),now(),now()); --可查当前时间,格式自己设置
create table t8(d date,t time,dt datetime);
insert into t8 values(now(),now(),now()); 
select * from t8;
+------------+----------+---------------------+
| d          | t        | dt                  |
+------------+----------+---------------------+
| 2017-09-17 | 21:06:59 | 2017-09-17 21:06:59 |
+------------+----------+---------------------+

  单条件where的使用。

sqlite 61sqlite 62

#1:单条件查询
    SELECT name FROM employee
        WHERE post='sale';

#2:多条件查询
    SELECT name,salary FROM employee
        WHERE post='teacher' AND salary>10000;

#3:关键字BETWEEN AND
    SELECT name,salary FROM employee 
        WHERE salary BETWEEN 10000 AND 20000;

    SELECT name,salary FROM employee 
        WHERE salary NOT BETWEEN 10000 AND 20000;

#4:关键字IS NULL(判断某个字段是否为NULL不能用等号,需要用IS)
    SELECT name,post_comment FROM employee 
        WHERE post_comment IS NULL;

    SELECT name,post_comment FROM employee 
        WHERE post_comment IS NOT NULL;

    SELECT name,post_comment FROM employee 
        WHERE post_comment=''; 注意''是空字符串,不是null
    ps:
        执行
        update employee set post_comment='' where id=2;
        再用上条查看,就会有结果了

#5:关键字IN集合查询
    SELECT name,salary FROM employee 
        WHERE salary=3000 OR salary=3500 OR salary=4000 OR salary=9000 ;

    SELECT name,salary FROM employee 
        WHERE salary IN (3000,3500,4000,9000) ;

    SELECT name,salary FROM employee 
        WHERE salary NOT IN (3000,3500,4000,9000) ;

#6:关键字LIKE模糊查询
    通配符’%’
    SELECT * FROM employee 
            WHERE name LIKE 'eg%';

    通配符’_’
    SELECT * FROM employee 
            WHERE name LIKE 'al__';

示例

发明底操作

sqlite 63sqlite 64

insert into 表 (列名,列名...) values (值,值,值...)
insert into 表 (列名,列名...) values (值,值,值...),(值,值,值...)
insert into 表 (列名,列名...) select (列名,列名...) from 表

sqlite 65sqlite 66

delete from 表
delete from 表 where id=1 and name='alex'

sqlite 67sqlite 68

update 表 set name = 'alex' where id>1

sqlite 69sqlite 70

select * from 表
select * from 表 where id > 1
select nid,name,gender as gg from 表 where id > 1

sqlite 71sqlite 72

create table tb12(
                id int auto_increment primary key,
                name varchar(32),
                age int
            )engine=innodb default charset=utf8;

        增
            insert into tb11(name,age) values('alex',12);

            insert into tb11(name,age) values('alex',12),('root',18);

            insert into tb12(name,age) select name,age from tb11;tb11的所有都复制到tb12
        删
            delete from tb12;
            delete from tb12 where id !=2
            delete from tb12 where id =2
            delete from tb12 where id > 2
            delete from tb12 where id >=2 and name=‘alex’
            delete from tb12 where id >=2 or name='alex'

        改
            update tb12 set name='alex' where id>12 and name='xx'
            update tb12 set name='alex',age=19 where id>12 and name='xx'
        查    
            select * from tb12;
            select id,name from tb12;
            select id,name from tb12 where id > 10 or name ='xxx';
            select id,name as cname from tb12 where id > 10 or name ='xxx';
select name,age,11 from tb12;
            其他:
                select * from tb12 where id != 1
                select * from tb12 where id in (1,5,12);只拿1,5,12
                select * from tb12 where id not in (1,5,12);除了都拿
                select * from tb12 where id in (select id from tb11)只能拿一列
                select * from tb12 where id between 5 and 12;闭区间
通配符:

                select * from tb12 where name like "a%"%任意字符
                select * from tb12 where name like "a_"_只是一个字符
分页:

                    select * from tb12 limit 10;前10条
                    select * from tb12 limit 0,10;
                    select * from tb12 limit 10,10;
                    select * from tb12 limit 20,10;
                  两个值从第几条开始取,向后取多少条
                    select * from tb12 limit 10 offset 20;
      从20开始取10条  

                    # page = input('请输入要查看的页码')
                    # page = int(page)
                    # (page-1) * 10
                    # select * from tb12 limit 0,10; 1
                    # select * from tb12 limit 10,10;2


                排序:
                    select * from tb12 order by id desc; id大到小
                    select * from tb12 order by id asc;  id小到大
                    select * from tb12 order by age desc,id desc;

                    取后10条数据(倒序取)
                    select * from tb12 order by id desc limit 10;

                分组:

                    select count(id),max(id),part_id from userinfo5 group by part_id;

                    count
                    max
                    min
                    sum
                    avg

                    **** 如果对于聚合函数结果进行二次筛选时?必须使用having ****
                    select count(id),part_id from userinfo5 group by part_id having count(id) > 1;

                    select count(id),part_id from userinfo5 where id > 0 group by part_id having count(id) > 1;
            where不能加聚合函数

                连表操作:

                    select * from userinfo5,department5#这个是不对的

                    select * from userinfo5,department5 where userinfo5.part_id = department5.id

                    select * from userinfo5 left join department5 on userinfo5.part_id = department5.id
                    select * from department5 left join userinfo5 on userinfo5.part_id = department5.id
                    # userinfo5左边全部显示
            select * from userinfo5 innder join department5 on userinfo5.part_id = department5.id
                    将出现null时一行隐藏
                    select * from
                        department5
                    left join userinfo5 on userinfo5.part_id = department5.id
                    left join userinfo6 on userinfo5.part_id = department5.id
                    select
                        score.sid,
                        student.sid
                        from
                    score
                        left join student on score.student_id = student.sid
                        left join course on score.course_id = course.cid
                        left join class on student.class_id = class.cid
                        left join teacher on course.teacher_id=teacher.tid
            select count(id) from userinfo5;

增删改查示例

  如果再次添表时未设置字符编码,插入中文时不时见面面世编码错误无法插入的情景。

sqlite 73sqlite 74

alter table t1 charset utf8; #修改表t1的编码
--此时任然无法插入中文,因为表的编码改变了,但是name字段还需要重新定义才可以
alter table t1 modify name varchar(20); 这样就可以插入中文了。

修改表插入中文

  也避免这种情景之起,最好将数据库的编码改成为utf8,这样以斯数据库下创造表时,都默认utf8编码了。

  查询的补偿:

  关键字distinct可以查询不更的记录。

select distinct xxx from table;查询结果去重

  聚合:

语法:select [column_name1,colun_name2,...] fun_name from tablename [where condition] [group by column_name1,colun_name2,...[with rollup] [having where condition]]
fun_name:表示聚合操作,也就是聚合函数,常用的有sum(求和),count(计数),max(最大值),min(最小值)
group by:要进行分类聚合的字段
with rollup:表明是否对分类聚合后的结果进行再汇总
having:表示对分类后的结果再进行过滤

  子查询:

  子查询的要紧字:in、not in、=、!=、exists、not exists、between …
and …;

  比较运算符

mysql> select * from students;
+----+-----------+----------+
| id | name      | class_id |
+----+-----------+----------+
|  1 | jeff      |        1 |
|  2 | franklike |        3 |
|  4 | xixilove  |       16 |
+----+-----------+----------+
mysql> select * from students where id>3;
+----+----------+----------+
| id | name     | class_id |
+----+----------+----------+
|  4 | xixilove |       16 |
+----+----------+----------+
mysql> select * from students where id<=3;
+----+-----------+----------+
| id | name      | class_id |
+----+-----------+----------+
|  1 | jeff      |        1 |
|  2 | franklike |        3 |
+----+-----------+----------+
mysql> select * from students where name!='jeff';
+----+-----------+----------+
| id | name      | class_id |
+----+-----------+----------+
|  2 | franklike |        3 |
|  4 | xixilove  |       16 |
+----+-----------+----------+

  除此之外还有逻辑运算符(and,or,not),模糊查询like,%(任意多字符),_(任意一个字符)。

  and比or先运算,如果又起并欲先算or,需要做()使用

  外键是一个新鲜之目,只能是点名内容。

create table userinfo(
            uid bigint auto_increment primary key,
            name varchar(32),
            department_id int,
            constraint fk_user_depar foreign key (department_id) references department(id)
        )engine=innodb default charset=utf8;

create table department(
            id bigint auto_increment primary key,
            title char(15))engine=innodb default charset=utf8;

   唯一索引,索引的目的都是为加速查找,唯一索引的引入一方面是以约束不能够再次,另一方面即使是加快查找,与主键不同之是,唯一索引虽然未可知重复而可以吗空,但是主键不能够为空。

 unique 唯一索引名称 (列名,列名),

  外键的变种,表和发明中的涉及好是千篇一律对准多,一对一,多对相同及多对多。

  示例:

sqlite 75sqlite 76

create table userinfo1(
                    id int auto_increment primary key,
                    name char(10),
                    gender char(10),
                    email varchar(64)
                )engine=innodb default charset=utf8;
                create table admin(
                    id int not null auto_increment primary key,
                    username varchar(64) not null,
                    password VARCHAR(64) not null,
                    user_id int not null,
                    unique uq_u1 (user_id),
                    CONSTRAINT fk_admin_u1 FOREIGN key (user_id) REFERENCES userinfo1(id)
                )engine=innodb default charset=utf8;

一对一

#大多针对性大多之涉

 

create table userinfo2(
     id int auto_increment primary key,
     name char(10),
     gender char(10),
     email varchar(64)
    )engine=innodb default charset=utf8;–这里是操作电脑的用户之阐发

   create table host(
     id int auto_increment primary key,
     hostname char(64)
    )engine=innodb default charset=utf8;–这里是存的处理器的说明

    create table user2host(
     id int auto_increment primary key,
     userid int not null,
     hostid int not null,
     unique uq_user_host
(userid,hostid),–每个人对同样雅计算机的操作权都只是需要出现平糟糕,所以加上唯一索引
     CONSTRAINT fk_u2h_user FOREIGN key (userid) REFERENCES
userinfo2(id),–外键约束
     CONSTRAINT fk_u2h_host FOREIGN key (hostid) REFERENCES host(id)
    )engine=innodb default charset=utf8;

   补充一个临时表。临时表只少存在内存中。

sqlite 77sqlite 78

mysql> select cid from (select * from course left join teacher on course.teach_id = teacher.tid) as n;
+-----+
| cid |
+-----+
|   1 |
|   2 |
|   3 |
+-----+

临时表

   在此间还要加一下着重字优先级。

  from>where>group by>having>select>distinct>order
by>limit。

  1.找到表:from;

  2.仍规则过滤表记录:where(过滤的结果是一条条笔录);

  3.以摸清的结果按标准分组:group by;

  4.拿分组的结果再行过滤:having(与where相同之处是还可以进行过滤,不同之处是having是因分组之后的结果进行过滤,过滤的结果也是一个个的组);

  5.查出结果:select;

  6.去重;

  7.将6底结果按规则排序:order by;

  8.将7的结果限制显示条数。

  外键:

  节省空间,方便修改(相对于枚举来说)

sqlite 79sqlite 80

        create table userinfo(
            uid bigint auto_increment primary key,
            name varchar(32),
            department_id int,
            xx_id int,--这个id就是外键,他指向另外一张表
            constraint fk_user_depar foreign key (department_id) references color(id)--这个是约束关系,外键只能是另一张表的id
        )engine=innodb default charset=utf8;

        create table department(
            id bigint auto_increment primary key,
            title char(15)
        )engine=innodb default charset=utf8;

外键

pymysql模块

  我们得下pymysql来MySQL数据库的总是,并促成数据库的各种操作。

  首先我们若理解怎么下pymysql来连续我们的数据库。

sqlite 81sqlite 82

create database dbforpymysql;
create table userinfo(id int not null auto_increment primary key,username varchar(10),passwd varchar(10))engine=innodb default charset=utf8;
insert into userinfo(username,passwd) values('frank','123'),('rose','321'),('jeff','666');
mysql> select * from userinfo;
+----+----------+--------+
| id | username | passwd |
+----+----------+--------+
|  1 | frank    | 123    |
|  2 | rose     | 321    |
|  3 | jeff     | 666    |
+----+----------+--------+

创建测试数据

#-*-coding=utf-8-*-
import pymysql

#连接数据库db就是conn
db = pymysql.connect("localhost","jeff","jeff@123","dbforpymysql")

#使用cursor()方法创建一个游标对象
cursor = db.cursor()

#使用execute()方法执行SQL语句
cursor.execute("SELECT * FROM userinfo;")

#使用fetall()获取全部数据
data = cursor.fetchall()

#打印获取到的数据
print(data)

#关闭游标和数据库的连接
cursor.close()
db.close()

sqlite 83sqlite 84

def __init__(self, host=None, user=None, password="",
             database=None, port=0, unix_socket=None,
             charset='', sql_mode=None,
             read_default_file=None, conv=None, use_unicode=None,
             client_flag=0, cursorclass=Cursor, init_command=None,
             connect_timeout=10, ssl=None, read_default_group=None,
             compress=None, named_pipe=None, no_delay=None,
             autocommit=False, db=None, passwd=None, local_infile=False,
             max_allowed_packet=16*1024*1024, defer_connect=False,
             auth_plugin_map={}, read_timeout=None, write_timeout=None,
             bind_address=None):
#参数解释:
host: Host where the database server is located    #主机名或者主机地址
user: Username to log in as   #用户名
password: Password to use.    #密码
database: Database to use, None to not use a particular one.    #指定的数据库
port: MySQL port to use, default is usually OK. (default: 3306)    #端口,默认是3306
bind_address: When the client has multiple network interfaces, specify
    the interface from which to connect to the host. Argument can be
    a hostname or an IP address.    #当客户端有多个网络接口的时候,指点连接到数据库的接口,可以是一个主机名或者ip地址
unix_socket: Optionally, you can use a unix socket rather than TCP/IP.
charset: Charset you want to use.    #指定字符编码
sql_mode: Default SQL_MODE to use. 
read_default_file:
    Specifies  my.cnf file to read these parameters from under the [client] section.
conv:
    Conversion dictionary to use instead of the default one.
    This is used to provide custom marshalling and unmarshaling of types.
    See converters.
use_unicode:
    Whether or not to default to unicode strings.
    This option defaults to true for Py3k.
client_flag: Custom flags to send to MySQL. Find potential values in constants.CLIENT.
cursorclass: Custom cursor class to use.
init_command: Initial SQL statement to run when connection is established.
connect_timeout: Timeout before throwing an exception when connecting.
    (default: 10, min: 1, max: 31536000)
ssl:
    A dict of arguments similar to mysql_ssl_set()'s parameters.
    For now the capath and cipher arguments are not supported.
read_default_group: Group to read from in the configuration file.
compress; Not supported
named_pipe: Not supported
autocommit: Autocommit mode. None means use server default. (default: False)
local_infile: Boolean to enable the use of LOAD DATA LOCAL command. (default: False)
max_allowed_packet: Max size of packet sent to server in bytes. (default: 16MB)
    Only used to limit size of "LOAD LOCAL INFILE" data packet smaller than default (16KB).
defer_connect: Don't explicitly connect on contruction - wait for connect call.
    (default: False)
auth_plugin_map: A dict of plugin names to a class that processes that plugin.
    The class will take the Connection object as the argument to the constructor.
    The class needs an authenticate method taking an authentication packet as
    an argument.  For the dialog plugin, a prompt(echo, prompt) method can be used
    (if no authenticate method) for returning a string from the user. (experimental)
db: Alias for database. (for compatibility to MySQLdb)
passwd: Alias for password. (for compatibility to MySQLdb)

设若确立连接connect可承受的参数

sqlite 85sqlite 86

#-*-coding=utf-8-*-
import pymysql

user = input("username:")
pwd = input("password:")

conn = pymysql.connect(host="localhost",user='jeff',password='jeff@123',database="dbforpymysql")
cursor = conn.cursor()#操作数据需要使用这个,链接是通道,他就是操作的手
sql = "select * from userinfo where username='%s' and passwd='%s'" %(user,pwd,)#这个方法是错误的,会造成sql注入
# select * from userinfo where username='uu' or 1=1 -- ' and password='%s'
cursor.execute(sql)
result = cursor.fetchone()#只拿第一条的查询结果
cursor.close()
conn.close()

if result:
    print('登录成功')
else:
    print('登录失败')

sql注入的缪登陆方式

sqlite 87sqlite 88

#-*-coding=utf-8-*-
import pymysql

user = input("username:")
pwd = input("password:")

conn = pymysql.connect(host="localhost",user='jeff',password='jeff@123',database="dbforpymysql")
cursor = conn.cursor()#操作数据需要使用这个,链接是通道,他就是操作的手
sql = "select * from userinfo where username= %s and passwd= %s" #这里的字符串占位符不需要加引号
# select * from userinfo where username='uu' or 1=1 -- ' and password='%s'
cursor.execute(sql,[user,pwd])#这里的excute只能接受2或3个参数,所以账户信息需要使用列表传入
result = cursor.fetchone()#只拿第一条的查询结果
cursor.close()
conn.close()

if result:
    print('登录成功')
else:
    print('登录失败')

是的报到方式参数自动传入

  使用pymysql进行增删改查

  以pymysql的操作着加进删改对数据库进行了转移操作,我们必须要拓展付出的操作。

  commit()方法:在数据库里多、删、改的下,必须要拓展提交,否则插入的数据未奏效。

sqlite 89sqlite 90

import pymysql
config={
    "host":"127.0.0.1",
    "user":"jeff",
    "password":"jeff@123",
    "database":"dbforpymysql"
}
db = pymysql.connect(**config)
cursor = db.cursor()
sql = "INSERT INTO userinfo(username,passwd) VALUES('jack','123')"
cursor.execute(sql)
db.commit()  #提交数据
cursor.close()
db.close()
#或者在execute提供插入的数据
import pymysql
config={
    "host":"127.0.0.1",
    "user":"jeff",
    "password":"jeff@123",
    "database":"dbforpymysql"
}
db = pymysql.connect(**config)
cursor = db.cursor()
sql = "INSERT INTO userinfo(username,passwd) VALUES(%s,%s)"
cursor.execute(sql,("bob","123"))
db.commit()  #提交数据
cursor.close()
db.close()
#再或者添加多行信息
import pymysql
config={
    "host":"127.0.0.1",
    "user":"jeff",
    "password":"jeff@123",
    "database":"dbforpymysql"
}
db = pymysql.connect(**config)
cursor = db.cursor()
sql = "INSERT INTO userinfo(username,passwd) VALUES(%s,%s)"
cursor.executemany(sql,[("tom","123"),('tony','123')])
db.commit()  #提交数据
cursor.close()
db.close()

插的示范

  execute()和executemany()都见面回去给影响的行数:

sqlite 91sqlite 92

import pymysql
config={
    "host":"127.0.0.1",
    "user":"jeff",
    "password":"jeff@123",
    "database":"dbforpymysql"
}
db = pymysql.connect(**config)
cursor = db.cursor()
sql = "delete from userinfo where username=%s"
r=cursor.executemany(sql,("toff",'ton'))
print(r)
db.commit()  #提交数据
print(r)
cursor.close()
db.close()
#这两个r都是2

给影响行数

  调用游标的lastrowid可以抱最后一软自增的ID。

print("the last rowid is ",cursor.lastrowid)
#the last rowid is  10

  pymysql的查操作

  查操作主要是三种绑定方法。

fetchone():获取下一行数据,第一次为首行;
fetchall():获取所有行数据源
fetchmany(4):获取下4行数据

  fetchone和python中的迭代器取值很相似每次都取出一行数。

  fetchall类似于文件之读取操作,一不好取出所有数据,第二不良施行得不顶价值。

  默认情况下,我们沾到的返回值是元组,只能望每行的数,却无掌握各个一样排代表的是呀,这个时段可使用以下方法来回到字典,每一行的多少还见面转一个字典:

cursor = db.cursor(cursor=pymysql.cursors.DictCursor)  #在实例化的时候,将属性cursor设置为pymysql.cursors.DictCursor

  使用fetchall获取所有行的数量,每一行都让充分成一个字典放在列表中:

sqlite 93sqlite 94

import pymysql
config={
    "host":"127.0.0.1",
    "user":"jeff",
    "password":"jeff@123",
    "database":"dbforpymysql"
}
db = pymysql.connect(**config)
cursor = db.cursor(cursor=pymysql.cursors.DictCursor)  #在实例化的时候,将属性cursor设置为pymysql.cursors.DictCursor
sql = "select * from userinfo"
cursor.execute(sql)
data=cursor.fetchall()
print(data)
cursor.close()
db.close()
输出结果:
[{'id': 1, 'username': 'frank', 'passwd': '123'}, {'id': 2, 'username': 'rose', 'passwd': '321'}, 。。。

字典形式读取数据

  和朗诵博文件时之seek一样,取值的时段吗堪移动取值位置。

cursor.scroll(1,mode='relative')  # 相对当前位置移动
cursor.scroll(2,mode='absolute') # 相对绝对位置移动
第一个值为移动的行数,整数为向下移动,负数为向上移动,mode指定了是相对当前位置移动,还是相对于首行移动

  数据库的操作为可以使用上下文管理:

with db.cursor(cursor=pymysql.cursors.DictCursor) as cursor:  #获取数据库连接的对象
    sql = "SELECT * FROM userinfo"   
    cursor.execute(sql)
    res = cursor.fetchone()
    print(res)
    cursor.scroll(2,mode='relative')
    res = cursor.fetchone()
    print(res)
    cursor.close()
db.close()

 MySQL多表查询

  创建测试数据库。

sqlite 95sqlite 96

#建表
create table department(
id int,
name varchar(20) 
);

create table employee(
id int primary key auto_increment,
name varchar(20),
sex enum('male','female') not null default 'male',
age int,
dep_id int
);

#插入数据
insert into department values
(200,'技术'),
(201,'人力资源'),
(202,'销售'),
(203,'运营');

insert into employee(name,sex,age,dep_id) values
('egon','male',18,200),
('alex','female',48,201),
('wupeiqi','male',38,201),
('yuanhao','female',28,202),
('liwenzhou','male',18,200),
('jingliyang','female',18,204)
;


#查看表结构和数据
mysql> desc department;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | varchar(20) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+

mysql> desc employee;
+--------+-----------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------+-----------------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(20) | YES | | NULL | |
| sex | enum('male','female') | NO | | male | |
| age | int(11) | YES | | NULL | |
| dep_id | int(11) | YES | | NULL | |
+--------+-----------------------+------+-----+---------+----------------+

mysql> select * from department;
+------+--------------+
| id | name |
+------+--------------+
| 200 | 技术 |
| 201 | 人力资源 |
| 202 | 销售 |
| 203 | 运营 |
+------+--------------+

mysql> select * from employee;
+----+------------+--------+------+--------+
| id | name | sex | age | dep_id |
+----+------------+--------+------+--------+
| 1 | egon | male | 18 | 200 |
| 2 | alex | female | 48 | 201 |
| 3 | wupeiqi | male | 38 | 201 |
| 4 | yuanhao | female | 28 | 202 |
| 5 | liwenzhou | male | 18 | 200 |
| 6 | jingliyang | female | 18 | 204 |
+----+------------+--------+------+--------+

测试数据表

  多表连接查询。

外链接语法

SELECT 字段列表
    FROM 表1 INNER|LEFT|RIGHT JOIN 表2
    ON 表1.字段 = 表2.字段;

   交叉连接:不适用其他匹配原则。生成笛卡尔积。

sqlite 97sqlite 98

mysql> select * from employee,department;
+----+------------+--------+------+--------+------+--------------+
| id | name       | sex    | age  | dep_id | id   | name         |
+----+------------+--------+------+--------+------+--------------+
|  1 | egon       | male   |   18 |    200 |  200 | 技术         |
|  1 | egon       | male   |   18 |    200 |  201 | 人力资源     |
|  1 | egon       | male   |   18 |    200 |  202 | 销售         |
|  1 | egon       | male   |   18 |    200 |  203 | 运营         |
|  2 | alex       | female |   48 |    201 |  200 | 技术         |
|  2 | alex       | female |   48 |    201 |  201 | 人力资源     |
|  2 | alex       | female |   48 |    201 |  202 | 销售         |
|  2 | alex       | female |   48 |    201 |  203 | 运营         |
|  3 | wupeiqi    | male   |   38 |    201 |  200 | 技术         |
|  3 | wupeiqi    | male   |   38 |    201 |  201 | 人力资源     |
|  3 | wupeiqi    | male   |   38 |    201 |  202 | 销售         |
|  3 | wupeiqi    | male   |   38 |    201 |  203 | 运营         |
|  4 | yuanhao    | female |   28 |    202 |  200 | 技术         |
|  4 | yuanhao    | female |   28 |    202 |  201 | 人力资源     |
|  4 | yuanhao    | female |   28 |    202 |  202 | 销售         |
|  4 | yuanhao    | female |   28 |    202 |  203 | 运营         |
|  5 | liwenzhou  | male   |   18 |    200 |  200 | 技术         |
|  5 | liwenzhou  | male   |   18 |    200 |  201 | 人力资源     |
|  5 | liwenzhou  | male   |   18 |    200 |  202 | 销售         |
|  5 | liwenzhou  | male   |   18 |    200 |  203 | 运营         |
|  6 | jingliyang | female |   18 |    204 |  200 | 技术         |
|  6 | jingliyang | female |   18 |    204 |  201 | 人力资源     |
|  6 | jingliyang | female |   18 |    204 |  202 | 销售         |
|  6 | jingliyang | female |   18 |    204 |  203 | 运营         |
+----+------------+--------+------+--------+------+--------------+

笛卡儿积

  内接连:只连接匹配的实行,找点儿摆设表共有的一些,相当给以标准由笛卡尔积结果受筛选出了是的结果。

sqlite 99sqlite 100

mysql> select employee.id,employee.name,employee.age,employee.sex,department.name from employee inner join department on employee.dep_id=department.id; 
+----+-----------+------+--------+--------------+
| id | name      | age  | sex    | name         |
+----+-----------+------+--------+--------------+
|  1 | egon      |   18 | male   | 技术         |
|  2 | alex      |   48 | female | 人力资源     |
|  3 | wupeiqi   |   38 | male   | 人力资源     |
|  4 | yuanhao   |   28 | female | 销售         |
|  5 | liwenzhou |   18 | male   | 技术         |
+----+-----------+------+--------+--------------+

#上述sql等同于
mysql> select employee.id,employee.name,employee.age,employee.sex,department.name from employee,department where employee.dep_id=department.id;

内链接

  外链接的误连接:优先显示左表全部记录,以左表为以,即找有富有职工信息,当然包括无机构的职工。本质就是是:在内连接的根基及多左边有右边没有的结果。

sqlite 101sqlite 102

mysql> select employee.id,employee.name,department.name as depart_name from employee left join department on employee.dep_id=department.id;
+----+------------+--------------+
| id | name       | depart_name  |
+----+------------+--------------+
|  1 | egon       | 技术         |
|  5 | liwenzhou  | 技术         |
|  2 | alex       | 人力资源     |
|  3 | wupeiqi    | 人力资源     |
|  4 | yuanhao    | 销售         |
|  6 | jingliyang | NULL         |
+----+------------+--------------+

左连接

  同理可得下手连接,通常理解错连接就可以了,要采取右连接把少摆设表倒置就得得同的结果了。

  全外连接:显示左右少单说明全部记下,在内连接的底子及搭左边有右边没有底同右侧有左没有底结果。在MySQL中运用union完成全外连接。

sqlite 103sqlite 104

select * from employee left join department on employee.dep_id = department.id
union
select * from employee right join department on employee.dep_id = department.id
;
#查看结果
+------+------------+--------+------+--------+------+--------------+
| id   | name       | sex    | age  | dep_id | id   | name         |
+------+------------+--------+------+--------+------+--------------+
|    1 | egon       | male   |   18 |    200 |  200 | 技术         |
|    5 | liwenzhou  | male   |   18 |    200 |  200 | 技术         |
|    2 | alex       | female |   48 |    201 |  201 | 人力资源     |
|    3 | wupeiqi    | male   |   38 |    201 |  201 | 人力资源     |
|    4 | yuanhao    | female |   28 |    202 |  202 | 销售         |
|    6 | jingliyang | female |   18 |    204 | NULL | NULL         |
| NULL | NULL       | NULL   | NULL |   NULL |  203 | 运营         |
+------+------------+--------+------+--------+------+--------------+

#注意 union与union all的区别:union会去掉相同的纪录

全外连接

  子查询有关

  关于子查询的几个概念:

  1.子查询是以一个查询语句子嵌套在另一个查询语句子被。

  2.内层查询语句之询问结果,可以吧外层查询语句提供查询条件。

  3.子查询中可以分包:IN、NOT IN、ANY、ALL、EXISTS 和 NOT
EXISTS等关键字。

  4.尚得蕴涵比较运算符:= 、 !=、> 、<等。

sqlite 105sqlite 106

#查询employee表,但dep_id必须在department表中出现过
select * from employee
    where dep_id in
        (select id from department);

带来IN关键字之子查询

sqlite 107sqlite 108

#比较运算符:=、!=、>、>=、<、<=、<>
#查询平均年龄在25岁以上的部门名
select id,name from department
    where id in 
        (select dep_id from employee group by dep_id having avg(age) > 25);

#查看技术部员工姓名
select name from employee
    where dep_id in 
        (select id from department where name='技术');

#查看不足1人的部门名
select name from department
    where id in 
        (select dep_id from employee group by dep_id having count(id) <=1);

拉动比较运算符的子查询

sqlite 109sqlite 110

#EXISTS关字键字表示存在。在使用EXISTS关键字时,内层查询语句不返回查询的记录。
而是返回一个真假值。True或False
#当返回True时,外层查询语句将进行查询;当返回值为False时,外层查询语句不进行查询
#department表中存在dept_id=203,Ture
mysql> select * from employee
    ->     where exists
    ->         (select id from department where id=200);
+----+------------+--------+------+--------+
| id | name       | sex    | age  | dep_id |
+----+------------+--------+------+--------+
|  1 | egon       | male   |   18 |    200 |
|  2 | alex       | female |   48 |    201 |
|  3 | wupeiqi    | male   |   38 |    201 |
|  4 | yuanhao    | female |   28 |    202 |
|  5 | liwenzhou  | male   |   18 |    200 |
|  6 | jingliyang | female |   18 |    204 |
+----+------------+--------+------+--------+

#department表中存在dept_id=205,False
mysql> select * from employee
    ->     where exists
    ->         (select id from department where id=204);
Empty set (0.00 sec)

带EXISTS关键字的子查询

 

网站地图xml地图