一、mysql查询的五种子句
为灌阳等地区用户提供了全套网页设计制作服务,及灌阳网站建设行业解决方案。主营业务为网站建设、成都网站制作、灌阳网站设计,以传统方式定制建设网站,并提供域名空间备案等一条龙服务,秉承以专业、用心的态度为用户提供真诚的服务。我们深信只要达到每一位用户的要求,就会得到认可,从而选择与我们长期合作。这样,我们也可以走得更远!
where(条件查询)、having(筛选)、group by(分组)、order by(排序)、limit(限制结果数)
1、where常用运算符:
比较运算符
, ,= , != ( ),= , =
in(v1,v2..vn)
between v1 and v2 在v1至v2之间(包含v1,v2)
逻辑运算符
not ( ! ) 逻辑非
or ( || ) 逻辑或
and ( ) 逻辑与
where price=3000 and price = 5000 or price =500 and price =1000
取500-1000或者3000-5000的值
where price not between 3000 and 5000
不在3000与5000之间的值
模糊查询
like 像
通配符:
% 任意字符
_ 单个字符
where goods_name like '诺基亚%'
where goods_name like '诺基亚N__'
2、group by 分组
一般情况下group需与统计函数(聚合函数)一起使用才有意义
如:select goods_id,goods_name,cat_id,max(shop_price) from goods group by cat_id;
这里取出来的结果中的good_name是错误的!因为shop_price使用了max函数,那么它是取最大的,而语句中使用了group by 分组,那么goods_name并没有使用聚合函数,它只是cat_id下的第一个商品,并不会因为shop_price改变而改变
mysql中的五种统计函数:
(1)max:求最大值
select max(goods_price) from goods
这里会取出最大的价格的值,只有值
#查询每个栏目下价格最高的
select cat_id,max(goods_price) from goos group by cat_id;
#查出价格最高的商品编号
select goods_id,max(goods_price) from goods group by goods_id;
(2)min:求最小值
(3)sum:求总数和
#求商品库存总和
select sum(goods_number) from goods;
(4)avg:求平均值
#求每个栏目的商品平均价格
select cat_id,avg(goods_price) from goods group by cat_id;
(5)count:求总行数
#求每个栏目下商品种类
select cat_id,count(*) from goods group by cat_id;
###要把每个字段名当成变量来理解,它可以进行运算###
例:查询本店每个商品价格比市场价低多少;
select goods_id,goods_name,goods_price-market_price from goods;
查询每个栏目下面积压的货款
select cat_id,sum(goods_price*goods_number) from goods group by cat_id;
###可以用as来给计算结果取个别名###
select cat_id,sum(goods_price * goods_number) as hk from goods group by cat_id
不仅列名可以取别名,表单也可以取别名
3、having 与where 的异同点
having与where类似,可以筛选数据,where后的表达式怎么写,having后就怎么写
where针对表中的列发挥作用,查询数据
having对查询结果中的列发挥作用,筛选数据
#查询本店商品价格比市场价低多少钱,输出低200元以上的商品
select goods_id,good_name,market_price - shop_price as s from goods having s200 ;
//这里不能用where因为s是查询结果,而where只能对表中的字段名筛选
如果用where的话则是:
select goods_id,goods_name from goods where market_price - shop_price 200;
#同时使用where与having
select cat_id,goods_name,market_price - shop_price as s from goods where cat_id = 3 having s 200;
#查询积压货款超过2万元的栏目,以及该栏目积压的货款
select cat_id,sum(shop_price * goods_number) as t from goods group by cat_id having s 20000
#查询两门及两门以上科目不及格的学生的平均分
思路:
#先计算所有学生的平均分
select name,avg(score) as pj from stu group by name;
#查出所有学生的挂科情况
select name,score60 from stu;
#这里score60是判断语句,所以结果为真或假,mysql中真为1假为0
#查出两门及两门以上不及格的学生
select name,sum(score60) as gk from stu group by name having gk 1;
#综合结果
select name,sum(score60) as gk,avg(score) as pj from stu group by name having gk 1;
4、order by
(1) order by price //默认升序排列
(2)order by price desc //降序排列
(3)order by price asc //升序排列,与默认一样
(4)order by rand() //随机排列,效率不高
#按栏目号升序排列,每个栏目下的商品价格降序排列
select * from goods where cat_id !=2 order by cat_id,price desc;
5、limit
limit [offset,] N
offset 偏移量,可选,不写则相当于limit 0,N
N 取出条目
#取价格第4-6高的商品
select good_id,goods_name,goods_price from goods order by good_price desc limit 3,3;
###查询每个栏目下最贵的商品
思路:
#先对每个栏目下的商品价格排序
select cat_id,goods_id,goods_name,shop_price from goods order by cat_id,shop_price desc;
#上面的查询结果中每个栏目的第一行的商品就是最贵的商品
#把上面的查询结果理解为一个临时表[存在于内存中]【子查询】
#再从临时表中选出每个栏目最贵的商品
select * from (select goods_id,goods_name,cat_id,shop_price from goods order by cat_id,shop_price desc) as t group by cat_id;
#这里使用group by cat_id是因为临时表中每个栏目的第一个商品就是最贵的商品,而group by前面没有使用聚合函数,所以默认就取每个分组的第一行数据,这里以cat_id分组
良好的理解模型:
1、where后面的表达式,把表达式放在每一行中,看是否成立
2、字段(列),理解为变量,可以进行运算(算术运算和逻辑运算)
3、 取出结果可以理解成一张临时表
二、mysql子查询
1、where型子查询
(把内层查询结果当作外层查询的比较条件)
#不用order by 来查询最新的商品
select goods_id,goods_name from goods where goods_id = (select max(goods_id) from goods);
#取出每个栏目下最新的产品(goods_id唯一)
select cat_id,goods_id,goods_name from goods where goods_id in(select max(goods_id) from goods group by cat_id);
2、from型子查询
(把内层的查询结果供外层再次查询)
#用子查询查出挂科两门及以上的同学的平均成绩
思路:
#先查出哪些同学挂科两门以上
select name,count(*) as gk from stu where score 60 having gk =2;
#以上查询结果,我们只要名字就可以了,所以再取一次名字
select name from (select name,count(*) as gk from stu having gk =2) as t;
#找出这些同学了,那么再计算他们的平均分
select name,avg(score) from stu where name in (select name from (select name,count(*) as gk from stu having gk =2) as t) group by name;
3、exists型子查询
(把外层查询结果拿到内层,看内层的查询是否成立)
#查询哪些栏目下有商品,栏目表category,商品表goods
select cat_id,cat_name from category where exists(select * from goods where goods.cat_id = category.cat_id);
三、union的用法
(把两次或多次的查询结果合并起来,要求查询的列数一致,推荐查询的对应的列类型一致,可以查询多张表,多次查询语句时如果列名不一样,则取第一次的列名!如果不同的语句中取出的行的每个列的值都一样,那么结果将自动会去重复,如果不想去重复则要加all来声明,即union all)
## 现有表a如下
id num
a 5
b 10
c 15
d 10
表b如下
id num
b 5
c 10
d 20
e 99
求两个表中id相同的和
select id,sum(num) from (select * from ta union select * from tb) as tmp group by id;
//以上查询结果在本例中的确能正确输出结果,但是,如果把tb中的b的值改为10以查询结果的b的值就是10了,因为ta中的b也是10,所以union后会被过滤掉一个重复的结果,这时就要用union all
select id,sum(num) from (select * from ta union all select * from tb) as tmp group by id;
#取第4、5栏目的商品,按栏目升序排列,每个栏目的商品价格降序排列,用union完成
select goods_id,goods_name,cat_id,shop_price from goods where cat_id=4 union select goods_id,goods_name,cat_id,shop_price from goods where cat_id=5 order by cat_id,shop_price desc;
【如果子句中有order by 需要用( ) 包起来,但是推荐在最后使用order by,即对最终合并后的结果来排序】
#取第3、4个栏目,每个栏目价格最高的前3个商品,结果按价格降序排列
(select goods_id,goods_name,cat_id,shop_price from goods where cat_id=3 order by shop_price desc limit 3) union (select goods_id,goods_name,cat_id,shop_price from goods where cat_id=4 order by shop_price desc limit 3) order by shop_price desc;
四、左连接,右连接,内连接
现有表a有10条数据,表b有8条数据,那么表a与表b的笛尔卡积是多少?
select * from ta,tb //输出结果为8*10=80条
1、左连接
以左表为准,去右表找数据,如果没有匹配的数据,则以null补空位,所以输出结果数=左表原数据数
语法:select n1,n2,n3 from ta left join tb on ta.n1= ta.n2 [这里on后面的表达式,不一定为=,也可以,等算术、逻辑运算符]【连接完成后,可以当成一张新表来看待,运用where等查询】
#取出价格最高的五个商品,并显示商品的分类名称
select goods_id,goods_name,goods.cat_id,cat_name,shop_price from goods left join category on goods.cat_id = category.cat_id order by shop_price desc limit 5;
2、右连接
a left join b 等价于 b right join a
推荐使用左连接代替右连接
语法:select n1,n2,n3 from ta right join tb on ta.n1= ta.n2
3、内连接
查询结果是左右连接的交集,【即左右连接的结果去除null项后的并集(去除了重复项)】
mysql目前还不支持 外连接(即左右连接结果的并集,不去除null项)
语法:select n1,n2,n3 from ta inner join tb on ta.n1= ta.n2
总结:可以对同一张表连接多次,以分别取多次数据
1、首先先创建一个存储过程,代码如图,存储过程主要的功能是为表JingYan插入新的数据。
2、执行这几行代码,看到执行成功,数据库里现在已经有存储过程sp_JY。
3、先看下JingYan表里目前的数组,如图,只有三行数据。
4、在mysql里,调用存储过程,只需要用call关键字,带上存储过程的名称就行了,当然有参数时,需要带个参数。
5、执行了这个存储过程的调用之后,再看下JingYan表里的数据,可以看到现在的数据已经是四条了,说明调用存储过程成功插入了一条新的数据。
6、再添加一个存储过程,该存储过程用select语句,返回表数据。
7、调用查询新的存储过程,可以看到结果里也是返回表数据。
方法/步骤
1
MySQL客户端SQLyog,使用某一数据库时,需要选定该数据库,那如何查询选中的数据库,可以利用DATABASE(),代码如下:
SELECT DATABASE();
如下图所示:
2
安装了MySQL数据库,想查看一下版本号,VERSION()返回当前数据库版本,代码如下:
SELECT VERSION();
如下图所示:
1
查询数据表除了前三条以外的数据。
起初我想到的是这条语句
SELECT
*
FROM
admin
WHERE
userid
NOT
IN
(SELECT
userid
FROM
admin
ORDER
BY
userid
LIMIT
3)
ORDER
BY
userid
DESC
但是运行的时候会报
This
version
of
MySQL
doesn't
yet
support
'LIMIT
IN/ALL/ANY/SOME
subquery
这个的意思是表示子查询的时候不支持limit
,还有一点我就是很二了
就是查询的时候用not
in
效率非常不高
最后的解决办法是
CREATE
VIEW
view_top3_admin
AS
SELECT
*
FROM
admin
ORDER
BY
userid
LIMIT
3;
先创建一个视图
将子查询条件放到视图里面
然后在用这条语句
SELECT
*
FROM
admin
a
WHERE
NOT
EXISTS
(SELECT
1
FROM
view_top3_admin
b
WHERE
b.userid=a.userid
)
ORDER
BY
a.userid
DESC
先来解释下这条语句
SELECT
1
FROM
view_top3_admin
b
WHERE
b.userid=a.userid
表示查询表里面的值
只要有数据都显示为 1,1表示不读取数据
这样的话就是提升了查询的性能,当然也可以把
里面的1
换成
null
性能是一致的。整条语句的意思是查询admin表值,
判断条件是值不在子查询表里的。
2
union
和
union
all
的使用
先来解释下这两个关键字在mysql数据库中提供了UNION和UNION
ALL关键字,这两个关键字都是将结果集合并为一个,但这两者从使用和效率上来说都有所不同
UNION在进行表链接后会筛选掉重复的记录,所以在表链接后会对所产生的结果集进行排序运算,删除重复的记录再返回结果。
select
*
from
table
union
select
*
from
tabl
UNION
ALL只是简单的将两个结果合并后就返回
如果返回的两个结果集中有重复的数据,那么返回的结果集就会包含重复的数据了
select
*
from
table
union
all
select
*
from
tabl
从效率上说,UNION
ALL
要比UNION快很多,所以,如果可以确认合并的两个结果集中不包含重复的数据的话,那么就使用UNION
这两个关键字用做报表比较多
例子如下:SELCET * FROM T-USER U WHERE CONCAT(U.LASTNAME,U.FIRSTNAME) LIKE '%$LSP_NAME$%'
LASTNAME 字段是姓;
FIRSTNAME字段是名字;
当查询字段为null时,返回结果为null。与concat_ws(...)不同。
如果为多个字段同时进行查询时,使用concat_ws(...)。
select concat_ws(',','11','22','33');
select concat_ws(',','11','22','33',null);都返回11,22,33。
CONCAT_WS() 代表 CONCAT With Separator,是CONCAT()的特殊形式。第一个参数是其它参数的分隔符。分隔符的位置放在要连接的两个字符串之间。分隔符可以是一个字符串,也可以是其它参数。
CONCAT()可以连接一个或者多个字符串,CONCAT_WS()可以添加分割符参数。
索引功能
索引是一种特殊的文件(InnoDB 数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针。索引不是万能的,索引可以加快数据检索操作,但会使数据修改操作变慢。每修改数据记录,索引就必须刷新一次。为了在某种程度上弥补这一缺陷,许多 SQL 命令都有一个 DELAY_KEY_WRITE 项。这个选项的作用是暂时制止 MySQL 在该命令每插入一条新记录和每修改一条现有之后立刻对索引进行刷新,对索引的刷新将等到全部记录插入/修改完毕之后再进行。在需要把许多新记录插入某个数据表的场合,DELAY_KEY_WRITE 选项的作用将非常明显。另外,索引还会在硬盘上占用相当大的空间。因此应该只为最经常查询和最经常排序的数据列建立索引。注意,如果某个数据列包含许多重复的内容,为它建立索引就没有太大的实际效果。
从理论上讲,完全可以为数据表里的每个字段分别建一个索引,但 MySQL 把同一个数据表里的索引总数限制为16个。
1.InnoDB 数据表的索引
与 InnoDB数据表相比,在 InnoDB 数据表上,索引对 InnoDB 数据表的重要性要大得多。在 InnoDB 数据表上,索引不仅会在搜索数据记录时发挥作用,还是数据行级锁定机制的苊、基础。“数据行级锁定”的意思是指在事务操作的执行过程中锁定正在被处理的个别记录,不让其他用户进行访问。这种锁定将影响到(但不限于)SELECT、LOCKINSHAREMODE、SELECT、FORUPDATE 命令以及 INSERT、UPDATE 和 DELETE 命令。出于效率方面的考虑,InnoDB 数据表的数据行级锁定实际发生在它们的索引上,而不是数据表自身上。显然,数据行级锁定机制只有在有关的数据表有一个合适的索引可供锁定的时候才能发挥效力。
2.限制
如果 WHERE 子句的查询条件里有不等号(WHERE coloum !=),MySQL 将无法使用索引。类似地,如果 WHERE 子句的查询条件里使用了函数(WHERE DAY(column)=),MySQL 也将无法使用索引。在 JOIN 操作中(需要从多个数据表提取数据时),MySQL 只有在主键和外键的数据类型相同时才能使用索引。
如果 WHERE 子句的查询条件里使用比较操作符 LIKE 和 REGEXP,MySQL 只有在搜索模板的第一个字符不是通配符的情况下才能使用索引。比如说,如果查询条件是 LIKE 'abc%‘,MySQL 将使用索引;如果查询条件是 LIKE '%abc’,MySQL 将不使用索引。
在 ORDER BY 操作中,MySQL 只有在排序条件不是一个查询条件表达式的情况下才使用索引。(虽然如此,在涉及多个数据表查询里,即使有索引可用,那些索引在加快 ORDER BY 方面也没什么作用)。如果某个数据列里包含许多重复的值,就算为它建立了索引也不会有很好的效果。比如说,如果某个数据列里包含的净是些诸如 “0/1” 或 “Y/N” 等值,就没有必要为它创建一个索引。
索引类别
1.普通索引
普通索引(由关键字 KEY 或 INDEX 定义的索引)的唯一任务是加快对数据的访问速度。因此,应该只为那些最经常出现在查询条件(WHERE column =)或排序条件(ORDER BY column)中的数据列创建索引。只要有可能,就应该选择一个数据最整齐、最紧凑的数据列(如一个整数类型的数据列)来创建索引。
2.唯一索引
普通索引允许被索引的数据列包含重复的值。比如说,因为人有可能同名,所以同一个姓名在同一个“员工个人资料”数据表里可能出现两次或更多次。
如果能确定某个数据列将只包含彼此各不相同的值,在为这个数据列创建索引的时候就应该用关键字UNIQUE 把它定义为一个唯一索引。这么做的好处:一是简化了 MySQL 对这个索引的管理工作,这个索引也因此而变得更有效率;二是 MySQL 会在有新记录插入数据表时,自动检查新记录的这个字段的值是否已经在某个记录的这个字段里出现过了;如果是,MySQL 将拒绝插入那条新记录。也就是说,唯一索引可以保证数据记录的唯一性。事实上,在许多场合,人们创建唯一索引的目的往往不是为了提高访问速度,而只是为了避免数据出现重复。
3.主索引
在前面已经反复多次强调过:必须为主键字段创建一个索引,这个索引就是所谓的“主索引”。主索引与唯一索引的唯一区别是:前者在定义时使用的关键字是 PRIMARY 而不是 UNIQUE。
4.外键索引
如果为某个外键字段定义了一个外键约束条件,MySQL 就会定义一个内部索引来帮助自己以最有效率的方式去管理和使用外键约束条件。
5.复合索引
索引可以覆盖多个数据列,如像 INDEX (columnA, columnB) 索引。这种索引的特点是 MySQL 可以有选择地使用一个这样的索引。如果查询操作只需要用到 columnA 数据列上的一个索引,就可以使用复合索引 INDEX(columnA, columnB)。不过,这种用法仅适用于在复合索引中排列在前的数据列组合。比如说,INDEX (A,B,C) 可以当做 A 或 (A,B) 的索引来使用,但不能当做 B、C 或 (B,C) 的索引来使用。
索引长度
在为 CHAR 和 VARCHAR 类型的数据列定义索引时,可以把索引的长度限制为一个给定的字符个数(这个数字必须小于这个字段所允许的最大字符个数)。这么做的好处是可以生成一个尺寸比较小、检索速度却比较快的索引文件。在绝大多数应用里,数据库中的字符串数据大都以各种各样的名字为主,把索引的长度设置为10~15 个字符已经足以把搜索范围缩小到很少的几条数据记录了。在为 BLOB 和 TEXT 类型的数据列创建索引时,必须对索引的长度做出限制;MySQL 所允许的最大索引全文索引文本字段上的普通索引只能加快对出现在字段内容最前面的字符串(也就是字段内容开头的字符)进行检索操作。如果字段里存放的是由几个、甚至是多个单词构成的较大段文字,普通索引就没什么作用了。这种检索往往以的形式出现,这对 MySQL 来说很复杂,如果需要处理的数据量很大,响应时间就会很长。
这类场合正是全文索引(full-textindex)可以大显身手的地方。在生成这种类型的索引时,MySQL 将把在文本中出现的所有单词创建为一份清单,查询操作将根据这份清单去检索有关的数据记录。全文索引即可以随数据表一同创建,也可以等日后有必要时再使用下面这条命令添加:
ALTER TABLE tablename ADD FULLTEXT(column1,column2)有了全文索引,就可以用 SELECT 查询命令去检索那些包含着一个或多个给定单词的数据记录了。下面是这类查询命令的基本语法:
SELECT * FROM tablename
WHERE MATCH (column1,column2) AGAINST('word1','word2','word3')
上面这条命令将把 column1 和 column2 字段里有 word1、word2 和 word3 的数据记录全部查询出来。
注解:InnoDB 数据表不支持全文索引。
在我们日常生活中偶尔会遇到一些自己不知道如何解决的问题,比如使用安装好的mysql。那么我们应该怎样解决这种自己不知道如何使用安装好的mysql的情况呢?那么接下来就由我来介绍一下使用安装好的mysql的步骤吧。
本次操作以Dell电脑为例,具体操作步骤如下:
第一步:
首先,打开MySQLWorkbench,双击打开即可。打开后的界面如下所示,然后选择数据库实例,双击进行登录。图中数据库的实例是LocalinstanceMYSQL57
第二步:
然后,输入用户名和密码进行登录。如下图所示:
第三步:
登录成功后,界面如下所示。其中,区域1显示的是数据库服务器中已经创建的数据库列表。区域2是关于数据库的操作列表。区域三是sql的编辑器和执行环境,区域4是执行结果的列表
第四步:
在sql的编辑器中输入测试语句,如图所示,其中world数据库是mysql自带的测试数据库,然后选择执行(或者使用快捷键ctrl+enter)。执行成功后,查询结果会显示在下面的列表中。
第五步:
使用完毕后,直接退出,并且如果无需数据库的后继操作的话,记得关掉MySQL的服务
看了我的方法,现在你学会如何使用安装好的mysql了吗?学会了的话就快快把这个方法分享出去,让更多的人知道如何使用安装好的mysql。以上就是使用安装好的mysql的步骤。
本文章基于Dell品牌、Windows10系统撰写的。