SELECT 语句是最常用的查询语句,它的使用方式有些复杂,但功能是相当强大的。SELECT 语句的基本语法如下:
SELECT selection_list --要查询的内容,选择哪些列
FROM 数据表名 --指定数据表
WHERE primary_constraint --查询时需要满足的条件,行必须满足的条件
GROUP BY grouping_columns --如何对结果进行分组
ORDER BY sorting_cloumns --如何对结果进行排序
HAVING secondary_constraint --查询时满足的第二条件
LIMIT count --限定输出的查询结果
【示例1】数据准备。
--创建fruits表
mysql> CREATE TABLE fruits(
-> f_id CHAR(10) NOT NULL,
-> s_id INT NOT NULL,
-> f_name CHAR(255) NOT NULL,
-> f_price DECIMAL(8,2) NOT NULL,
-> PRIMARY KEY(f_id));
Query OK, 0 rows affected (0.05 sec)
--插入数据
INSERT INTO fruits(f_id,s_id,f_name,f_price)
VALUES('a1',101,'apple',5.2),
('b1',101,'blackberry',10.2),
('bs1',102,'orange',11.2),
('bs2',105,'melon',8.2),
('t1',102,'banana',10.3),
('t2',102,'grape',5.3),
('o2',103,'coconut',9.2),
('c0',101,'cherry',3.2),
('a2',103,'apricot',2.2),
('l2',104,'lemon',6.4),
('b2',104,'berry',7.6),
('m1',106,'mango',15.6),
('m2',105,'xbabay',2.6),
('t4',107,'xbababa',3.6),
('m3',105,'xxtt',11.6),
('b5',107,'xxxx',3.6);
【示例1】从 fruits 表中检索所有字段的数据,SQL语句如下:
SELECT * FROM fruits;
SELECT f_id,s_id,f_name,f_price FROM fruits;
SELECT fruits.f_id,fruits.s_id,fruits.f_name,fruits.f_price FROM fruits;
查询结果如下:
一般情况下,除非需要使用表中所有的字段数据,最好不要使用通配符 *
。 使用通配符虽然可以节省输入查询语句的时间,但是获取不需要的列数据通常会降低查询和所使用的应用程序的效率。通配符的优势是,当不知道所需要的列的名称时,可以通过它获取它们。
【示例2】查询单个字段。查询 fruits 表中f_name列所有水果名称,SQL语句如下:
mysql> SELECT f_name FROM fruits;
【示例3】查询多个字段。查询 fruits 表中f_name和f_price两列,SQL语句如下:
SELECT f_name,f_price FROM fruits;
如果要从很多记录中查询出指定的记录,那么就需要一个查询的条件。设定查询条件应用的是 WHERE 子句。通过它可以实现很多复杂的条件查询。在使用 WHERE 子句时,需要使用一些比较运算符来确定查询的条件。其常用比较运算符如下表所示:
运算符 | 名称 | 示例 | 运算符 | 名称 | 示例 |
---|---|---|---|---|---|
= | 等于 | id=5 | IS NOT NULL | 查询非空值 | id IS NOT NULL |
> | 大于 | id>5 | BETWEEN | n/a | is BETWEEN 1 AND 15 |
< | 小于 | id<5 | IN | n/a | id IN(3,4,5) |
>= | 大于等于 | id>=5 | NOT IN | n/a | name NOT IN(shi,li) |
<= | 小于等于 | id<=5 | LIKE | 模式匹配 | name LIKE(‘shi%’) |
!=或<> | 不等于 | id!=5 | NOT LIKE | 模式匹配 | name NOT LIKE(‘shi%’) |
IS NULL | 查询空值 | id IS NULL | regexp | 常规表达式 | name正则表达式 |
【示例4】查询指定记录。查询价格为10.2元的水果的名称,SQL语句如下:
SELECT f_name,f_price FROM fruits WHERE f_price=10.2;
【示例5】查询指定记录。查找名称为apple的水果的价格,SQL语句如下:
SELECT f_name,f_price FROM fruits WHERE f_name='apple';
【示例6】查询指定记录。查询价格小于10的水果的名称,SQL语句如下:
mysql> SELECT f_name,f_price FROM fruits WHERE f_price<10;
【示例7】带IN关键字的查询。s_id 为101和102的记录,SQL语句如下:
--语法:SELECT * FROM 表名 WHERE 条件 [NOT] IN(元素1,元素2,…,元素n);
SELECT s_id,f_name,f_price FROM fruits WHERE s_id IN(101,102);
【示例8】带IN关键字的查询。查询所有s_id 不等于101也不等于102的记录,SQL语句如下:
mysql> SELECT s_id,f_name,f_price FROM fruits WHERE s_id NOT IN(101,102);
+------+---------+---------+
| s_id | f_name | f_price |
+------+---------+---------+
| 103 | apricot | 2.20 |
| 104 | berry | 7.60 |
| 107 | xxxx | 3.60 |
| 105 | melon | 8.20 |
| 104 | lemon | 6.40 |
| 106 | mango | 15.60 |
| 105 | xbabay | 2.60 |
| 105 | xxtt | 11.60 |
| 103 | coconut | 9.20 |
| 107 | xbababa | 3.60 |
+------+---------+---------+
10 rows in set (0.00 sec)
【示例9】查询价格在2.00元~10.20元之间的水果名称和价格,SQL语句如下:
--语法:SELECT * FROM 表名 WHERE 条件 [NOT] BETWEEN 取值1 AND 取值2;
--取值1范围的起始值、取值2结束值,两者会被包括!
mysql> SELECT f_name,f_price FROM fruits WHERE f_price BETWEEN 2.00 AND 10.20;
+------------+---------+
| f_name | f_price |
+------------+---------+
| apple | 5.20 |
| apricot | 2.20 |
| blackberry | 10.20 |
| berry | 7.60 |
| xxxx | 3.60 |
| melon | 8.20 |
| cherry | 3.20 |
| lemon | 6.40 |
| xbabay | 2.60 |
| coconut | 9.20 |
| grape | 5.30 |
| xbababa | 3.60 |
+------------+---------+
12 rows in set (0.00 sec)
【示例10】查询价格在2.00元~10.20元之外的水果名称和价格,SQL语句如下:
SELECT f_name,f_price FROM fruits WHERE f_price NOT BETWEEN 2.00 AND 10.20;
【示例11】带Like的字符匹配查询。百分号%,匹配任意长度的字符,甚至包括零字符。查找所有以b字母开头的水果,SQL语句如下:
mysql> SELECT f_id,f_name FROM fruits WHERE f_name LIKE 'b%';
+------+------------+
| f_id | f_name |
+------+------------+
| b1 | blackberry |
| b2 | berry |
| t1 | banana |
+------+------------+
3 rows in set (0.00 sec)
【示例12】带Like的字符匹配查询。百分号%,匹配任意长度的字符,甚至包括零字符。在fruits表中,查询fruits表中包含字母g的记录,SQL语句如下:
SELECT f_id,f_name FROM fruits WHERE f_name LIKE '%g%';
【示例13】带Like的字符匹配查询。百分号%,匹配任意长度的字符,甚至包括零字符。查询以b开头,并以y结尾的水果的名称,SQL语句如下:
mysql> SELECT f_id,f_name FROM fruits WHERE f_name LIKE 'b%y';
+------+------------+
| f_id | f_name |
+------+------------+
| b1 | blackberry |
| b2 | berry |
+------+------------+
【示例14】带Like的字符匹配查询。下划线通配符_,一次只能匹配任意一个字符,在fruits表中,查询以字母y结尾,且y前面只有4个字母的记录,SQL语句如下:
mysql> SELECT f_id,f_name FROM fruits WHERE f_name LIKE '____y';
+------+--------+
| f_id | f_name |
+------+--------+
| b2 | berry |
+------+--------+
1 row in set (0.00 sec)
【示例15】在test数据库中创建customers表,并插入以下数据,SQL语句如下:
--建议大家在写创建表语句的时候可以先在高级记事本中书写,出现错误方便修改
--然后放到mysql黑窗口执行,当然也可以使用navicat这种图形化管理工具
mysql> CREATE TABLE customers(
-> c_id INT NOT NULL AUTO_INCREMENT,
-> c_name CHAR(50) NOT NULL,
-> c_address CHAR(50) NULL,
-> c_city CHAR(50) NULL,
-> c_zip CHAR(10) NULL,
-> c_contact CHAR(50) NULL,
-> c_email CHAR(255) NULL,
-> PRIMARY KEY(c_id));
Query OK, 0 rows affected (0.08 sec)
--插入数据
mysql> INSERT INTO customers(c_id,c_name,c_address,c_city,c_zip,c_contact,c_email)
-> VALUES(1001,'RedHook','200 Street','Tianjin','300000','LiMing','[email protected]'),
-> (1002,'Stars','333 Fromage Lane','Dalian','116000','Zhangbo','[email protected]'),
-> (1003,'Netbhood','1 Sunny Place','Qingdao','266000','LuoCong',NULL),
-> (1004,'JOTO','829 Riverside Drive','Haikou','570000','YangShan','[email protected]');
Query OK, 4 rows affected (0.01 sec)
Records: 4 Duplicates: 0 Warnings: 0
mysql> select * from customers;
+------+----------+---------------------+---------+--------+-----------+-------------------+
| c_id | c_name | c_address | c_city | c_zip | c_contact | c_email |
+------+----------+---------------------+---------+--------+-----------+-------------------+
| 1001 | RedHook | 200 Street | Tianjin | 300000 | LiMing | LMing@163.com |
| 1002 | Stars | 333 Fromage Lane | Dalian | 116000 | Zhangbo | Jerry@hotmail.com |
| 1003 | Netbhood | 1 Sunny Place | Qingdao | 266000 | LuoCong | NULL |
| 1004 | JOTO | 829 Riverside Drive | Haikou | 570000 | YangShan | sam@hotmail.com |
+------+----------+---------------------+---------+--------+-----------+-------------------+
4 rows in set (0.00 sec)
【示例16】查询customers表中c_email为空的记录的c_id、c_name和c_email字段值,SQL语句如下:
mysql> SELECT c_id,c_name,c_email FROM customers WHERE c_email IS NULL;
+------+----------+---------+
| c_id | c_name | c_email |
+------+----------+---------+
| 1003 | Netbhood | NULL |
+------+----------+---------+
1 row in set (0.00 sec)
【示例17】查询customers表中c_email不为空的记录的c_id、c_name和c_email字段值,SQL语句如下:
mysql> SELECT c_id,c_name,c_email FROM customers WHERE c_email IS NOT NULL;
+------+---------+-------------------+
| c_id | c_name | c_email |
+------+---------+-------------------+
| 1001 | RedHook | LMing@163.com |
| 1002 | Stars | Jerry@hotmail.com |
| 1004 | JOTO | sam@hotmail.com |
+------+---------+-------------------+
3 rows in set (0.00 sec)
【示例18】带AND的多条件查询。在fruits表中查询s_id=101,并且price大于等于5的水果的价格和名称,SQL语句如下:
--语法:SELECT * FROM 数据表名 WHERE 条件1 AND 条件2 […AND 条件表达式n];
mysql> SELECT f_id,f_name,f_price FROM fruits WHERE s_id=101 AND f_price>=5;
+------+------------+---------+
| f_id | f_name | f_price |
+------+------------+---------+
| a1 | apple | 5.20 |
| b1 | blackberry | 10.20 |
+------+------------+---------+
2 rows in set (0.00 sec)
【示例19】带AND的多条件查询。在fruits表中查询s_id=101或者102,并且price大于5,并且f_name='apple’的水果的价格和名称,SQL语句如下:
mysql> SELECT f_id,f_name,f_price FROM fruits WHERE s_id IN(101,102) AND f_price>5 AND f_name='apple';
+------+--------+---------+
| f_id | f_name | f_price |
+------+--------+---------+
| a1 | apple | 5.20 |
+------+--------+---------+
1 row in set (0.00 sec)
【示例20】带OR的多条件查询。查询s_id=101或者s_id=102的水果供应商的f_price和f_name,SQL语句如下:
SELECT f_id,f_name,f_price FROM fruits WHERE s_id=101 OR s_id=102;
SELECT f_id,f_name,f_price FROM fruits WHERE s_id IN(101,102);
【示例21】查询结果不重复。查询fruits表中s_id字段的值,返回s_id字段值且不得重复,SQL语句如下:
--语法:SELECT DISTINCT 字段名 FROM 表名;
SELECT distinct s_id FROM fruits;
【示例22】用ORDER BY关键字对查询结果排序。查询fruits表的f_name字段值,并对其进行排序,SQL语句如下:
--ORDER BY 字段名 [ASC|DESC];
-- ASC表示按升序进行排序(默认) DESC表示按降序进行排序。
SELECT f_name FROM fruits ORDER BY f_name;
【示例23】用ORDER BY关键字对查询结果排序。查询fruits表的f_name和f_price字段,先按f_name排序,再按f_price排序,SQL语句如下:
SELECT f_name,f_price FROM fruits ORDER BY f_name, f_price;
【示例24】查询fruits表中的f_name和f_price字段,对结果按f_price降序方式排序,SQL语句如下:
SELECT f_name,f_price FROM fruits ORDER BY f_price DESC;
【示例25】查询fruits表,先按f_price降序方式排序,再按f_name字段升序方式排序,SQL语句如下:
SELECT f_name,f_price FROM fruits ORDER BY f_price DESC, f_name ASC;
【示例26】根据s_id对fruits表中的数据进行分组。SQL语句如下:
mysql> SELECT s_id,COUNT(*) AS Total FROM fruits GROUP BY s_id;
+------+-------+
| s_id | Total |
+------+-------+
| 101 | 3 |
| 103 | 2 |
| 104 | 2 |
| 107 | 2 |
| 102 | 3 |
| 105 | 3 |
| 106 | 1 |
+------+-------+
7 rows in set (0.00 sec)
【示例27】根据s_id对fruits表中的数据进行分组,将每个供应商的水果名称显示出来,SQL语句如下:
mysql> SELECT s_id,GROUP_CONCAT(f_name) AS NameList,COUNT(*) AS Total FROM fruits GROUP BY s_id;
+------+-------------------------+-------+
| s_id | NameList | Total |
+------+-------------------------+-------+
| 101 | apple,blackberry,cherry | 3 |
| 102 | orange,banana,grape | 3 |
| 103 | apricot,coconut | 2 |
| 104 | berry,lemon | 2 |
| 105 | melon,xbabay,xxtt | 3 |
| 106 | mango | 1 |
| 107 | xxxx,xbababa | 2 |
+------+-------------------------+-------+
7 rows in set (0.00 sec)
【示例28】根据s_id对fruits表中的数据进行分组,并显示水果种类大于1的分组信息,SQL语句如下:
SELECT s_id,GROUP_CONCAT(f_name) AS NameList,COUNT(*) AS Total FROM fruits GROUP BY s_id HAVING COUNT(f_name)>1;
HAVING 在数据分组之后进行过滤来选择分组,而WHERE在分组之前用来选择记录。另外 WHERE 排除的记录不再包括在分组中。
【示例29】根据s_id对fruits表中的数据进行分组,并显示记录数量,SQL语句如下:
mysql> 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)
【示例30】根据s_id和f_name字段对fruits表中的数据进行分组。SQL语句如下:
SELECT * FROM fruits GROUP BY s_id,f_name;
【示例31】在test数据库中创建orderitems表,SQL语句如下:
mysql> CREATE TABLE orderitems(
-> o_num INT NOT NULL,
-> o_item INT NOT NULL,
-> f_id CHAR(10) NOT NULL,
-> quantity INT NOT NULL,
-> item_price DECIMAL(8,2) NOT NULL,
-> PRIMARY KEY(o_num,o_item));
Query OK, 0 rows affected (0.04 sec)
--插入数据
mysql> INSERT INTO orderitems(o_num,o_item,f_id,quantity,item_price)
-> VALUES(30001,1,'a1',10,5.2),
-> (30001,2,'b2',3,7.6),
-> (30001,3,'bs1',5,11.2),
-> (30001,4,'bs2',15,9.2),
-> (30002,1,'b3',2,20.0),
-> (30003,1,'c0',100,10),
-> (30004,1,'o2',50,2.50),
-> (30005,1,'c0',5,10),
-> (30005,2,'b1',10,8.99),
-> (30005,3,'a1',10,2.2),
-> (30005,4,'m1',5,14.99);
Query OK, 11 rows affected (0.01 sec)
Records: 11 Duplicates: 0 Warnings: 0
【示例32】查询订单价格大于100的订单号和总订单价格,SQL语句如下:
mysql> SELECT o_num, SUM(quantity*item_price) AS orderTotal FROM orderitems GROUP BY o_num HAVING SUM(quantity * item_price) >= 100;
+-------+------------+
| o_num | orderTotal |
+-------+------------+
| 30001 | 268.80 |
| 30003 | 1000.00 |
| 30004 | 125.00 |
| 30005 | 236.85 |
+-------+------------+
4 rows in set (0.00 sec)
--按照升序排列显示结果
mysql> SELECT o_num, SUM(quantity*item_price) AS orderTotal FROM orderitems GROUP BY o_num HAVING SUM(quantity * item_price) >= 100 ORDER BY orderTotal;
+-------+------------+
| o_num | orderTotal |
+-------+------------+
| 30004 | 125.00 |
| 30005 | 236.85 |
| 30001 | 268.80 |
| 30003 | 1000.00 |
+-------+------------+
4 rows in set (0.00 sec)
--按照降序排列显示结果
mysql> 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)
【示例33】查询数据时,可能会查询出很多的记录。而用户需要的记录可能只是很少的一部分。这样就需要来限制查询结果的数量。LIMIT是MySQL中的一个特殊关键字。LIMIT子句可以对查询结果的记录条数进行限定,控制它输出的行数。显示fruits表查询结果的前4行,SQL语句如下:
--limit 后面可以接两个参数,
--第一个参数表示从哪行开始返回,第二个参数表示返回几行,第一个参数可以省略。
mysql> SELECT * FROM fruits limit 4;
【示例34】在fruits表中,使用LIMIT子句,返回从第5个记录开始的,行数长度为3的记录,SQL语句如下:
--注意:第5个记录的在使用limit表示的时候第一个参数要写4
--limit的第一个参数的值是从0开始表示第1行,1开始表示第2行....
mysql> SELECT * FROM fruits limit 4,3;
+------+------+--------+---------+
| f_id | s_id | f_name | f_price |
+------+------+--------+---------+
| b5 | 107 | xxxx | 3.60 |
| bs1 | 102 | orange | 11.20 |
| bs2 | 105 | melon | 8.20 |
+------+------+--------+---------+
3 rows in set (0.00 sec)
【示例35】聚合函数查询。查询customers表中总的行数,SQL语句如下:
--COUNT(*):计算表中总的行数,不管某列有数值或者为空值。
--COUNT(字段名):计算指定列下总的行数,计算时将忽略空值的行。
mysql> SELECT COUNT(*) FROM customers;
+----------+
| COUNT(*) |
+----------+
| 5 |
+----------+
1 row in set (0.03 sec)
【示例36】聚合函数查询。查询customers表中有电子邮箱的顾客的总数,SQL语句如下:
mysql> SELECT COUNT(c_email) FROM customers;
+----------------+
| COUNT(c_email) |
+----------------+
| 4 |
+----------------+
1 row in set (0.00 sec)
【示例37】在orderitems表中,使用COUNT()函数统计不同订单号中订购的水果种类,SQL语句如下:
mysql> SELECT o_num,COUNT(f_id) FROM orderitems GROUP BY o_num;
+-------+-------------+
| o_num | COUNT(f_id) |
+-------+-------------+
| 30001 | 4 |
| 30002 | 1 |
| 30003 | 1 |
| 30004 | 1 |
| 30005 | 4 |
+-------+-------------+
5 rows in set (0.00 sec)
【示例38】在orderitems表中查询30005号订单一共购买的水果总量,SQL语句如下:
--SUM()函数是一个求总和的函数,返回指定列值的总和。
--SUM()函数在计算的时候,会忽略值为NULL的行。
mysql> SELECT SUM(quantity) FROM orderitems WHERE o_num=30005;
+---------------+
| SUM(quantity) |
+---------------+
| 30 |
+---------------+
1 row in set (0.00 sec)
【示例39】在orderitems表中,使用sum()函数统计不同订单号中订购的水果总量,SQL语句如下:
mysql> SELECT o_num,SUM(quantity) FROM orderitems GROUP BY o_num;
+-------+---------------+
| o_num | SUM(quantity) |
+-------+---------------+
| 30001 | 33 |
| 30002 | 2 |
| 30003 | 100 |
| 30004 | 50 |
| 30005 | 30 |
+-------+---------------+
5 rows in set (0.00 sec)
【示例40】在fruits表中,查询s_id=103的供应商的水果价格的平均值,SQL语句如下:
--AVG()函数通过计算返回的行数和每一行数据的和,求得指定列数据的平均值。
mysql> SELECT AVG(f_price) FROM fruits WHERE s_id=103;
+--------------+
| AVG(f_price) |
+--------------+
| 5.700000 |
+--------------+
1 row in set (0.00 sec)
【示例41】在fruits表中,查询每一个供应商的水果价格的平均值,SQL语句如下:
mysql> SELECT s_id,AVG(f_price) FROM fruits GROUP BY s_id;
+------+--------------+
| s_id | AVG(f_price) |
+------+--------------+
| 101 | 6.200000 |
| 103 | 5.700000 |
| 104 | 7.000000 |
| 107 | 3.600000 |
| 102 | 8.933333 |
| 105 | 7.466667 |
| 106 | 15.600000 |
+------+--------------+
7 rows in set (0.00 sec)
【示例42】在fruits表中查找市场上价格最高的水果,SQL语句如下:
--MAX()返回指定列中的最大值。
mysql> SELECT MAX(f_price) AS max_price FROM fruits;
+-----------+
| max_price |
+-----------+
| 15.60 |
+-----------+
1 row in set (0.00 sec)
【示例43】在fruits表中查找不同供应商提供的价格最高的水果,SQL语句如下:
mysql> SELECT s_id,MAX(f_price) AS max_price FROM fruits GROUP BY s_id;
+------+-----------+
| s_id | max_price |
+------+-----------+
| 101 | 10.20 |
| 103 | 9.20 |
| 104 | 7.60 |
| 107 | 3.60 |
| 102 | 11.20 |
| 105 | 11.60 |
| 106 | 15.60 |
+------+-----------+
7 rows in set (0.00 sec)
【示例44】在fruits表中查找f_name的最大值,SQL语句如下:
mysql> SELECT MAX(f_name) FROM fruits;
+-------------+
| MAX(f_name) |
+-------------+
| xxxx |
+-------------+
1 row in set (0.00 sec)
【示例45】在fruits表中查找市场上价格最小的水果,SQL语句如下:
--MIN()返回查询列中的最小值。
mysql> SELECT MIN(f_price) AS min_price FROM fruits;
+-----------+
| min_price |
+-----------+
| 2.20 |
+-----------+
1 row in set (0.00 sec)
【示例46】在fruits表中查找不同供应商提供的价格最小的水果,SQL语句如下:
mysql> SELECT s_id,MIN(f_price) AS max_price FROM fruits GROUP BY s_id;
+------+-----------+
| s_id | max_price |
+------+-----------+
| 101 | 3.20 |
| 103 | 2.20 |
| 104 | 6.40 |
| 107 | 3.60 |
| 102 | 5.30 |
| 105 | 2.60 |
| 106 | 15.60 |
+------+-----------+
7 rows in set (0.00 sec)