您的位置:首页 > 数据库 > MySQL

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 左连接

返回左表中所有的行而不仅仅是连接列匹配的行,如果左表的行在右表中没有匹配行,则在相关的连接结果中,右表的所有选择列均为空值

废话不多说,直接上例子
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: