MySQL数据查询
2016-04-29 10:04
225 查看
数据库的增删改查,查询操作一般而言是用的最多的,变化也比较大,终于开始学习这部分了。
话不多说,直接上。
基本查询语句
select
{*|<字段名列表>} // 星号是通配符,表示所有列全选,字段名列表至少包含一个字段名,如果有多个则用逗号隔开,最后一个字段不加逗号
[
from <表1>, <表2>... // 表1, 表2是查询数据的来源,可以是单个也可以是多个
[ where <表达式>] // 可选的,表示查询的数据应该满足什么查询条件
[ groupy by <group by definition>] // 对查询出来的数据按照指定的字段分组
[ having <表达式> [{<operator><表达式>}...]]
[ order by <order by definition>] // 对查询出来的数据进行排序
[ limit [<offset>,] <row count>] // 显示查询出来的数据的条数
]
select [字段1, 字段2, ... , 字段n]
from [表或者视图]
where [查询条件];
select语句决定了要查询的列值
野棉花:
mysql > system clear
可以用来清屏
单表查询
单表查询是指从一张表中查询所需的数据
查询所有字段
使用*号通配符来完成
select * from 表名;
带in关键字查询
in操作符用来查询满足指定范围内的条件的记录,检索条件用括号括起来。
select s_id, f_name, f_price
from fruits
where s_id in (101, 102)
order by f_name;
相反可以用not in来表达不在范围之中
between and
匹配范围中的所有值,包括边界
not between and
不在所选的范围之间
带like的字符匹配查询
百分号通配符匹配任意长度的字符,包括0字符
select f_id, f_name
from fruits
where f_name like 'b%';
%匹配在指定位置上任意数目的字符
下划线通配符,一次只能匹配任意一个字符
select f_name from fruits where f_name like '_a%';
查询空值
空置不同于0,也不同于空字符串,一般表示数据未知、不适用或者将在以后添加数据
用is null判断是否为空
select f_name from fruits where f_name is not null; // 这个可用
select f_name from fruits where f_name not is null; // 这个报错
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'is null' at line 1
带and的多条件查询
select f_name from fruits where s_id = 105 and f_price < 10;
带or的多条件查询
select f_name,s_id,f_price
from fruits
where s_id = 105 or f_price > 10;
in的速度要快于or,而且支持更复杂的嵌套查询
and的优先级要高于or
查询结果不重复
select distinct 字段名 from 表名;
好像这个只能针对单个字段进行查询
对查询结果进行排序
order by
多列排序
对多列进行排序时,首先第一列必须有相同的值才会对第二列进行排序,如果第一列的值都是唯一的,将不会对第二列进行排序
指定排序的方向
order by 字段名 desc | asc
select s_id, f_price from fruits order by s_id asc, f_price desc;
排序的时候asc是默认的排序方式,加不加都可以。
每个desc或者asc只对应它前面唯一一个字段
分组查询
按照某个或多个字段进行分组,group by
group by 字段 having <条件表达式>
group by 常常和集合函数一起使用,例如max(), min(), count(), sum(), avg()。
示例:
select s_id, count(*) as total from fruits group by s_id;
select s_id, count(*) as total from fruits where f_price > 8 group by s_id;
如果要查看供应商分别提供的水果名称,可以在group by 中使用group_concat()函数
mysql> select s_id, group_concat(f_name) as Names from fruits group by s_id;
+------+--------------------------------+
| s_id | Names |
+------+--------------------------------+
| 101 | apple,blackberry,cherry |
| 102 | orange,banana,grape |
| 103 | apricot,coconut |
| 104 | berry,lemon |
| 105 | melon,xbabay,xxtt |
| 106 | mango |
| 107 | xxxx,xbababa |
+------+--------------------------------+
group_concat(字段名)就随分组而归结到一起了
做个实验
mysql> select s_id, group_concat(f_name+f_price) as Names from fruits group by s_id;
会出现啥
试过暂时不行,要对f_price 进行转换
使用having过滤分组
group by可以和having结合使用
select s_id, group_concat(f_name) as Names
from fruits
group by s_id having count(f_name) > 1;
问题来了,上一句和下面这一句的区别在于?
select s_id, group_concat(f_name) as Names
from fruits
group by s_id having count(s_id) > 1;
试验结果没什么不同
having和where都是用来过滤数据的,不同在于:
having在数据分组之后进行过滤来选择分组
where则是在分组之前用来选择记录,此外,where排除的记录不再包括在分组中
在group by子句中使用with rollup
使用rollup关键字后,在所有查询的分组记录之后增加一条记录,计算所有记录的总和
示例:
select s_id, count(*) as total
from fruits
group by s_id with rollup;
+------+-------+
| s_id | total |
+------+-------+
| 101 | 3 |
| 102 | 3 |
| 103 | 2 |
| 104 | 2 |
| 105 | 3 |
| 106 | 1 |
| 107 | 2 |
| NULL | 16 |
+------+-------+
8 rows in set (0.00 sec)
mysql> select s_id, count(f_id) from fruits;
+------+-------------+
| s_id | count(f_id) |
+------+-------------+
| 101 | 16 |
+------+-------------+
1 row in set (0.00 sec)
mysql> select s_id, count(f_id) from fruits group by s_id;
+------+-------------+
| s_id | count(f_id) |
+------+-------------+
| 101 | 3 |
| 102 | 3 |
| 103 | 2 |
| 104 | 2 |
| 105 | 3 |
| 106 | 1 |
| 107 | 2 |
+------+-------------+
7 rows in set (0.01 sec)
多字段分组
group by可以对多个字段进行分组,分组层次从左到右
示例:
select * from fruits group by s_id, f_name;
+------+------+------------+---------+
| f_id | s_id | f_name | f_price |
+------+------+------------+---------+
| a1 | 101 | apple | 5.20 |
| b1 | 101 | blackberry | 10.20 |
| c0 | 101 | cherry | 3.20 |
| t1 | 102 | banana | 10.30 |
| t2 | 102 | grape | 5.30 |
| bs1 | 102 | orange | 11.20 |
| a2 | 103 | apricot | 2.20 |
| o2 | 103 | coconut | 9.20 |
| b2 | 104 | berry | 7.60 |
| l2 | 104 | lemon | 6.40 |
| bs2 | 105 | melon | 8.20 |
| m2 | 105 | xbabay | 2.60 |
| m3 | 105 | xxtt | 11.60 |
| m1 | 106 | mango | 15.60 |
| t4 | 107 | xbababa | 3.60 |
| b5 | 107 | xxxx | 3.60 |
+------+------+------------+---------+
16 rows in set (0.00 sec)
group by和order by一起使用
select o_num, sum(quantity * item_price) as ordertotal
from orderitems
group by o_num
having sum(quantity * item_price) >= 100;
学会把复杂的查询语句分解
select o_num, sum(quantity * item_price) as ordertotal
from orderitems
group by o_num
having sum(quantity * item_price) >= 100
order by ordertotal desc;
+-------+------------+
| o_num | ordertotal |
+-------+------------+
| 30003 | 1000.00 |
| 30001 | 268.80 |
| 30005 | 236.85 |
| 30004 | 125.00 |
+-------+------------+
4 rows in set (0.00 sec)
group by子句按订单号对数据进行分组
sum()函数可以返回总的订单价格
having子句对分组数据进行过滤,使得只返回总价格大于100的订单
最后用order by子句来排序输出
rollu和order by是相互排斥的
使用limit限制查询结果数量
limit [位置偏移量] 行数
位置偏移量是可选的,如果不选这个那么默认是从第一个开始
limit 4 offset 3
第五条记录开始的后面三条
使用集合函数查询
avg(), count(), max(), min(), sum()
count( )函数
count(*)计算表中总的行数
count(字段名) 指定列下的总行数
mysql> select count(*) as total from fruits;
+-------+
| total |
+-------+
| 16 |
+-------+
如果指定了列那么列下面的null值不会计入到count中
如果count(*),那么所有行都会计入
示例:
select o_num, count(f_id)
from orderitems
group by o_num;
先按照o_num分组,然后分别统计每组中的记录数
sum( )函数
返回指定列值的和
sum( )也可以和group by 一起使用,来计算每个分组的和
select o_num, sum(quantity) as items_total
from orderitems
group by o_num;
avg( ) 返回指定数据列的平均值
示例:
select avg(f_price) as avg_price
from fruits
where s_id = 103;
avg( )也可以和group by一起使用
select o_num,avg(quantity * item_price) as avg_order
from orderitems
group by o_num;
这样也可以。。。
max( )函数 min( )
max( ) 返回指定列中的最大值
也可以和group by一起使用
max( ) 不仅适用于数值型,也适用于字符型
连接查询
连接查询是关系数据库中最主要的查询,主要有内连接和外连接,通过连接运算符可以实现多个表查询
内连接查询
外连接查询
复合连接查询
内连接查询
inner join
对表间的某些列进行比较操作,并列出这些表中与连接条件相匹配的数据行,组合成新的记录
在内连接查询中只有符合条件的记录才会出现在关系结果中
首先建立一些示例表
select suppliers.s_id, s_name, f_name, f_price // 这是你要选择的列
from fruits, suppliers // 从哪个表里面选择
where fruits.s_id = suppliers.s_id; // 选出的条件是什么
这里查询出来的结果是来自于两个不同的表
如果查询的表中有相同的列那么就要指定是来自于哪一个表
select suppliers.s_id, s_name, f_name, f_price
from fruits inner join suppliers
on fruits.s_id = suppliers.s_id; //这里的where 变成on了
查询供应f_id = 'a1'的水果供应商提供的其他种类的水果
select f1.f_id, f1.f_name
from fruits as f1, fruits as f2
where f1.s_id = f2.s_id and f2.f_id = 'a1';
这个查询好好回味一下
防止歧义性使用了别名
外连接查询
查询多个表中相关的行,内连接时仅是符合查询条件和连接条件的行
左连接:返回包括左表中的所有记录和右表中连接字段相等的记录
右连接:返回包括右表中的所有记录和左表中连接字段相等的记录
全连接:
left join 左连接
返回左表中所有的行而不仅仅是连接列匹配的行,如果左表的行在右表中没有匹配行,则在相关的连接结果中,右表的所有选择列均为空值
废话不多说,直接上例子
话不多说,直接上。
基本查询语句
select
{*|<字段名列表>} // 星号是通配符,表示所有列全选,字段名列表至少包含一个字段名,如果有多个则用逗号隔开,最后一个字段不加逗号
[
from <表1>, <表2>... // 表1, 表2是查询数据的来源,可以是单个也可以是多个
[ where <表达式>] // 可选的,表示查询的数据应该满足什么查询条件
[ groupy by <group by definition>] // 对查询出来的数据按照指定的字段分组
[ having <表达式> [{<operator><表达式>}...]]
[ order by <order by definition>] // 对查询出来的数据进行排序
[ limit [<offset>,] <row count>] // 显示查询出来的数据的条数
]
select [字段1, 字段2, ... , 字段n]
from [表或者视图]
where [查询条件];
select语句决定了要查询的列值
野棉花:
mysql > system clear
可以用来清屏
单表查询
单表查询是指从一张表中查询所需的数据
查询所有字段
使用*号通配符来完成
select * from 表名;
带in关键字查询
in操作符用来查询满足指定范围内的条件的记录,检索条件用括号括起来。
select s_id, f_name, f_price
from fruits
where s_id in (101, 102)
order by f_name;
相反可以用not in来表达不在范围之中
between and
匹配范围中的所有值,包括边界
not between and
不在所选的范围之间
带like的字符匹配查询
百分号通配符匹配任意长度的字符,包括0字符
select f_id, f_name
from fruits
where f_name like 'b%';
%匹配在指定位置上任意数目的字符
下划线通配符,一次只能匹配任意一个字符
select f_name from fruits where f_name like '_a%';
查询空值
空置不同于0,也不同于空字符串,一般表示数据未知、不适用或者将在以后添加数据
用is null判断是否为空
select f_name from fruits where f_name is not null; // 这个可用
select f_name from fruits where f_name not is null; // 这个报错
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'is null' at line 1
带and的多条件查询
select f_name from fruits where s_id = 105 and f_price < 10;
带or的多条件查询
select f_name,s_id,f_price
from fruits
where s_id = 105 or f_price > 10;
in的速度要快于or,而且支持更复杂的嵌套查询
and的优先级要高于or
查询结果不重复
select distinct 字段名 from 表名;
好像这个只能针对单个字段进行查询
对查询结果进行排序
order by
多列排序
对多列进行排序时,首先第一列必须有相同的值才会对第二列进行排序,如果第一列的值都是唯一的,将不会对第二列进行排序
指定排序的方向
order by 字段名 desc | asc
select s_id, f_price from fruits order by s_id asc, f_price desc;
排序的时候asc是默认的排序方式,加不加都可以。
每个desc或者asc只对应它前面唯一一个字段
分组查询
按照某个或多个字段进行分组,group by
group by 字段 having <条件表达式>
group by 常常和集合函数一起使用,例如max(), min(), count(), sum(), avg()。
示例:
select s_id, count(*) as total from fruits group by s_id;
select s_id, count(*) as total from fruits where f_price > 8 group by s_id;
如果要查看供应商分别提供的水果名称,可以在group by 中使用group_concat()函数
mysql> select s_id, group_concat(f_name) as Names from fruits group by s_id;
+------+--------------------------------+
| s_id | Names |
+------+--------------------------------+
| 101 | apple,blackberry,cherry |
| 102 | orange,banana,grape |
| 103 | apricot,coconut |
| 104 | berry,lemon |
| 105 | melon,xbabay,xxtt |
| 106 | mango |
| 107 | xxxx,xbababa |
+------+--------------------------------+
group_concat(字段名)就随分组而归结到一起了
做个实验
mysql> select s_id, group_concat(f_name+f_price) as Names from fruits group by s_id;
会出现啥
试过暂时不行,要对f_price 进行转换
使用having过滤分组
group by可以和having结合使用
select s_id, group_concat(f_name) as Names
from fruits
group by s_id having count(f_name) > 1;
问题来了,上一句和下面这一句的区别在于?
select s_id, group_concat(f_name) as Names
from fruits
group by s_id having count(s_id) > 1;
试验结果没什么不同
having和where都是用来过滤数据的,不同在于:
having在数据分组之后进行过滤来选择分组
where则是在分组之前用来选择记录,此外,where排除的记录不再包括在分组中
在group by子句中使用with rollup
使用rollup关键字后,在所有查询的分组记录之后增加一条记录,计算所有记录的总和
示例:
select s_id, count(*) as total
from fruits
group by s_id with rollup;
+------+-------+
| s_id | total |
+------+-------+
| 101 | 3 |
| 102 | 3 |
| 103 | 2 |
| 104 | 2 |
| 105 | 3 |
| 106 | 1 |
| 107 | 2 |
| NULL | 16 |
+------+-------+
8 rows in set (0.00 sec)
mysql> select s_id, count(f_id) from fruits;
+------+-------------+
| s_id | count(f_id) |
+------+-------------+
| 101 | 16 |
+------+-------------+
1 row in set (0.00 sec)
mysql> select s_id, count(f_id) from fruits group by s_id;
+------+-------------+
| s_id | count(f_id) |
+------+-------------+
| 101 | 3 |
| 102 | 3 |
| 103 | 2 |
| 104 | 2 |
| 105 | 3 |
| 106 | 1 |
| 107 | 2 |
+------+-------------+
7 rows in set (0.01 sec)
多字段分组
group by可以对多个字段进行分组,分组层次从左到右
示例:
select * from fruits group by s_id, f_name;
+------+------+------------+---------+
| f_id | s_id | f_name | f_price |
+------+------+------------+---------+
| a1 | 101 | apple | 5.20 |
| b1 | 101 | blackberry | 10.20 |
| c0 | 101 | cherry | 3.20 |
| t1 | 102 | banana | 10.30 |
| t2 | 102 | grape | 5.30 |
| bs1 | 102 | orange | 11.20 |
| a2 | 103 | apricot | 2.20 |
| o2 | 103 | coconut | 9.20 |
| b2 | 104 | berry | 7.60 |
| l2 | 104 | lemon | 6.40 |
| bs2 | 105 | melon | 8.20 |
| m2 | 105 | xbabay | 2.60 |
| m3 | 105 | xxtt | 11.60 |
| m1 | 106 | mango | 15.60 |
| t4 | 107 | xbababa | 3.60 |
| b5 | 107 | xxxx | 3.60 |
+------+------+------------+---------+
16 rows in set (0.00 sec)
group by和order by一起使用
select o_num, sum(quantity * item_price) as ordertotal
from orderitems
group by o_num
having sum(quantity * item_price) >= 100;
学会把复杂的查询语句分解
select o_num, sum(quantity * item_price) as ordertotal
from orderitems
group by o_num
having sum(quantity * item_price) >= 100
order by ordertotal desc;
+-------+------------+
| o_num | ordertotal |
+-------+------------+
| 30003 | 1000.00 |
| 30001 | 268.80 |
| 30005 | 236.85 |
| 30004 | 125.00 |
+-------+------------+
4 rows in set (0.00 sec)
group by子句按订单号对数据进行分组
sum()函数可以返回总的订单价格
having子句对分组数据进行过滤,使得只返回总价格大于100的订单
最后用order by子句来排序输出
rollu和order by是相互排斥的
使用limit限制查询结果数量
limit [位置偏移量] 行数
位置偏移量是可选的,如果不选这个那么默认是从第一个开始
limit 4 offset 3
第五条记录开始的后面三条
使用集合函数查询
avg(), count(), max(), min(), sum()
count( )函数
count(*)计算表中总的行数
count(字段名) 指定列下的总行数
mysql> select count(*) as total from fruits;
+-------+
| total |
+-------+
| 16 |
+-------+
如果指定了列那么列下面的null值不会计入到count中
如果count(*),那么所有行都会计入
示例:
select o_num, count(f_id)
from orderitems
group by o_num;
先按照o_num分组,然后分别统计每组中的记录数
sum( )函数
返回指定列值的和
sum( )也可以和group by 一起使用,来计算每个分组的和
select o_num, sum(quantity) as items_total
from orderitems
group by o_num;
avg( ) 返回指定数据列的平均值
示例:
select avg(f_price) as avg_price
from fruits
where s_id = 103;
avg( )也可以和group by一起使用
select o_num,avg(quantity * item_price) as avg_order
from orderitems
group by o_num;
这样也可以。。。
max( )函数 min( )
max( ) 返回指定列中的最大值
也可以和group by一起使用
max( ) 不仅适用于数值型,也适用于字符型
连接查询
连接查询是关系数据库中最主要的查询,主要有内连接和外连接,通过连接运算符可以实现多个表查询
内连接查询
外连接查询
复合连接查询
内连接查询
inner join
对表间的某些列进行比较操作,并列出这些表中与连接条件相匹配的数据行,组合成新的记录
在内连接查询中只有符合条件的记录才会出现在关系结果中
首先建立一些示例表
select suppliers.s_id, s_name, f_name, f_price // 这是你要选择的列
from fruits, suppliers // 从哪个表里面选择
where fruits.s_id = suppliers.s_id; // 选出的条件是什么
这里查询出来的结果是来自于两个不同的表
如果查询的表中有相同的列那么就要指定是来自于哪一个表
select suppliers.s_id, s_name, f_name, f_price
from fruits inner join suppliers
on fruits.s_id = suppliers.s_id; //这里的where 变成on了
查询供应f_id = 'a1'的水果供应商提供的其他种类的水果
select f1.f_id, f1.f_name
from fruits as f1, fruits as f2
where f1.s_id = f2.s_id and f2.f_id = 'a1';
这个查询好好回味一下
防止歧义性使用了别名
外连接查询
查询多个表中相关的行,内连接时仅是符合查询条件和连接条件的行
左连接:返回包括左表中的所有记录和右表中连接字段相等的记录
右连接:返回包括右表中的所有记录和左表中连接字段相等的记录
全连接:
left join 左连接
返回左表中所有的行而不仅仅是连接列匹配的行,如果左表的行在右表中没有匹配行,则在相关的连接结果中,右表的所有选择列均为空值
废话不多说,直接上例子
相关文章推荐
- mysql中datetime比较大小问题
- 【数据库】MySQL性能优化之swap占用高
- mysql更改表id自增数AUTO_INCREMENT
- ERROR 2002 (HY000): mysql
- 使用JDBC操作数据库(mysql):
- Mysql 性能调优之Memory 计算
- MySQL执行计划explain的key_len解析
- 深入mysql "ON DUPLICATE KEY UPDATE" 语法的分析
- MySQL复制应用中继日志解析
- MySQL用户管理和权限设置
- 使用MySQL正则表达式 __MySQL必知必会
- MySQL定义异常和异常处理方法
- mysql安装教程
- MySQL触发器使用详解
- mysql删除重复数据只保留一条
- mysql删除重复数据只保留一条
- Mysql :removeAbandonedTimeout:180
- Mysql查询语句优化技巧
- Mysql语句快速复习教程(全)
- mysql查询某列数据截取字符串