Go to comments

兄弟连 SQL语言的设计与编写

一、结构化查询语言 SQL(structured query language)

SQL 语句的主要用途是,构造各种数据库的操作的指令,sql 语句分四种(通常把 DML 和 DQL 放到一起,作为增删改查来看)


1. DDL(Data Definition Language)数据库定义语言


用于定义和管理数据对象的,

什么是数据对象呢?

库是对象、表是对象、索引是对象、视图是对象,

比如管理库的时候有 CREATE 创建、DROP 删除、ALTER 更改,也就是跟数据库、表、视图这些对象有关的称为 DDL 语句


2. DML(Data Manipulation Language)数据操作语言


什么是数据操作语言?

数据操作语言是我们用的机率比较多的,比如最常使用的查询 select、插入INSTER、更新 update,删除 delete,就是跟表中的数据和记录有关的


3. DQLDimensional Query Language数据查询语言


用于查询数据库中所包含的数据,因为 60% 的时候在使用 SELECT 查询语句,所以单独拿出来,而且查询语句是相当复杂的包括

单表查询

链接查询

嵌套查询集合查询

还有各种各样复杂程度不同的数据查询


4. DCLData Control Language数据库控制语言


是用来管理数据库的,包含管理权限及数据更改,

比如赋予个用户什么权限,

那个用户可以链接,链接之后可以管理哪个数据库,

个库里的表有什么操作的权限,

还有事务处理的提交,回滚等等操作都属于 DCL,例如 crant、revoke、commit、rollback 等语句


1、DDL 语句

先创建一个数据库,

然后在创建一个“商品分类表”和“商品表”


数据库名称是 dbshop,

创建库就属于创建一个对象,这个属于DDL 语句

create database IF NOT EXISTS dbshop charset utf8;

use dbshop;

\s;


产品分类(类别)表 cats

id

pid       父id

name  类别名称

desn    类别的描述

给 id 字段设置成主键

name 和 pid  创建索引

create table cats(
  id int unsigned not null auto_increment,
  pid int not null default '0',
  name varchar(60) not null default '',
  desn text not null default '',
  primary key(id),
  index nameid(name,pid)
)engine=InnoDB default charset=utf8;


产品表 products

id

cid       产品所在的类别id

name   产品名称

price    产品价格

num    产品数量

desn    产品介绍(这个字段不设置缺省值,如果不插入数据默认为 null 空,后面学习查询的时候有用

ptime   产品发布时间

id 字段加上索引

通常搜索产品按照名字 name、价钱 proce 去查找,所以这两个字段加上普通索引

create table products(
  id int unsigned not null auto_increment,
  cid int not null default '0',
  name varchar(60) not null default '',
  price double(7,2) not null default '0.00',
  num int not null default '0',
  desn text,
  ptime int not null default '0',
  primary key(id),
  key pname(name, price)
)engine=InnoDB default charset=utf8;


创建库、创建表是 DDL 语句,

下面 DML 语句是插入 insert、更新 update、删除 delete


2、DML 语句

insert 插入语法   insert into 表名 ( [字段列表] ) values ( 值列表 )  

1. 字段列表是可选的

2. 值列表是必须


插入的三个特点

1. 如果表名后没有给出“字段列表”,则“值列表”必须列出所有字段的值,必须按表中默认的字段顺序插入

insert into cats values(null, 0, 'soft', '这是一个软件分类');


2. 所有需要写“字段名”的地方都不要加单引号或双引号,但所有值建议都要以字符串形式是使用

为什么所有值都要以字符串形式使用?

因为 Mysql 会自动类型转换,比如数字 1 加数字 1,得到的结果是 2

select 1 + 1;

+-------+

 | 1 + 1  |

+-------+

 |     2    |

+-------+


数字 1 加上字符串的 '1' ,还是等于 2,因为 mysql 会根据环境自动将类型转成整数

select 1 + '1';

+---------+

 | 1 + '1'   |

+---------+

 |       2     |

+---------+


所以插入字符串的 '1',会自动转成整数型

insert into cats (id, pid, name, desn) values (null, '1', 'JAVA', 'java分类');


3. 建议插入数据时最好给出“字段列表”,则值要和“字段列表”对应即可,可以不按照表中字段的顺序

insert into cats (pid, name) values ('1', 'PHP');


字段列表”可以不按表中字段的顺序,后面的值与前面的字段一一对应

insert into cats (name, pid) values ('JAVASCRIPT', '1');


另外还可以一起插入多个值列表

 insert into 表名 ( [字段名] ) values ( 值列表1 ), ( 值列表2 ), ( 值列表3 ) 

insert into cats (pid, name, desn)
values
('2', 'J2se', 'java类pid是2'),
('2', 'J2me', 'java类pid是2'),
('2', 'J2me', 'java类pid是2'),
('3', 'smarty', 'PHP类pid是3'),
('3', 'thinkphp', 'PHP类pid是3');

select * from cats;

+----+-----+------------+------------------+

 | id   | pid   | name         | desn                   |

+----+-----+------------+------------------+

 |  1   |   0    | soft            | 这是一个软件分类|

 |  2   |   1    | JAVA          | java分类             |

 |  3   |   1    | PHP           | NULL                  |

 |  4   |   1    | JAVASCRIPT | NULL               |

 |  5   |   2    | J2se           |   java类pid是2    |

 |  6   |   2    | J2me         |   java类pid是2    |

 |  7   |   2    | J2me         |   java类pid是2    |

 |  8   |   3    | smarty       |  PHP类pid是3    |

 |  9   |   3    | thinkphp   |  PHP类pid是3     |

+----+-----+------------+------------------+


update 更新修改语句  update 表名 set 字段 = '值'  [,字段2 = '值2'] where 字段名 = '值'

1. 可以更新多个字段

2. 更新语句必须给 where 条件,条件可以指定一条,也可以指定多条


如果执行,所有的 name 都更新为 'J2ee pid是2' 了

update cats set
  name = 'J2ee pid是2';


where 条件指定要更改的记录

update cats set
  name = 'J2ee',
  desn='J2ee属于java,所以pid是2'
  where id = 6;


where 条件可以用比较运算符“并且”更新了多条记录

update cats set desn='属于java,pid是2' where id >= 5 && id <=7;


不仅是 update 更新语句需要条件,delete 删除语句也需要条件,删除语句的条件跟更新语言的条件一样的,删除指定的记录


update语句、delete语句如果不给 where 条件

更新语句,整个表的数据都会被改变

删除语句,整个表所有的记录都会被删除(如果需要删除整个表这个写法效率还比较低,不如用 truncate


delete 删除语句  delete from 表名 [ where 字段名 = '值' ] 

如果直接这样写就把表删空了

delete from cats; -- 不要执行,执行后面的练习没法做了


如果要清空表

 truncate table 表名   这种语句效果会更高(自动增长的 id 字段从 1 开始


所以删除语句一定要给一个条件

delete from cats where id > 8;


在学查询语句之前要先有数据,所以先给 products 商品表多插入一些数据

insert into 
products(cid, name, price, num, desn, ptime)
values
(1, 'javaOne', '34.5', '10', 'very good', '1631413148'),
(1, 'javaTwo', '414.56', '30', 'very good', '1631413180'),
(1, 'javaThree', '441.56', '50', 'very good', '1631413180'),
(1, 'javaFour', '144.56', '30', 'very good', '1631413180'),
(3, 'dedeCms', '44.56', '30', 'very good', '1631413180'),
(3, 'phpCms', '44.56', '30', 'very good', '1631413180'),
(3, 'ecshop', '84.56', '30', 'very good', '1631413201'),
(4, 'jquery', '244.56', '8', 'very good', '1631413201'),
(4, 'Vue', '44.56', '30', 'veryod', '1631413201'),
(4, 'React', '944.56', '30', 'very good', '1631413201'),
(4, 'bootStrap', '4444.56', '30', 'very good', '1631413201'),
(5, 'J2seONE', '544.56', '30', 'very good', '1631413201'),
(5, 'J2seTwo', '44.56', '30', 'very good', '1631413201'),
(5, 'J2seThree', '44.56', '90', 'very good', '1631413201'),
(5, 'J2seFour', '44.56', '30', 'very good', '1631413201'),
(5, 'J2seFive', '4324.56', '30', 'very good', '1631413243'),
(5, 'J2seFix', '454.56', '30', 'very good', '1631413243'),
(6, 'J2eeOne', '44.56', '30', 'very good', '1631413243'),
(6, 'J2eeTwo', '454.56', '30', 'very good', '1631413243'),
(6, 'J2eeThree', '4.56', '30', 'very good', '1631413243'),
(6, 'J2eeFour', '44.56', '30', 'very good', '1631413243'),
(6, 'J2eeFive', '494.56', '30', 'very good', '1631413201'),
(7, 'J2meOne', '48.56', '30', 'very good', '1631413262'),
(7, 'J2meTwo', '324.56', '30', 'very good', '1631413262'),
(3, 'smartyOne', '4432.56', '30', 'very good', '1631413262'),
(3, 'smartyTwo', '434.56', '30', 'very good', '1631413262'),
(3, 'smartyThree', '442.56', '30', 'very good', '1631413262');


插入、更新、删除写法比较固定,给一些简单条件就行了,

最复杂的就是 select 查询语句


 ? show select;   看一下查询语句的语法

select [ALL | DISTINCT]    - [中括号] 的部分表示可选的部分

{* | table.* | [table.]field1[as alias1][,[table.]field2[as alias2]][……]}  -{大括号} 部分表示必须从中选择一个,如果有多个中间都是用逗号 ',' 隔开的,

FROM 表名1, [表名2] - from 后面的多个表名,有可能是联合查询,中间也是使用逗号隔开

[WHERE] - 条件

[GROUP BY]  - 分组条件

[HAVING]

[ORDER BY]  - 排序的条件

[LIMLT count]  - 查询的数量


二、列出要查询的字段

上面学的是 sql 语句中的 DDL 还有 DML,这节课学 DQL 命令,也就是查询数据表中的数据,

查询数据表中的数据,可以简单的单表查询,也可以复杂的多表查询和嵌套查询,

所以 select 查询检索,是 sql 语句的核心,使用 sql 语句中使用频率最高,达到 60% 都在使用 select 语句


通过适当的 sql 语句查询的编写,

可以让数据库服务器根据用户的需求,检索出所需要的一些数据资料,

并按照用户指定的格式进行整理并返回,所以 sql 语句可以对数据表或者视图进行检索


用 * 星号选择所有字段

select * from products;


用 * 星号有两个弊端

1. 所有字段全部查询出来,不用的字段也全部查询出来了,浪费效率

2. 会按照表的字段顺序显示出数据 cid, name, price...,数据都查询出来了


安自己指定的字段查询,多个字段用逗号隔开,

比如就查询 name,price 两个字段,这样不仅效率提高了,读着也清晰

select name, price from products;

只查询两个字段

+-------------+---------+

 | name           | price     |

+-------------+---------+

 | J2eefive       |  494.56 |

 | J2eefour      |   44.56  |

 | J2eeone      |   44.56  |

…………


还可以指定字段的顺序,

比如重点是看价格,就把价格字段 price 放到前面

select price, name from products;

就按照我们指定的顺序查询出来了

+---------+-------------+

 | price      | name          |

+---------+-------------+

 |  494.56  | J2eefive      |

 |   44.56   | J2eefour     |

 |   44.56   | J2eeone     |

 …………


字段列表可以加  表名.字段名 

单表查询不用使用表名,也可以使用表名,用   table.* (products.*)也是一样的

select products.* from products;


当然一个表的时候是没有必要  表名.字段名 

这里是没有必要的,因为是单表查询通常都不使用 字段名.表名(但使用自己指定的 字段列表 是比较有用的

select products.price, products.name from products;


三、字段别名

如果觉得字段的名字不好,可以给字段起别名


怎么起别名呢?

比如价钱 price 起别名为 bookprice,中间加关键字 as

select price as bookprice from products;

as 后面的 bookprice 就是别名

+-----------+

 | bookprice|

+-----------+

 |   4444.56 |

 |     44.56   |

 |     84.56   |

 ……


给 name 字段起别名为 bookname

select price as bookprice, name as bookname from products;

+-----------+-------------+

 | bookprice| bookname  |

+-----------+-------------+

 |   4444.56 | bootStrap    |

 |     44.56   | dedecms      |

 |     84.56   | ecshop         |

 ……


别名前面也可以不加 as 关键字,直接加空格也是可以的,前面是原字段名后面是起的别名

select price bookprice, name bookname from products;


什么时候用到别名?

1. 多表查询的时候,两个表字段名冲突,就必须起别名

2. 关键字冲突的时候,有时候查 Mysql 版本(版本的括号),发生冲突的时候也要用到别名


不仅是“字段”可以起别名,“表”也可起别名,当然也是在多表查询的时候起别名


四、DISTINCT 取消重复的数据

如果 select 语句返回的记录结果中包含重复的值,

1. 可以使用关键字 distinct 取消重复的数据,重复的数据只返回一个,

2. 但是不是针对单独的某一个字段取消重复的,而是针对整个记录取消重复的


比如价钱 44.56 有很多重复的

select price, name from products;

表里面总共有 27 条记录

+---------+-------------+

 | price      | name          |

+---------+-------------+

 | 4444.56 | bootstrap   |

 |   44.56   | dedecms    |

 |   84.56   | ecshop       |

 |  494.56  | J2eefive      |

 |   44.56   | J2eefour     |

 |   44.56   | J2eeone     |

 …………

27 rows in set (0.107 sec)


select 语句后面默认的是 ALL 意思是所有的

 select all price, name from products   现在不用默认的用 distinct

select distinct price, name from products;

没有起到效果,还是27条记录没有取到去重复的效果?

+---------+-------------+

 | price      | name          |

+---------+-------------+

 | 4444.56 | bootstrap   |

 |   44.56   | dedecms    |

 |   84.56   | ecshop       |

 |  494.56  | J2eefive      |

 |   44.56   | J2eefour     |

 |   44.56   | J2eeone     |

 …………

27 rows in set (0.107 sec)   还是 27 条记录?


因为 distinct 的作用是整行不重复,

现在没有那个行是重复的,比如价钱 price 字段 44.56 重复,但是后面的 name 字段的值不重复,

所以是整条记录上不重复,并不是某一单独字段


比如就单独查一个价钱字段 price,一行就找不到重复的了

select distinct price from products;

+---------+

 | price     |

+---------+

 | 4444.56 |

 |   44.56   |

 |   84.56   |

 |  494.56  |

 |    4.56    |

 |  454.56  |

 |   48.56   |

 |  324.56  |

 | 4324.56 |

 |  544.56  |

 |  144.56  |

 |   34.50   |

 |  441.56  |

 |  414.56  |

 |  244.56  |

 |  944.56  |

 | 4432.56 |

 |  442.56  |

 |  434.56  |

+---------+

19 rows in set (0.011 sec)


关键字 distinct 查询范围是整个查询的列表,并不是单独的一列,

如果同时对两列数据查询的时候,使用了 distinct 关键字,将返回这两列数据唯一的一个组合,

所以 distinct 不是每一个字段都能加的,它是针对整个记录的


五、SQL 语句中使用表达式

在 insert 增、delete 删、update 改、select 查语句中,

可以使用任意的算术运行符号,可以使用条件运算符,还可以使用逻辑运算符号,跟程序中是一样的


select 1+1;

+-----+

 | 1+1 |

+-----+

 |   2   |

+-----+


select 10*5;

+------+

 | 10*5 |

+------+

 |   50   |

+------+


select 9*8;

+-----+

 | 9*8  |

+-----+

 |  72  |

+-----+

加、减、乘、除、取余都可以,这是最常用,最简单的的用法


1. 算数运算


什么时候用算术运算符

比如 update 更新语句,num 字段当做变量加 1 再赋给 num 字段。这个的语法可以做浏览页面时的计数器,每次刷新一次页面执行一下 num + 1 的更新语句

update products set num = num+1 where id = 27;
update products set num = num+1 where id = 27;
update products set num = num+1 where id = 27;

select id, num from products where id = 27;

+----+-----+

 | id   | num |

+----+-----+

 | 27  |  33   |   每执行一次 sql 语句,num 列就累加 1 一次

+----+-----+


select 查询语句也可以用算数计算,

比如查询打八折后的价钱,然后起一个别名 dzprice

select name, price, price*0.8 dzprice from products;

+-------------+---------+---------+

 | name          | price      | dzprice  |

+-------------+---------+---------+

 | bootstrap   | 4444.56  | 3555.65 |

 | dedecms    |   44.56    |   35.65   |

 | ecshop       |   84.56    |   67.65   |

 …………


2. 比较运算符、逻辑运算符


可以在 where 条件后面用比较运算符,查询条件是  id > 4 或 id < 10   用到了比较运算符和逻辑运算符

select id, name, price, price*0.8 dzprice from products where id > 4 && id < 10;

+----+---------+--------+---------+

 | id   | name     | price    | dzprice |

+----+---------+--------+---------+

 |  5   | dedecms|  44.56  |   35.65 |

 |  6   | phpcms  |  44.56  |   35.65 |

 |  7   | ecshop   |  84.56  |   67.65 |

 |  8   | jqurey    | 244.56  |  195.65 |

 |  9   | vue         |  44.56  |   35.65 |

+----+---------+--------+---------+

乘号是算术运算符、大于小于是比较运算符、&& 是逻辑运算符,还可以用位运算符


上面说为什么要起别名

比如查询关键字的时候,看一下 mysql 版本和 1.23 乘 10 

select version(), 1.23 * 10;

version()   这个字段名有括号,在 PHP 程序里有可能是数组的下标

1.23 * 10   这个字段名有点有星号

+------------------+-----------+

 | version()             | 1.23 * 10  |

+------------------+-----------+

 | 5.7.18-cynos-log|     12.30   |

+------------------+-----------+


如果在 PHP 程序里,返回的字段名列表包含了括号、点、星号,这些特殊字符,

如果将这些 sql 语句嵌入到 PHP 中使用,会和 PHP 的运算符号混淆,极易产生错误,因此遇到这些字段名不是标准字符串,有些特殊符号的情况下,就需要给字段起别名


给两个字段起别名

select version() mysql_version, 1.23 * 10 as experssion;

+------------------+------------+

 | mysql_version    | experssion |

+------------------+------------+

 | 5.7.18-cynos-log|      12.30    |

+------------------+------------+


总结,

在 select 后面和 where 后面,都可以使用各种运算符


六、WHERE 条件

select 语句、update 语句、delete 语句,这三个语句都可以使用 where 字句(在 select 语句怎么使用 where,别的语句就怎么使用


因为可以使用 where 子句去检索条件,

实现从数据库列表中检索出符合条件的记录,条件可以由一个或多个由逻辑运算表达式组成的。


逻辑运算符有(单词和符号的作用是一样的),在 where 字句中使用运算符号是将多个条件组合

&&||!
ANDORNOT


比较运算符号用的也比较多,比 PHP 程序里的要多

符号作用
=等于

等号在字段列表里是赋值,在 where 后面是判断等于的意思,

再 mysql 里和程序中的两个等号 == 写法不一样

<=>特殊的等于和等号 = 作用一样,但 <=> 可以用于 NULL 值的比较



!=不等于
<>也是不等于



<大于
<=大于等于
>小于
>=小于等于


下面的“比较运算符”是数据库中有的而程序中没有的

符号作用
IS NULL查询空

where desn is null

查询 desn字段是 null 的值

IS NOT NULL查询非非空

desn is not nul

l查询 desn字段不是 null 的值

BETWEEN AND

NOT BETWEEN AND

LIKE两个通配符号
1. _ 任意一个字符)
2. % 另个或多个任意字符

NOT LIKE

IN

REGEXP 或  RLIKE正则表达式


“比较运算符”在 where 条件里用的是比较多的,通常是和“逻辑运算符”串起来使用


需要注意不管是更新条件、删除条件、还是查询条件,也就是说在构造搜索条件的时候

1. 如果是算术运算,只能对数值类型进行运算,

     并且只能在相同的数据类型之间进行记录的比较,比如字符串和数值不能进行比较,除非他们转换成相同的数据类型

2. 如果使用字符串做为检索条件查询的时候,则值必要要用单引号括起来,

     而对数值类型数据,单引号则不是必须的(它会自动往字符串类型转)


比如挑选一些 100 元以下的产品,用的一个条件的运算符  price < 100   

select id, price, name from products where price < 100;

+----+-------+-----------+

 | id   | price   | name       |

+----+-------+-----------+

 |  5   | 44.56  | dedeCms  |

 |  7   | 84.56  | ecshop     |

 | 21  | 44.56  | J2eeFour  |

 | 18  | 44.56  | J2eeOne   |

 | 20  |  4.56   | J2eeThree |

 | 23  | 48.56  | J2meOne  |

 | 15  | 44.56  | J2seFour   |

 | 14  | 44.56  | J2seThree |

 | 13  | 44.56  | J2seTwo   |

 |  1   | 34.50  | javaOne   |

 |  6   | 44.56  | phpCms   |

 |  9   | 44.56  | Vue          |

+----+-------+-----------+


如果想挑选“大于 50 小于 100”的商品,就要用多个条件运算符   price > 50 and price < 100  

select id, price, name from products where price > 50 and price < 100;

只有一个符合条件的

+----+-------+--------+

 | id   | price   | name   |

+----+-------+--------+

 |  7   | 84.56   | ecshop|

+----+-------+--------+


= 等号

这里的等号 = 和程序中的两个等号 == 一样,只是写法不一样,比如   id = 10 

select id, price, name from products where id = 10;

+----+--------+-------+

| id | price  | name  |

+----+--------+-------+

| 10 | 944.56 | React |

+----+--------+-------+


!= 不等于

查询条件,id 不等于10 的

select id, price, name from products where id != 10;

除了 id 不等于 10 的全部查询出来了,

查询返回 26 rows in set (0.00 sec)


<>  不等于

<> 和 != 是别名的关系,用这个 <> 不等于也是返回 26 rows in set (0.00 sec)

select id, price, name from products where id <> 10;


&&

&& 和 and 是一样的,这两个是别名的关系

 price > 50 and price < 100     

 price > 50 && price < 100 

select id, price, name from products where price > 50 && price < 100;

+----+-------+--------+

 | id   | price   | name   |

+----+-------+--------+

 |  7   | 84.56  | ecshop |

+----+-------+--------+


and 和 && 是别名的关系

!= 和 <> 也是别名的关系

下面看一下 is null 和 is not null


4. 数据库中的运算符


插入几行字段有 null 值的数据,

设计表的时候其只有 desn 字段没有设置缺省值,

现在只插入一个 name 字段,其他的字段都有缺省值,只有 desn 没有设置缺省值默认的是 null 空

insert into products (name) values('a');
insert into products (name) values('b');
insert into products (name) values('c');

select id, name, price, num, desn from products;

desn 字段没有指定默认值,没有默认值默认的是 null

+----+-------------+---------+-----+-----------+

 | id   | name           | price     | num | desn         |

+----+-------------+---------+-----+-----------+

 …………

 | 26  | smartytwo   |  434.56  |  30   | very good|

 | 27  | smartythree |  442.56  |  30   | very good|

 | 28  | a                  |    0.00    |   0    | NULL        |

 | 29  | b                  |    0.00    |   0    | NULL        |

 | 30  | c                  |    0.00    |   0    | NULL        |

+----+-------------+---------+-----+-----------+

30 rows in set (0.00 sec)


NULL 空值是不能用 = 等号处理,条件  desn = null  查询不出来

select id, name, desn from products where desn = null;

返回 Empty set (0.011 sec) 没有查出来


is null

null 的值不能用 = 等号去查,NULL 是一种值,遍历条件的时候只能用   desn is null  ,desn 字段是空的的记录

select id, name, desn from products where desn is null;

+----+------+------+

 | id   | name | desn |

+----+------+------+

 | 28  | a        | NULL|

 | 29  | b       | NULL|

 | 30  | c        | NULL|

+----+------+------+


is not null

查询非空用用 is not null

select id, name, desn from products where desn is not null;

27 rows in set (0.00 sec) 非空的数据都查出来了共27条


null 值处理比较麻烦,所以 创建表的时候,尽量使用非空(not null)

1. 非空的好处是有默认的值,转成程序的时候,会转成对应的数据类型

2. 而 null(空)转成程序,有可能转成 0,有可能转成 null(PHP里面的空),有可能会转成空字符串,它是不一定的,所以不好处理


<=> 符号是干什么的?

1. <=> 和 = 作用一样,可以判断是否等于 =

2. 也可以判断是否是 null 值


查询 desn 字段值等于 veryod   where desn <=> 'veryod'   字符串 'verupd' 要用引号

select id, name, desn from products where desn <=> 'veryod';

+----+------+--------+

 | id   | name| desn     |

+----+------+--------+

 |  9   | Vue   | veryod |

+----+------+--------+


也可以判断 desn 字段等于 null 空值

select id, name, desn from products where desn <=> null;

+----+------+------+

 | id   | name| desn  |

+----+------+------+

 | 28  | a       | NULL |

 | 29  | b       | NULL |

 | 30  | c        | NULL |

+----+------+------+


between and

查询 id 大于等于 10 并且小于等于 20 的数据,这样的语句就可以用   id between 10  and 20 

select id, name from products where id between 10 and 20;

id 大于 20 和小于 10,包括 10 和 20 的都查询出来了

+----+-----------+

 | id   | name        |

+----+-----------+

 | 10  | React        |

 | 11  | bootStrap |

 | 12  | J2seONE   |

 | 13  | J2seTwo   |

 | 14  | J2seThree |

 | 15  | J2seFour   |

 | 16  | J2seFive    |

 | 17  | J2seFix      |

 | 18  | J2eeOne   |

 | 19  | J2eeTwo   |

 | 20  | J2eeThree |

+----+-----------+


其实没有 between 用 and 也能查询出来  id >= 10 && id <= 20  

select id, name from products where id >= 10 && id <= 20;

+----+-----------+ 

 | id   | name        |

+----+-----------+

 | 10  | React        |

 | 11  | bootStrap |

 | 12  | J2seONE   |

 | 13  | J2seTwo   |

 | 14  | J2seThree |

 | 15  | J2seFour   |

 | 16  | J2seFive    |

 | 17  | J2seFix      |

 | 18  | J2eeOne   |

 | 19  | J2eeTwo   |

 | 20  | J2eeThree |

+----+-----------+


  id between 10 and 20   和   id >= 10 && id <= 20  

两个的作用是一样的,在 10 和 20 之间的数据,

包括两边的边界 10 和 20 


not between

正好是取反,

10 和 20 之间的数据没有了

也包括 10 和 20 都没有了

select id, name from products where id not between 10 and 20;


IN 列表

是用单个处理的   id in(5, 10, 15, 20, 25)   只获取括号里面的这五条

select id, name, price, num from products where id in(5, 10, 15, 20, 25);

+----+-----------+---------+-----+

 | id   | name        | price      | num|

+----+-----------+---------+-----+

 |  5   | dedeCms  |   44.56   |  30  |

 | 10  | React        |  944.56  |  30  |

 | 15  | J2seFour   |   44.56   |  30  |

 | 20  | J2eeThree |    4.56    |  30  |

 | 25  | smartyOne| 4432.56 |  30  |

+----+-----------+---------+-----+


where 条件不仅在 select 语句能用,其它语句里面这些条件也都能用,

比如 update 更新语句   id in(5, 10, 15, 20, 25)   把符合条件的 num 字段值修改为 77

update products set num = 77 where id in(5, 10, 15, 20, 25);

返回 Rows matched: 5  Changed: 5  Warnings: 0 五条记录被更新了


再查询 products 表num 字段被更新了

select id, name, price, num from products where id in(5, 10, 15, 20, 25);

num 字段是 77 了,之前上面是 30 的

+----+-----------+---------+-----+

 | id   | name        | price     | num |

+----+-----------+---------+-----+

 |  5   | dedeCms  |   44.56  |  77   |

 | 10  | React        |  944.56 |  77   |

 | 15  | J2seFour   |   44.56  |  77   |

 | 20  | J2eeThree |    4.56   |  77   |

 | 25  | smartyOne| 4432.56|  77   |

+----+-----------+---------+-----+


delete 删除语句也是一样,

删除的 where 条件为  id in(5, 10, 15)  这三条数据

delete from products where id in(5, 10, 15);

返回 Query OK, 3 rows affected (0.011 sec) 三条语句受到影响


在查询 where 条件为  id in (5, 10, 15, 20, 25)  就剩下 20 和 25 两条数据

select id, name, price, num from products where id in(5, 10, 15, 20, 25);

5、10、15 已经删除不存在了

+----+-----------+---------+-----+

 | id   | name        | price      | num |

+----+-----------+---------+-----+

 | 20  | J2eeThree |    4.56    |  77   |

 | 25  | smartyOne| 4432.56 |  77   |

+----+-----------+---------+-----+


5. 模糊查询


likenot like 是模糊查询,

还有正则 regexprlike 都属于模糊查询中的一种


也就是在 select 语句的 where 从句中,使用 like 对数据库进行模糊查询,将查询的结果锁定在一个范围内,

我们必须在查询条件中,使用下划线 _ 和百分号 % 这两个通配符号

1. 下划线 _ 表示任意一个字符(什么字符都可以匹配出来

2. 百分号 % 可以表示零个或多个任意字符


link

比如查询由“任意6个字符串”组成的名字   name like '______'  

select id, name, price, num from products where name like '______';

+----+--------+--------+-----+

 | id   | name    | price   | num |

+----+--------+--------+-----+

 |  6   | phpCms|  44.56 |  30    |

 |  7   | ecshop |  84.56  |  30    |

 |  8   | jquery  | 244.56  |   8    |

+----+--------+--------+-----+


查询 java 后面跟 3 个字符的  name link 'java___' 

select id, name, price, num from products where name like 'java___';

+----+---------+--------+-----+

 | id   | name     | price    | num |

+----+---------+--------+-----+

 |  1   | javaone |  34.50   |  10   |

 |  2   | javatwo | 414.56  |  30   |

+----+---------+--------+-----+


一个下划线代表任意一个字符,百分号可以代表任意多个字符


比如以 s 结尾的,字母 s 前面可以是任意多个字符  name like '%s' 

select id, name, price, num from products where name like '%s';

+----+--------+-------+-----+

 | id   | name   | price   | num |

+----+--------+-------+-----+

 |  6   | phpcms| 44.56  |  30  |

+----+--------+-------+-----+


名字字段以字母 s 开头的   name like 's%' 

select id, name, price, num from products where name like 's%';

+----+-------------+---------+-----+

 | id   | name           | price     | num |

+----+-------------+---------+-----+

 | 25  | smartyOne   | 4432.56|  77   |

 | 27  | smartyThree |  442.56 |  30   |

 | 26  | smartyTwo   |  434.56 |  30   |

+----+-------------+---------+-----+


以字母 j 开头的   name like 'j%' 

select id, name, price, num from products where name like 'j%';

+----+-----------+---------+-----+

 | id   | name        | price     | num |

+----+-----------+---------+-----+

 |  1   | javaOne    |   34.50   |  10  |

 |  2   | javaTwo    |  414.56  |  30  |

 |  3   | javaThree |  441.56   |  50 |

 |  4   | javaFour   |  144.56   |  30 |

 |  8   | jquery       |  244.56   |   8  |

 | 12  | J2seONE   |  544.56   |  30 |

 | 13  | J2seTwo   |   44.56    |  30 |

 | 14  | J2seThree |   44.56    |  90 |

 | 16  | J2seFive    | 4324.56  |  30 |

 | 17  | J2seFix      |  454.56   |  30 |

 | 18  | J2eeOne   |   44.56    |  30 |

 | 19  | J2eeTwo   |  454.56   |  30 |

 | 20  | J2eeThree |    4.56    |  77  |

 | 21  | J2eeFour   |   44.56   |  30  |

 | 22  | J2eeFive    |  494.56  |  30  |

 | 23  | J2meOne  |   48.56   |  30  |

 | 24  | J2meTwo  |  324.56  |  30  |

+----+-----------+---------+-----+


查询 name 字段包含 PHP 的    name link %php%   % 百分号代表 0 个或多个 PHP

select id, name, price, num from products where name like '%PHP%';

+----+--------+-------+-----+

 | id   | name   | price   | num |

+----+--------+-------+-----+

 |  6   | phpCms| 44.56 |  30   |

+----+--------+-------+-----+


name 字段中包含 java 的  name link %java%   

select id, name, price, num from products where name like '%java%';

+----+-----------+--------+-----+

 | id   | name        | price    | num|

+----+-----------+--------+-----+

 |  1   | javaOne   |  34.50   |  10  |

 |  2   | javaTwo   | 414.56  |  30  |

 |  3   | javaThree | 441.56  |  50  |

 |  4   | javaFour   | 144.56  |  30  |

+----+-----------+--------+-----+


name 字段中包含 two 的  name link %two%   

select id, name, price, num from products where name like '%two%';

+----+-----------+--------+-----+

 | id   | name        | price    | num |

+----+-----------+--------+-----+

 |  2   | javaTwo   | 414.56  |  30   |

 | 13  | J2seTwo   |  44.56   |  30   |

 | 19  | J2eeTwo   | 454.56 |  30   |

 | 24  | J2meTwo  | 324.56 |  30   |

 | 26  | smartyTwo| 434.56 |  30   |

+----+-----------+--------+-----+


not like 取反

比如名字 name 字段不包含 two 字样的  name not like '%two%' 

select id, name, price, num from products where name not like '%two%';

这些名字字段是不包含 two 的

+----+-------------+---------+-----+

 | id   | name           | price      | num|

+----+-------------+---------+-----+

 |  1   | javaOne       |   34.50  |  10   |

 |  3   | javaThree    |  441.56  |  50   |

 |  4   | javaFour      |  144.56  |  30   |

 |  6   | phpCms      |   44.56   |  30   |

 |  7   | ecshop        |   84.56   |  30   |

 |  8   | jquery         |  244.56  |   8    |

 |  9   | Vue             |   44.56   |  30   |

 | 11  | bootStrap   | 4444.56 |  30   |

 | 12  | J2seONE     |  544.56  |  30   |

 | 14  | J2seThree   |   44.56   |  90   |

 | 16  | J2seFive      | 4324.56 |  30   |

 | 17  | J2seFix        |  454.56 |  30    |

 | 18  | J2eeOne     |   44.56  |  30    |

 | 20  | J2eeThree   |    4.56   |  77    |

 | 21  | J2eeFour     |   44.56  |  30    |

 | 22  | J2eeFive      |  494.56 |  30    |

 | 23  | J2meOne     |   48.56 |  30    |

 | 25  | smartyOne  | 4432.56|  77   |

 | 27  | smartyThree|  442.56 |  30   |

 | 28  | a                  |    0.00   |   0    |

 | 29  | b                  |    0.00   |   0    |

 | 30  | c                  |    0.00    |   0    |

+----+-------------+---------+-----+

22 rows in set (0.00 sec)


当然,如果使用完整的字符串作为精确查询,最好不用 like 进行模糊查询,应该直接使用等号 =

比如查询名字是 a 的行

select id, name, price, num from products where name = 'a';

+----+------+-------+-----+

 | id   | name| price   | num|

+----+------+-------+-----+

 | 28  | a       |  0.00    |   0   |

+----+------+-------+-----+


6. 正则


regexp 正则的方式,不用 / 加斜线(定界符)


查询 name 字段中以字母 j 开头的  name regexp '^j' 

select id, name, price from products where name regexp '^j';

+----+-----------+---------+

 | id   | name        | price     |

+----+-----------+---------+

 | 22  | J2eeFive   |  494.56  |

 | 21  | J2eeFour  |   44.56   |

 | 18  | J2eeOne   |   44.56   |

 | 20  | J2eeThree |    4.56    |

 | 19  | J2eeTwo   |  454.56  |

 | 23  | J2meOne  |   48.56  |

 | 24  | J2meTwo  |  324.56 |

 | 16  | J2seFive    | 4324.56 |

 | 17  | J2seFix      |  454.56 |

 | 12  | J2seONE   |  544.56 |

 | 14  | J2seThree |   44.56  |

 | 13  | J2seTwo    |   44.56  |

 |  4   | javaFour    |  144.56 |

 |  1   | javaOne    |   34.50   |

 |  3   | javaThree  |  441.56  |

 |  2   | javaTwo    |  414.56  |

 |  8   | jquery       |  244.56  |

+----+-----------+---------+


以字母 s 结尾的名字  name regexp 's$' 

select id, name, price from products where name regexp 's$';

+----+--------+-------+

 | id   | name    | price  |

+----+--------+-------+

 |  6   | phpcms| 44.56  |

+----+--------+-------+


名字中包含 e 的  name regexp 'e' 

select id, name, price from products where name regexp 'ne';


七、多表查询(也称连接查询)

多表查询是数据库中经常用到的一种形式,

比如百位级数据的时候,就不能还是用一个表了,就需要像切豆腐块一样切掉,


怎么切呢?

1. 可以把长表分成短表,

     比如有 20 字段的表,分成五个表,每个表四个字段的(当然要按照索引关系去分

2. 可以按照类别分表,

     比如某一类商品放到一个表里面,另外一类商品放到另外一个表里面,不要都挤在一个表里面,这样就能大大提高速度


分完的表,在使用的时候要链在一起,

比如 cats 分类表,prducts 产品表,这两张表怎么链在一起查询呢?


如果要对多张表的数据同时进行查询,就可以通过“链接运算符”实现多个表查询(也叫链接查询),

多个表链接是关系型数据库模型的主要特点,也是区别于其它类型数据库管理系统的标志


在关系型数据库管理系统中,规范化的逻辑数库设计,来将数据表分为多个相同的表,

也就是拥有大量的窄表,也就是列较少的表,是规范化数据库设计的特征,

而拥有少量的宽表,也就是列较多的表称为宽表,是非规范化数据库的特征


当我们检索的时候,

1. 通过链接操作查询出,存在多个表中的信息,

2. 多个表查询给用户带来很大的灵活性,

     可以在任意时候增加新的数据类型(为不同的实体创建新的表),然后通过链接查询多个表,就可以将多个数据表一起拿过来


比如想知道 prducts 产品表,

javaone 属于的那个分类,在 cats 表 id 是 2,想知道这个 id  表中的分类名称 name 怎么办呢?


所以多个表查询分为两种

1. 非等值的多表查询(这种查询是没意义的)

2. 等值的多表查询


1、非等值的多表查询

多表查询和普通的单表查询很相似

1. 都是通过 select 语句,

2. 只不过在多表查询时,需要把多张表的名字全部填在 from 子句中,然后用逗号分开

3. 字段列表不能用 * 号,容易出错


查询 pid 字段和 price 字段,两张表里面 pid 和 price 这个两个字段名没有重复,这么执行还可以

select pid, price from cats, products;

216 rows in set

返回 216 条数据


但是再写一个 name 字段就出错了,因为不知道 name 字段是 cats 分类表的还是 products 产品表的

select pid, price, name from cats, products;

返回报错信息

ERROR 1052 (23000): Column 'name' in field list is ambiguous


所以对于两个表有相同字段名的,必须用指定表名(不是起别名)

比如 

cats 类别表里面的 name 字段这样写 cats.name

products 商品表里面的 name 字段这样写 products.name

select cats.name, products.name, products.price from cats, products;

+-------------+-------------+---------+

 | name           | name          | price     |

+-------------+-------------+---------+

 | J2ee pid是2 | javaOne      |   34.50  |

 | J2me           | javaOne      |   34.50  |

 | J2se             | javaOne      |   34.50  |

 | JAVA           | javaOne      |   34.50  |

 ……

216 rows in set (0.013 sec)


但是这样写的 sql 语句不太好,所以给表起简短的别名

cats c

products as p

字段就可以用表的别名了

select c.name, c.desn, p.name, p.desn from cats c, products as p;

+-------------+------------------+-------------+-----------+

 | name          | desn                    | name          | desn         |

+-------------+------------------+-------------+-----------+

 | soft             | 这是一个软件分类| javaOne      | very good |

 | JAVA           | java分类              | javaOne      | very good |

 | PHP            | NULL                   | javaOne      | very good |

 ……

216 rows in set (0.013 sec)


对于名称相同的字段,还可以给每个字段起别名

select c.name cname, c.desn cdesn, p.name pname, p.desn pdesn from cats c, products as p;

+-------------+------------------+-------------+-----------+

 | cname        | cdesn                  | pname         | pdesn      |

+-------------+------------------+-------------+-----------+

 | soft             | 这是一个软件分类| javaOne       | very good |

 | JAVA           | java分类              | javaOne       | very good |

 | PHP             | NULL                  | javaOne       | very good |

 ……

216 rows in set (0.013 sec)


三张表链接查询也是同样的,在 from 后面再加一个表名,

但是有一个问题,多个表查询的时候分为“链接查询”和“非等链接查询”,

比如左链接、右链接也是处理 笛卡尔乘积 问题,


比如现在两个表连接查询后有 216 条记录,两个表加起来也没有这么多条记录

但是两个表相乘是 216 条记录


怎么出现的笛卡尔乘积?

也就是两个表查询的时候,假如第一个表叫 a 表,第二个表加 b 表,

将 a 表的中的每一条记录,和 b 表中的每一条记录依次匹配,

又将 a 表中第二条记录,和 b 表中再次匹配一次,

所以是一个相乘的关系,这个相乘的结果就是笛卡尔乘积,显然得到的结果是没有意义的


那么怎么办呢?

我们就需要按照“等值查询”,因为这两个表是有关系的


2、等值查询

这两个表是什么关系呢?

在产品表里面的保存的 cid,等于类别表里的 id,所以可以加一个 where 条件   c.id = p.cid 

select c.name cname , c.desn cdesn, p.name pname, p.desn pdesn, p.num pnum 
from 
cats c, products as p
where 
c.id = p.cid;

查询出24条记录

+-------------+------------------+-------------+-----------+------+

 | cname        | cdesn                  | pname        | pdesn       | pnum|

+-------------+------------------+-------------+-----------+------+

 | soft             | 这是一个软件分类 | javaOne     | very good |   10   |

 | soft             | 这是一个软件分类 | javaTwo     | very good |   30   |

 | soft             | 这是一个软件分类 | javaThree   | very good |   50   |

 ……

 24 rows in set (0.008 sec)


为什么叫关系型数据库啊?

指的就是一个表的外键,关联另外一个表的主键,

产品表的的 cid 就是一个外键,关联上了分类表里面的主键 id


也可以在增加一个 where 条件,并且 c.id = 3 查询出是 php 分类的

select c.name cname , c.desn cdesn, p.name pname, p.price pprice, p.desn pdesn, p.num pnum 
from 
cats c, products as p
where 
c.id = p.cid
and
c.id = 3;

+-------+-------+-------------+---------+-----------+------+

 | cname| cdesn | pname         | pprice   | pdesn       | pnum|

+-------+-------+-------------+---------+-----------+------+

 | PHP    | NULL  | phpCms      |   44.56   | very good |   30   |

 | PHP    | NULL  | ecshop        |   84.56   | very good |   30   |

 | PHP    | NULL  | smartyOne  | 4432.56 | very good |   77   |

 | PHP    | NULL  | smartyTwo  |  434.56  | very good |   30   |

 | PHP    | NULL  | smartyThree|  442.56  | very good |   33   |

+-------+-------+-------------+---------+-----------+------+


c.id = 4 是 JAVASCRIPT 分类的

select c.name cname , c.desn cdesn, p.name pname, p.price pprice, p.desn pdesn, p.num pnum 
from 
cats c, products as p
where 
c.id = p.cid
and
c.id = 4;


c.id = 6 是 J2ee 分类的

select c.name cname , c.desn cdesn, p.name pname, p.price pprice, p.desn pdesn, p.num pnum 
from 
cats c, products as p
where 
c.id = p.cid
and
c.id = 6;


这叫做

等表查询,或等值查询,

如果非等值查询,就会出现笛卡尔乘积的查询


连接查询的操作,不仅可以用于多表之间,也可以是一个表与自己进行相链,成为自身的链接查询

查看 cats 表结构

1. cats 表本身有 id 还是一个父 pid,

2. 就是大类里面存小类,小类里面再存子类,这样一个关系,是无限分类的一种设计的方式

desc cats;

+-------+-------------+------+-----+---------+----------------+

 | Field   | Type            | Null  | Key   | Default | Extra                 |

+-------+-------------+------+-----+---------+----------------+

 | id        | int(11)         | NO   | PRI   | NULL    | auto_increment |

 | pid      | int(11)         | NO   |         | 0           |                          |

 | name  | varchar(60) | NO    | MUL|              |                          |

 | desn   | text             | YES    |         | NULL    |                          |

+-------+-------------+------+-----+---------+----------------+


所以我们可以给同一个表起两个别名

select a.id aid, a.name aname, b.id bid, b.name bname
from 
cats as a, cats b;

笛卡尔乘积又出来了

+-----+------------+-----+------------+

 | aid   | aname       | bid   | bname      |

+-----+------------+-----+------------+

 |   6    | J2ee           |   6   | J2ee           |

 |   7    | J2me          |   6   | J2ee           |

 ………………

64 rows in set (0.011 sec) 


所以一定要加条件

select a.id aid, a.name aname, b.id bid, b.name bname
from 
cats as a, cats b
where
b.pid = a.id;

+-----+-------+-----+-------------+

 | aid   | aname| bid  | bname         |

+-----+-------+-----+-------------+

 |   1    | soft    |   3    | PHP             |

 |   1    | soft    |   2    | JAVA           |

 |   1    | soft    |   4    | JAVASCRIPT|

 |   2    | JAVA  |   7    | J2me           |

 |   2    | JAVA  |   5    | J2se             |

 |   2    | JAVA  |   6    | J2ee pid是2 |

 |   3    | PHP    |   8    | smarty        |

+-----+-------+-----+-------------+


八、嵌套查询(子查询)

上面的 select 查询都是单句的查询,在关系型数据中还经常使用到“嵌套查询”,

嵌套查询是一个 select 语句中的 where 字句中,包含了另外一个查询语句(也称为子查询


比如查找 porducts 产品表中的类别,是以字母 j 开头的所有产品

1. 执行的时候先执行子查询,子查询的结果作为父查询的条件(子查询中还可以再有子查询

2. 这里子查询可能有多个值,所以用 in 列表,

     如果子查询中会出现一个值,where 条件不仅可以 in,还可以用等号、大于、小于号都是可以的,

     不过一般子查询的结果都是多个结果

select id, name, cid 
  from products 
  where cid in(select id from cats where name like 'j%');

这些产品的类别分别是 java 和 javascript,分类都是以 j 开头的 

+----+-----------+-----+

 | id   | name        | cid   |

+----+-----------+-----+

 |  8   | jquery       |   4   |

 |  9   | Vue           |   4   |

 | 11  | bootStrap |   4   |

 | 12  | J2seONE   |   5   |

 | 13  | J2seTwo   |   5    |

 | 14  | J2seThree |   5   |

 | 16  | J2seFive    |   5   |

 | 17  | J2seFix      |   5   |

 | 18  | J2eeOne   |   6   |

 | 19  | J2eeTwo   |   6   |

 | 20  | J2eeThree |   6   | 

 | 21  | J2eeFour   |   6   |

 | 22  | J2eeFive    |   6   |

 | 23  | J2meOne  |   7   |

 | 24  | J2meTwo  |   7   |

+----+-----------+-----+


执行的时候,

1. 先执行子查询,

2. 子查询的结果作为父查询的条件


九、order by 排序

 order by 字段名 [asc] | desc 


所以在写每一条查询语句的时候,最好给排序的条件,

order by 和 where 条件同是 select 查询的从句,

所以它们可以同时存在,也可以不同时存在


按 id 排序,默认就正序排序  order by id 

select id, name from products order by id;

+----+-------------+

 | id   | name        |

+----+-------------+

 |  1   | javaone     |

 |  2   | javatwo     |

 |  3   | javathree   |

 ……


按照 name 字段排序   order by name 

select id, name from products order by name;

按首字母顺序排序

+----+-------------+

 | id   | name           |

+----+-------------+

 | 28  | a                  |

 | 29  | b                  |

 | 11  | bootstrap    |

 | 30  | c                  |

 |  7   | ecshop        |

 | 22  | J2eefive       |

 | 21  | J2eefour      |

 ……


按照价钱 price 字段,从低到高排序   order by price asc 

select id, name, price from products order by price asc;

+----+-------------+---------+

 | id   | name           | price     |

+----+-------------+---------+

 | 28  | a                  |    0.00    |

 | 30  | c                  |    0.00    |

 | 29  | b                  |    0.00    |

 | 20  | J2eethree     |    4.56    |

 |  1   | javaone        |   34.50   |

 |  6   | phpcms        |   44.56   |

 |  9   | vue               |   44.56   |

 ……


价钱从高到低   order by price desc 

select id, name, price from products order by price desc;

倒叙是从高到底

+----+-------------+---------+

 | id   | name           | price     |

+----+-------------+---------+

 | 11  | bootstrap    | 4444.56 |

 | 25  | smartyone   | 4432.56 |

 | 16  | J2sefive        | 4324.56 |

 | 12  | J2seONE      |  544.56  |

 ……


正序排序是 asc,正序 asc 排序是不用写的

倒序排序是 desc,


order by 排序语句和 where 语句可以同时使用的,

比如 id 小于 5 的倒序排序

select id, name from products where id < 5 order by id desc;

+----+-----------+

 | id   | name       |

+----+-----------+

 |  4   | javafour   |

 |  3   | javathree |

 |  2   | javatwo    |

 |  1   | javaone    |

+----+-----------+


十、limit count 限制查询的数量

limit 也是单独的从句,

不一定跟 where 语句和 order by 联合使用,

当然也可以联合使用的,也可能单独使用


比如查询 5 条语句  limit 5 

select id, name, price from products limit 5;

+----+-----------+---------+

 | id   | name        | price     |

+----+-----------+---------+

 | 28  | a               |    0.00    |

 | 29  | b               |    0.00    |

 | 11  | bootStrap | 4444.56 |

 | 30  | c                |    0.00   |

 |  7   | ecshop      |   84.56  |

+----+-----------+---------+


limit 和排序 order by 联合使用  order by 字段名 desc limit 5 

先写  order by id

在写  desc limit 5 

select id, name, price from products order by id desc limit 5;

+----+-------------+--------+

 | id   | name           | price    |

+----+-------------+--------+

 | 30  | c                  |   0.00    |

 | 29  | b                  |   0.00   |

 | 28  | a                  |   0.00   |

 | 27  | smartythree | 442.56 |

 | 26  | smartytwo   | 434.56 |

+----+-------------+--------+


也可以加上 where 条件   where id < 10 order by id desc limit 5 

select id, name, price from products where id < 10 order by id desc limit 5;

+----+----------+--------+

 | id   | name      | price    |

+----+----------+--------+

 |  9   | vue         |  44.56  |

 |  8   | jqurey     | 244.56 |

 |  7   | ecshop   |  84.56  |

 |  6   | phpcms  |  44.56  |

 |  4   | javafour  | 144.56 |

+----+----------+--------+


思考,

知道当前文章 id,怎么知道上一篇文章和下一篇文章呢?

这就需要 where、order by、limit 这几个从句的配合了


先删除一些语句,使 id 不是连续的

delete from products where id in(11,12,13,9,8,7,6,5);

select id, name from products order by id asc;

+----+-------------+

 | id   | name          |

+----+-------------+

 |  1   | javaOne      |

 |  2   | javaTwo      |

 |  3   | javaThree   |

 |  4   | javaFour     |

 | 14  | J2seThree   |

 | 16  | J2seFive      |

 | 17  | J2seFix        |

 | 18  | J2eeOne     |

 | 19  | J2eeTwo     |

 | 20  | J2eeThree   |

 | 21  | J2eeFour     |

 | 22  | J2eeFive      |

 | 23  | J2meOne    |

 | 24  | J2meTwo    |

 | 25  | smartyOne  |

 | 26  | smartyTwo  |

 | 27  | smartyThree|

 | 28  | a                  |

 | 29  | b                  |

 | 30  | c                  |

+----+-------------+


比如当前文章的 id 是 14,如何查询下一篇

1. where 条件大于 14 的

     select id, name from products where id > 14 

2. 正序排列

     select id, name from products where id > 14 order by id asc 

3. 从 0 取,取第一条记录

     select id, name from products where id > 14 order by id asc limit 0, 1  

select id, name from products where id > 14 order by id asc limit 0, 1;

下一篇文章是第 16 条

+----+----------+

 | id   | name      |

+----+----------+

 | 16  | J2sefive  |

+----+----------+


上一篇文章的也很简单,

改成 id 小于 14 的

order by 按照 id 倒序排序

select id, name from products where id < 14 order by id desc limit 0, 1;

+----+----------+

 | id   | name      |

+----+----------+

 |  4   | javafour  |

+----+----------+


十一、分组 guoup by

先看一些 sql 语句中的统计函数

count() 总数

sum()   总合

avg()   平均值

max()   最大值

min()   最小值


查询总数

select count(*) from products;

共有 20 条数据

+----------+

 | count(*)  |

+----------+

 |       20     |

+----------+


按照类别 cid 分组,统计出每个组的一些数据

数据总行数      count(*) 

价钱的总和      sum(price)

平均价格         avg(price)

价钱最贵的      max(price)

价钱最便宜的   min(price)

select cid, count(*), sum(price), avg(price), max(price), min(price) from products group by cid;

+-----+----------+------------+-------------+------------+------------+

 | cid   | count(*)  | sum(price) | avg(price)    | max(price) | min(price)  |

+-----+----------+------------+-------------+------------+------------+

 |   0   |        3       |       0.00     |    0.000000  |       0.00     |       0.00     |   0 组里面有 3 个产品,总价值是 0.00

 |   2   |        4       |    1035.18  |  258.795000|     441.56   |      34.50    |

 |   5   |        3       |    4823.68  | 1607.893333|    4324.56 |      44.56    |

 |   6   |        5       |    1042.80  |  208.560000 |     494.56  |       4.56     |

 |   7   |        2       |     373.12   |  186.560000 |     324.56  |      48.56    |

 |   8   |        3       |    5309.68  | 1769.893333|    4432.56 |     434.56   |

+-----+----------+------------+-------------+------------+------------+


group by 后面加上一个字段,就可以按照那个字段分组,

比如用户表加上性别字段,性别字段有男和女两种值,那就分成男的一组,女的一组,

统计出每个组的最大值,最小值等等


having


如果是分组,想给每个组指定一个条件,就不能用 where 了,每个组的条件用 having 从句

比如每个组评价价格大于 500 的条件

select cid, count(*), sum(price), avg(price), max(price), min(price) from products 
group by cid
having avg(price) > 500;

+-----+----------+------------+-------------+------------+------------+

 | cid   | count(*)  | sum(price) | avg(price)    | max(price) | min(price) |

+-----+----------+------------+-------------+------------+------------+

 |   5   |        3       |    4823.68  | 1607.893333|    4324.56  |      44.56   |

 |   8   |        3       |    5309.68  | 1769.893333|    4432.56  |     434.56  |

+-----+----------+------------+-------------+------------+------------+


having 是分组后给的条件,所以 having 做为 group by 的从句出现


MySQL 中的内置系统函数

用在 SELECT 语句,能及子句 where order by having 中 UPDATE DELETE, 

函数中可以将字段名作为变量来用,变量的值就是这个列对应的每一行记录



Leave a comment 0 Comments.

Leave a Reply

换一张