MySQL基本查询【3/29】

MySQL基本查询【3/29】

单表查询、带IN关键字的查询、带BETWEEN AND的范围查询、带LIKE的字符匹配查询、带AND的多条件查询等

MySQL基础查询【3月29日】

SELECT {* | <字段列表>}
[
FROM <表1>,<表2>…
[WHERE <表达式>]
[GROUP BY <group by definition>]
[HAVING <expression> [{<operator> <expression>}…]]
[ORDER BY <order by definition>]
[LIMIT [<offset>,] <row count>]
]
SELECT [字段1,字段2,…,字段n]
FROM [表或视图]
WHERE [查询条件]

{* | <字段列表>}包含星号通配符选字段列表,表示查询的字段,其中字段列表至少包含一个字段名称,如果要查询多个字段,多个字段之间用“,”隔开,最后一个字段不加逗号。

FROM <表1>,<表2>…,表1和表2表示查询数据的来源,可以是单个或多个。

WHERE子句是可选项,如果选择该项,将限定查询行必须满足的查询条件

GROUP BY<字段>,如何显示查询出来的数据,并按照指定的字段分组

[ORDER BY<字段>]按什么样的顺序显示查询出来的数据,可以进行的排序有:升序(ASC),降序(DESC)

[LIMIT [<offset>,] <row count>]每次显示查询出来的数据条数。mysql> SELECT f_id, f_name FROM fruits;
±-----±----------+
| f_id | f_name |
±-----±----------+
| a1 | apple |
| a2 | apricot |
| b1 | blckberry |
| b2 | berry |
| b5 | xxxx |
| bs1 | orange |
| bs2 | melon |
| c0 | cherry |
| l2 | lemon |
| m1 | mango |
| m2 | xbabay |
| m3 | xxtt |
| o2 | cocount |
| t1 | banana |
| t2 | grape |
| t4 | xbababa |
±-----±----------+
16 rows in set (0.00 sec)

显示的顺序为添加到表中的顺序。

  • 单表查询:

查询所有字段:

1
SELECT * FROM 表名;

查询指定字段:
SELECT 列名 FROM 表名;

查询指定记录:
SELECT 字段1,字段2,…,字段名n FROM 表名 WHERE 查询条件

WHERE 条件判断符

|操作符|说明
|------
|=|相等
|<>,!=|不相等
|<|小于
|<=|小于或等于
|>|大于
|>=|大于或者等于
|BETWEEN|位于两值之间

比较数字:
mysql> SELECT f_name,f_price FROM fruits WHERE f_price = 10.2;

比较字符串:
mysql> SELECT f_name,f_price FROM fruits WHERE f_name = 'apple';

  • 带IN关键字的查询:

查询满足指定条件范围的记录:
mysql> SELECT s_id,f_name,f_price FROM fruits WHERE s_id IN (101,102) ORDER BY f_name;
±-----±----------±--------+
| s_id | f_name | f_price |
±-----±----------±--------+
| 101 | apple | 5.20 |
| 102 | banana | 10.30 |
| 101 | blckberry | 10.20 |
| 101 | cherry | 3.20 |
| 102 | grape | 5.30 |
| 102 | orange | 11.30 |
±-----±----------±--------+
6 rows in set (0.00 sec)

查询不在指定范围内的记录:
mysql> SELECT s_id,f_name,f_price FROM fruits WHERE s_id NOT IN (101,102) ORDER BY f_name;
±-----±--------±--------+
| s_id | f_name | f_price |
±-----±--------±--------+
| 103 | apricot | 2.20 |
| 104 | berry | 7.60 |
| 103 | cocount | 9.20 |
| 104 | lemon | 6.40 |
| 106 | mango | 15.60 |
| 105 | melon | 8.20 |
| 107 | xbababa | 3.60 |
| 105 | xbabay | 2.60 |
| 105 | xxtt | 11.60 |
| 107 | xxxx | 3.60 |
±-----±--------±--------+
10 rows in set (0.00 sec)

  • 带BETWEEN AND的范围查询
    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 |
    | blckberry | 10.20 |
    | berry | 7.60 |
    | xxxx | 3.60 |
    | melon | 8.20 |
    | cherry | 3.20 |
    | lemon | 6.40 |
    | xbabay | 2.60 |
    | cocount | 9.20 |
    | grape | 5.30 |
    | xbababa | 3.60 |
    ±----------±--------+
    12 rows in set (0.00 sec)

    mysql> SELECT f_name,f_price FROM fruits WHERE f_price NOT BETWEEN 2.00 AND 10.20;
    ±-------±--------+
    | f_name | f_price |
    ±-------±--------+
    | orange | 11.30 |
    | mango | 15.60 |
    | xxtt | 11.60 |
    | banana | 10.30 |
    ±-------±--------+
    4 rows in set (0.00 sec)

  • 带LIKE的字符匹配查询:

**‘%’匹配任意长度的字符,甚至包括0字符,‘_’**一次只能匹配任意一个字符
mysql> SELECT f_id,f_name FROM fruits WHERE f_name LIKE 'b%';
±-----±----------+
| f_id | f_name |
±-----±----------+
| b1 | blckberry |
| b2 | berry |
| t1 | banana |
±-----±----------+
3 rows in set (0.00 sec)
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)

查询表结构
mysql> describe fruits;
±--------±-------------±-----±----±--------±------+
| Field | Type | Null | Key | Default | Extra |
±--------±-------------±-----±----±--------±------+
| f_id | char(10) | NO | PRI | NULL | |
| s_id | int(11) | NO | | NULL | |
| f_name | char(255) | NO | | NULL | |
| f_price | decimal(8,2) | NO | | NULL | |
±--------±-------------±-----±----±--------±------+
4 rows in set (0.01 sec)

查询空值:空值指数据未知,不适用或将在以后添加数据

查询计数
mysql> SELECT COUNT(*) AS cust_num FROM customers;
±---------+
| cust_num |
±---------+
| 4 |
±---------+
1 row in set (0.00 sec)

查询空值
mysql> SELECT c_id,c_name,c_email FROM customers WHERE c_email IS NULL;
±------±---------±--------+
| c_id | c_name | c_email |
±------±---------±--------+
| 10003 | Netbhood | NULL |
±------±---------±--------+
1 row in set (0.00 sec)

查询字段不为空的记录
mysql> SELECT c_id,c_name,c_email FROM customers WHERE c_email IS NOT NULL;
±------±--------±------------------+
| c_id | c_name | c_email |
±------±--------±------------------+
| 10001 | RedHook | [email protected] |
| 10002 | Stars | [email protected] |
| 10004 | JOTO | [email protected] |
±------±--------±------------------+
3 rows in set (0.00 sec)

  • 带AND的多条件查询:
    mysql> SELECT f_id,f_price,f_name FROM fruits WHERE s_id = '101' AND f_price >=5;
    ±-----±--------±----------+
    | f_id | f_price | f_name |
    ±-----±--------±----------+
    | a1 | 5.20 | apple |
    | b1 | 10.20 | blckberry |
    ±-----±--------±----------+
    2 rows in set (0.00 sec)

带OR的多条件查询,只要满足其中一个条件记录即返回
mysql> SELECT s_id,f_price,f_name FROM fruits WHERE s_id = 101 OR s_id = 102;
±-----±--------±----------+
| s_id | f_price | f_name |
±-----±--------±----------+
| 101 | 5.20 | apple |
| 101 | 10.20 | blckberry |
| 102 | 11.30 | orange |
| 101 | 3.20 | cherry |
| 102 | 10.30 | banana |
| 102 | 5.30 | grape |
±-----±--------±----------+
6 rows in set (0.00 sec)

OR操作符和IN操作符作用效果一样,但IN快一些,且可以执行更加复杂的嵌套查询。

AND的优先级高于OR,因此先对AND两边的操作数进行操作,再与OR中操作数结合。

  • 去重复操作
    mysql> SELECT DISTINCT s_id FROM fruits;
    ±-----+
    | s_id |
    ±-----+
    | 101 |
    | 103 |
    | 104 |
    | 107 |
    | 102 |
    | 105 |
    | 106 |
    ±-----+

对查询结果进行排序
mysql> SELECT f_name FROM fruits ORDER BY f_name;
±----------+
| f_name |
±----------+
| apple |
| apricot |
| banana |
| berry |
| blckberry |
| cherry |
| cocount |
| grape |
| lemon |
| mango |
| melon |
| orange |
| xbababa |
| xbabay |
| xxtt |
| xxxx |
±----------+
16 rows in set (0.00 sec)

  • 多列排序
    mysql> SELECT f_name,f_price FROM fruits ORDER BY f_name,f_price;
    ±----------±--------+
    | f_name | f_price |
    ±----------±--------+
    | apple | 5.20 |
    | apricot | 2.20 |
    | banana | 10.30 |
    | berry | 7.60 |
    | blckberry | 10.20 |
    | cherry | 3.20 |
    | cocount | 9.20 |
    | grape | 5.30 |
    | lemon | 6.40 |
    | mango | 15.60 |
    | melon | 8.20 |
    | orange | 11.30 |
    | xbababa | 3.60 |
    | xbabay | 2.60 |
    | xxtt | 11.60 |
    | xxxx | 3.60 |
    ±----------±--------+
    16 rows in set (0.00 sec)

在对多列进行排序的时候,首先排序的第一列必须有相同的列值,才会对第二列进行排序。如果第一列数据中所有的值都是唯一的,将不再对第二列进行排序。

在排序的时候(ASC)为默认的排序方式。

先按f_price降序排序,再将f_name字段升序排序

如果要对多列进行降序排序,必须要在每一列的列名后面加DESC关键字

分组查询

GROUP BY 通常与集合函数一起使用:MAX(),MIN(),COUNT(),SUM(),AVG()
mysql> SELECT s_id,COUNT(*) AS Total FROM fruits GROUP BY s_id;
±-----±------+
| s_id | Total |
±-----±------+
| 101 | 3 |
| 102 | 3 |
| 103 | 2 |
| 104 | 2 |
| 105 | 3 |
| 106 | 1 |
| 107 | 2 |
±-----±------+
7 rows in set (0.00 sec)

显示每个分组的各个字段

1
2
3
4
5
6
7
8
9
10
11
12
13
mysql> SELECT s_id,GROUP_CONCAT(f_name) AS Names FROM fruits GROUP BY s_id;
+------+------------------------+
| s_id | Names |
+------+------------------------+
| 101 | apple,blckberry,cherry |
| 102 | orange,banana,grape |
| 103 | apricot,cocount |
| 104 | berry,lemon |
| 105 | melon,xbabay,xxtt |
| 106 | mango |
| 107 | xxxx,xbababa |
+------+------------------------+
7 rows in set (0.00 sec)
  • 使用HAVIING过滤分组

显示水果种类大于1的分组信息
mysql> SELECT s_id,GROUP_CONCAT(f_name) AS Names FROM fruits GROUP BY s_id HAVING COUNT(f_name)>1;
±-----±-----------------------+
| s_id | Names |
±-----±-----------------------+
| 101 | apple,blckberry,cherry |
| 102 | orange,banana,grape |
| 103 | apricot,cocount |
| 104 | berry,lemon |
| 105 | melon,xbabay,xxtt |
| 107 | xxxx,xbababa |
±-----±-----------------------+
6 rows in set (0.00 sec)

HAVING和WHERE 过滤数据的区别

HAVING在数据分组之后进行过滤,WHERE分组之前用来选择记录,WHERE排除的记录将不包含在分组中

使用WITH ROLLUP,在所有查询出的分组记录之后增加一条记录,该记录计算查询出的所有记录的总和,统计记录数量。
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)

多字段分组,分组层次从左至右,先按第一个字段分组,然后在第一个字段值相同的记录中,再根据第2个字段的值进行分组。
mysql> SELECT * FROM fruits GROUP BY s_id,f_name;
±-----±-----±----------±--------+
| f_id | s_id | f_name | f_price |
±-----±-----±----------±--------+
| a1 | 101 | apple | 5.20 |
| b1 | 101 | blckberry | 10.20 |
| c0 | 101 | cherry | 3.20 |
| t1 | 102 | banana | 10.30 |
| t2 | 102 | grape | 5.30 |
| bs1 | 102 | orange | 11.30 |
| a2 | 103 | apricot | 2.20 |
| o2 | 103 | cocount | 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.01 sec)

2019年3月31日更新

GROUP BY和ORDER BY进行分组排序

表结构
Database changed
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.01 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,'a2',10,2.2),
-> (30005,4,'m1',5,14.99);
Query OK, 11 rows affected (0.01 sec)
Records: 11 Duplicates: 0 Warnings: 0

查询订单价格大于100的订单号和总订单价格
mysql> SELECT o_num,SUM(quantityitem_price) AS order_total FROM orderitems GROUP BY o_num HAVING SUM(quantityitem_price)>=100;
±------±------------+
| o_num | order_total |
±------±------------+
| 30001 | 268.80 |
| 30003 | 1000.00 |
| 30004 | 125.00 |
| 30005 | 236.85 |
±------±------------+

对order_total进行排序
mysql> SELECT o_num,SUM(quantityitem_price) AS order_total FROM orderitems GROUP BY o_num HAVING SUM(quantityitem_price)>=100 ORDER BY order_total;
±------±------------+
| o_num | order_total |
±------±------------+
| 30004 | 125.00 |
| 30005 | 236.85 |
| 30001 | 268.80 |
| 30003 | 1000.00 |
±------±------------+
4 rows in set (0.00 sec)

ROLLUP和ORDER BY是互斥的

使用LIMIT限制查询结果的数量

1
LIMIT [位置偏移量,] 行数

第一条记录的位置偏移量是0

查前4行
mysql> SELECT * FROM fruits LIMIT 4;
±-----±-----±----------±--------+
| f_id | s_id | f_name | f_price |
±-----±-----±----------±--------+
| a1 | 101 | apple | 5.20 |
| a2 | 103 | apricot | 2.20 |
| b1 | 101 | blckberry | 10.20 |
| b2 | 104 | berry | 7.60 |
±-----±-----±----------±--------+
4 rows in set (0.00 sec)

从第5个记录开始,行数长度为3的记录
mysql> SELECT * FROM fruits LIMIT 4,3;
±-----±-----±-------±--------+
| f_id | s_id | f_name | f_price |
±-----±-----±-------±--------+
| b5 | 107 | xxxx | 3.60 |
| bs1 | 102 | orange | 11.30 |
| bs2 | 105 | melon | 8.20 |
±-----±-----±-------±--------+
3 rows in set (0.00 sec)

MySQL聚合函数

|函数|作用
|------
|AVG()|返回某列的平均值
|COUNT()|返回某列的行数
|MAX()|返回某列的最大值
|MIN()|返回某列的最小值
|SUM()|返回某列值的和

【计算某一字段总的行数,忽略空值的行】查询customers表中有电子邮箱的顾客的总数
mysql> SELECT COUNT(c_email) AS email_num FROM customers;
±----------+
| email_num |
±----------+
| 3 |
±----------+
1 row in set (0.00 sec)

【COUNT(*)不忽略记录中的空值行】

SUM计算每个分组中记录的总和,忽略空值行
mysql> SELECT o_num,SUM(quantity) AS items_total FROM orderitems GROUP BY o_num;
±------±------------+
| o_num | items_total |
±------±------------+
| 30001 | 33 |
| 30002 | 2 |
| 30003 | 100 |
| 30004 | 50 |
| 30005 | 30 |
±------±------------+
5 rows in set (0.00 sec)

AVG()求指定列数据的平均值
mysql> SELECT AVG(f_price) AS avg_price FROM fruits WHERE s_id =103;
±----------+
| avg_price |
±----------+
| 5.700000 |
±----------+
1 row in set (0.00 sec)

如果多列求多个平均值,则每一列都要用AVG函数

查找不同供应商提供的价格最高的水果值
mysql> SELECT s_id,MAX(f_price) AS max_price FROM fruits GROUP BY s_id;
±-----±----------+
| s_id | max_price |
±-----±----------+
| 101 | 10.20 |
| 102 | 11.30 |
| 103 | 9.20 |
| 104 | 7.60 |
| 105 | 11.60 |
| 106 | 15.60 |
| 107 | 3.60 |
±-----±----------+
7 rows in set (0.00 sec)

MAX可以返回字符的最大值,按ASCII码值,先比较第一个字母,如果相等,继续比较下一个,一直到两个字符不相等或者字符结束为止。

连接查询

当两个或多个表中存在相同意义的字段时,便可以通过这些字段对不同的表进行连接查询

内连接(INNER JOIN)使用比较运算符进行表间某些列数据的比较操作,并列出这些表中与连接条件相匹配的数据行,组合成新的记录。

俩个表都具有相同字段s_id
mysql> DESC fruits;
±--------±-------------±-----±----±--------±------+
| Field | Type | Null | Key | Default | Extra |
±--------±-------------±-----±----±--------±------+
| f_id | char(10) | NO | PRI | NULL | |
| s_id | int(11) | NO | | NULL | |
| f_name | char(255) | NO | | NULL | |
| f_price | decimal(8,2) | NO | | NULL | |
±--------±-------------±-----±----±--------±------+
4 rows in set (0.06 sec)

mysql> DESC suppliers;
±-------±---------±-----±----±--------±---------------+
| Field | Type | Null | Key | Default | Extra |
±-------±---------±-----±----±--------±---------------+
| s_id | int(11) | NO | PRI | NULL | auto_increment |
| s_name | char(50) | NO | | NULL | |
| s_city | char(50) | YES | | NULL | |
| s_zip | char(10) | YES | | NULL | |
| s_call | char(50) | NO | | NULL | |
±-------±---------±-----±----±--------±---------------+
5 rows in set (0.00 sec)

从fruits表中查f_name、f_price字段,从suppliers表中查询s_id、s_name
mysql> SELECT suppliers.s_id,s_name,f_name,f_price FROM fruits,suppliers WHERE fruits.s_id = suppliers.s_id;
±-----±---------------±----------±--------+
| s_id | s_name | f_name | f_price |
±-----±---------------±----------±--------+
| 101 | FastFruit Inc. | apple | 5.20 |
| 103 | ACME | apricot | 2.20 |
| 101 | FastFruit Inc. | blckberry | 10.20 |
| 104 | FNK Inc. | berry | 7.60 |
| 107 | DK Inc | xxxx | 3.60 |
| 102 | LT Supplies | orange | 11.30 |
| 105 | Good Set. | melon | 8.20 |
| 101 | FastFruit Inc. | cherry | 3.20 |
| 104 | FNK Inc. | lemon | 6.40 |
| 106 | Just Eat Ours | mango | 15.60 |
| 105 | Good Set. | xbabay | 2.60 |
| 105 | Good Set. | xxtt | 11.60 |
| 103 | ACME | cocount | 9.20 |
| 102 | LT Supplies | banana | 10.30 |
| 102 | LT Supplies | grape | 5.30 |
| 107 | DK Inc | xbababa | 3.60 |
±-----±---------------±----------±--------+
16 rows in set (0.01 sec)

使用内连接进行查询
mysql> SELECT suppliers.s_id,s_name,f_name,f_price FROM fruits,suppliers WHERE fruits.s_id = suppliers.s_id;
±-----±---------------±----------±--------+
| s_id | s_name | f_name | f_price |
±-----±---------------±----------±--------+
| 101 | FastFruit Inc. | apple | 5.20 |
| 103 | ACME | apricot | 2.20 |
| 101 | FastFruit Inc. | blckberry | 10.20 |
| 104 | FNK Inc. | berry | 7.60 |
| 107 | DK Inc | xxxx | 3.60 |
| 102 | LT Supplies | orange | 11.30 |
| 105 | Good Set. | melon | 8.20 |
| 101 | FastFruit Inc. | cherry | 3.20 |
| 104 | FNK Inc. | lemon | 6.40 |
| 106 | Just Eat Ours | mango | 15.60 |
| 105 | Good Set. | xbabay | 2.60 |
| 105 | Good Set. | xxtt | 11.60 |
| 103 | ACME | cocount | 9.20 |
| 102 | LT Supplies | banana | 10.30 |
| 102 | LT Supplies | grape | 5.30 |
| 107 | DK Inc | xbababa | 3.60 |
±-----±---------------±----------±--------+
16 rows in set (0.01 sec)

在一个连接查询中,涉及到的两个表都是同一个表,这种查询称为自连接查询。

查询供应f_id = ‘a1’的水果供应商提供的其他水果种类
mysql> 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';
±-----±----------+
| f_id | f_name |
±-----±----------+
| a1 | apple |
| b1 | blckberry |
| c0 | cherry |
±-----±----------+
3 rows in set (0.01 sec)

外连接

LEFT JOIN(左连接):返回包括左表中的所有记录和右表中连接字段相等的记录

RIGHT JOIN(右连接):返回包括右表中的所有记录和左表中连接字段相等的记录

左连接的结果包括LEFT OUTER子句中指定的左表的所有行,而不仅仅是连接列所匹配的行。如果左表的某行在右表中没有匹配行,则在相关联的结果行中,右表中的所有选择列表列均为空值。

查询所有客户,包括没有订单的客户
mysql> SELECT customers.c_id,orders.o_num FROM customers LEFT OUTER JOIN orders ON customers.c_id = orders.c_id;
±------±------+
| c_id | o_num |
±------±------+
| 10001 | 30001 |
| 10003 | 30002 |
| 10004 | 30003 |
| 10001 | 30005 |
| 10002 | NULL |
±------±------+
5 rows in set (0.00 sec)

查询所有订单,包括没有客户的订单
mysql> SELECT customers.c_id,orders.o_num FROM customers RIGHT OUTER JOIN orders ON customers.c_id = orders.c_id;
±------±------+
| c_id | o_num |
±------±------+
| 10001 | 30001 |
| 10003 | 30002 |
| 10004 | 30003 |
| NULL | 30004 |
| 10001 | 30005 |
±------±------+
5 rows in set (0.00 sec)

复合条件连接查询

通过添加过滤条件,限制查询结果

查询customers表中ID为10001的客户的订单信息
mysql> SELECT customers.c_id,orders.o_num FROM customers INNER JOIN orders ON customers.c_id = orders.c_id AND customers.c_id =10001;
±------±------+
| c_id | o_num |
±------±------+
| 10001 | 30001 |
| 10001 | 30005 |
±------±------+
2 rows in set (0.00 sec)

子查询

子查询结果作为外层另一个查询的过滤条件。

常用操作符ANY(SOME)\ALL\IN\EXISTS

ANY\SOME表示满足其中任一条件,只要满足内层子查询的任何一个比较条件,就返回一个结果作为外层查询的条件。

ANY关键字接在一个比较操作符后面,表示若与子查询返回的任何值比较为TRUE,则返回TRUE
mysql> INSERT INTO tb11 values(1),(5),(13),(27);
Query OK, 4 rows affected (0.00 sec)
Records: 4 Duplicates: 0 Warnings: 0

mysql> INSERT INTO tb12 values(6),(14),(11),(20);
Query OK, 4 rows affected (0.00 sec)
Records: 4 Duplicates: 0 Warnings: 0

mysql> SELECT num1 FROM tb11 WHERE num1 > ANY (SELECT num2 FROM tb12);
±-----+
| num1 |
±-----+
| 13 |
| 27 |
±-----+
2 rows in set (0.00 sec)

ALL需要同时满足所有内层查询的条件
mysql> SELECT num1 FROM tb11 WHERE num1 > ALL (SELECT num2 FROM tb12);
±-----+
| num1 |
±-----+
| 27 |
±-----+
1 row in set (0.00 sec)

EXISTS关键字后面参数是任意一个子查询,系统对子查询进行运算以判断它是否返回行,如果至少返回一行,则结果为true,此时外层查询语句将进行查询。

查询suppliers表中是否存在s_id=107的供应商,如果存在,则查询fruits表中的记录:
mysql> SELECT * FROM fruits WHERE EXISTS (SELECT s_name FROM suppliers WHERE s_id = 107);
±-----±-----±----------±--------+
| f_id | s_id | f_name | f_price |
±-----±-----±----------±--------+
| a1 | 101 | apple | 5.20 |
| a2 | 103 | apricot | 2.20 |
| b1 | 101 | blckberry | 10.20 |
| b2 | 104 | berry | 7.60 |
| b5 | 107 | xxxx | 3.60 |
| bs1 | 102 | orange | 11.30 |
| bs2 | 105 | melon | 8.20 |
| c0 | 101 | cherry | 3.20 |
| l2 | 104 | lemon | 6.40 |
| m1 | 106 | mango | 15.60 |
| m2 | 105 | xbabay | 2.60 |
| m3 | 105 | xxtt | 11.60 |
| o2 | 103 | cocount | 9.20 |
| t1 | 102 | banana | 10.30 |
| t2 | 102 | grape | 5.30 |
| t4 | 107 | xbababa | 3.60 |
±-----±-----±----------±--------+
16 rows in set (0.00 sec)

查询suppliers表中是否存在s_id = 107的供应商,如果存在,则查询fruits表中的f_price大于10.20的记录
mysql> SELECT * FROM fruits WHERE f_price>10.20 AND EXISTS (SELECT s_name FROM suppliers WHERE s_id = 107);
±-----±-----±-------±--------+
| f_id | s_id | f_name | f_price |
±-----±-----±-------±--------+
| bs1 | 102 | orange | 11.30 |
| m1 | 106 | mango | 15.60 |
| m3 | 105 | xxtt | 11.60 |
| t1 | 102 | banana | 10.30 |
±-----±-----±-------±--------+
4 rows in set (0.01 sec)

EXISTS和NOT EXISTS的结果只取决于是否会返回行,而不取决于这些行的内容。

带IN关键字的子查询

在orderitems表中查询f_id为c0的订单号,并根据订单号查询具有订单号的客户c_id
mysql> SELECT c_id FROM orders WHERE o_num IN (SELECT o_num FROM orderitems WHERE f_id = 'c0');
±------+
| c_id |
±------+
| 10004 |
| 10001 |
±------+
2 rows in set (0.00 sec)

UNION关键字可以给出多条SELECT语句,并将它们的结果组合成单个结果集,合并时,两个表对应的列数和数据类型必须相同。

SELECT语句之间使用UNION (执行的时候删除重复记录)和 UNION ALL(不删除重复行也不对结果进行重复排序)分隔
mysql> SELECT s_id,f_name,f_price FROM fruits WHERE f_price < 9.0 UNION ALL SELECT s_id,f_name,f_price FROM fruits WHERE s_id IN (101,103);
±-----±----------±--------+
| s_id | f_name | f_price |
±-----±----------±--------+
| 101 | apple | 5.20 |
| 103 | apricot | 2.20 |
| 104 | berry | 7.60 |
| 107 | xxxx | 3.60 |
| 105 | melon | 8.20 |
| 101 | cherry | 3.20 |
| 104 | lemon | 6.40 |
| 105 | xbabay | 2.60 |
| 102 | grape | 5.30 |
| 107 | xbababa | 3.60 |
| 101 | apple | 5.20 |
| 103 | apricot | 2.20 |
| 101 | blckberry | 10.20 |
| 101 | cherry | 3.20 |
| 103 | cocount | 9.20 |
±-----±----------±--------+
15 rows in set (0.06 sec)

确定查询结果中不会有重复数据或者不需要去掉重复数据的时候,使用UNION ALL以提高查询效率

分别取别名,并进行连接查询
mysql> SELECT c.c_id,o.o_num FROM customers AS c LEFT OUTER JOIN orders AS o ON c.c_id=o.c_id;
±------±------+
| c_id | o_num |
±------±------+
| 10001 | 30001 |
| 10003 | 30002 |
| 10004 | 30003 |
| 10001 | 30005 |
| 10002 | NULL |
±------±------+
5 rows in set (0.01 sec)

表、字段别名
mysql> SELECT CONCAT(TRIM(s_name),'(',TRIM(s_city),')') AS suppliers_title FROM suppliers ORDER BY s_name;
±------------------------+
| suppliers_title |
±------------------------+
| ACME(Shanghai) |
| DK Inc(Zhengzhou) |
| FastFruit Inc.(Tianjin) |
| FNK Inc.(Zhongshan) |
| Good Set.(Taiyuang) |
| Just Eat Ours(Beijing) |
| LT Supplies(Chongqing) |
±------------------------+
7 rows in set (0.01 sec)

|选项|说明|例子
|------
||匹配文本的开始字符|‘b’匹配以字母b开头的字符串
|st|匹配文本的结束字符|‘st’匹配以st结尾的字符串
|.|匹配任何单个字符|‘b.t’匹配任何b和t之间有一个字符
||匹配零个或多个在它前面的字符|‘fn’匹配字符n前面有任意个字符f
|+|匹配前面的字符一次或多次|‘ba+’匹配以b开头后面紧跟至少有一个a
|<字符串>|匹配包含指定字符串的文本|‘fa’
|[字符集合]|匹配字符集合中的任意一个字符|‘[xz]’匹配x或者z
|[]|匹配不在括号中的任何字符|‘[abc]’匹配任何不包含a,b,c的字符串
|字符串{n,}|匹配前面的字符串至少n次|b{2}匹配2个或更多的b
|字符串{n,m}|匹配前面的字符串至少n次,至多m次。如果n为0,此参数为可选参数|b[2,4]匹配最少2个,最多4个b

查询f_name字段以字母’y’结尾的记录
mysql> SELECT * FROM fruits WHERE f_name REGEXP 'y$';
±-----±-----±----------±--------+
| f_id | s_id | f_name | f_price |
±-----±-----±----------±--------+
| b1 | 101 | blckberry | 10.20 |
| b2 | 104 | berry | 7.60 |
| c0 | 101 | cherry | 3.20 |
| m2 | 105 | xbabay | 2.60 |
±-----±-----±----------±--------+
4 rows in set (0.00 sec)

综合案例
mysql> desc dept;
±-----------±-------------±-----±----±--------±---------------+
| Field | Type | Null | Key | Default | Extra |
±-----------±-------------±-----±----±--------±---------------+
| d_no | int(11) | NO | PRI | NULL | auto_increment |
| d_name | varchar(50) | YES | | NULL | |
| d_location | varchar(100) | YES | | NULL | |
±-----------±-------------±-----±----±--------±---------------+
3 rows in set (0.00 sec)
mysql> desc employee;
±---------±-------------±-----±----±--------±------+
| Field | Type | Null | Key | Default | Extra |
±---------±-------------±-----±----±--------±------+
| e_no | int(11) | NO | PRI | NULL | |
| e_name | varchar(100) | NO | | NULL | |
| e_gender | char(2) | NO | | NULL | |
| dept_no | int(11) | NO | MUL | NULL | |
| e_job | varchar(100) | NO | | NULL | |
| e_salary | smallint(6) | NO | | NULL | |
| hireDate | date | YES | | NULL | |
±---------±-------------±-----±----±--------±------+
7 rows in set (0.00 sec)

1.计算所有女员工f的年龄

查找出所有的女员工
mysql> desc employee;
±---------±-------------±-----±----±--------±------+
| Field | Type | Null | Key | Default | Extra |
±---------±-------------±-----±----±--------±------+
| e_no | int(11) | NO | PRI | NULL | |
| e_name | varchar(100) | NO | | NULL | |
| e_gender | char(2) | NO | | NULL | |
| dept_no | int(11) | NO | MUL | NULL | |
| e_job | varchar(100) | NO | | NULL | |
| e_salary | smallint(6) | NO | | NULL | |
| hireDate | date | YES | | NULL | |
±---------±-------------±-----±----±--------±------+
7 rows in set (0.00 sec)

使用LIMIT查询从第3条记录开始到第6条记录
mysql> desc employee;
±---------±-------------±-----±----±--------±------+
| Field | Type | Null | Key | Default | Extra |
±---------±-------------±-----±----±--------±------+
| e_no | int(11) | NO | PRI | NULL | |
| e_name | varchar(100) | NO | | NULL | |
| e_gender | char(2) | NO | | NULL | |
| dept_no | int(11) | NO | MUL | NULL | |
| e_job | varchar(100) | NO | | NULL | |
| e_salary | smallint(6) | NO | | NULL | |
| hireDate | date | YES | | NULL | |
±---------±-------------±-----±----±--------±------+
7 rows in set (0.00 sec)

查询销售人员(SALSEMAN)的最低工资
mysql> INSERT INTO employee
-> VALUES (1001,'SMITH','m',20,'CLERK',800,'2005-11-12'),
-> (1002,'ALLEN','f',30,'SALESMAN',1600,'2003-05-12'),
-> (1003,'WARD','f',30,'SALESMAN',1250,'2003-05-12'),
-> (1004,'JONES','m',20,'MANAGER',2975,'1998-05-18'),
-> (1005,'MARTIN','m',30,'SALESMAN',1250,'2001-06-12'),
-> (1006,'BLAKE','f',30,'MANAGER',2850,'1997-02-15'),
-> (1007,'CLARK','m',10,'MANAGER',2450,'2002-09-12'),
-> (1008,'SCOTT','m',20,'ANALYST',3000,'2003-05-12'),
-> (1009,'KING','f',10,'PRESIDENT',5000,'1995-01-01'),
-> (1010,'TURNER','f',30,'SALESMAN',1500,'1997-10-12'),
-> (1011,'ADAMS','m',20,'CLERK',1100,'1999-10-05'),
-> (1012,'JAMES','m',30,'CLERK',950,'2008-06-15');
Query OK, 12 rows affected (0.01 sec)
Records: 12 Duplicates: 0 Warnings: 0

mysql> SELECT MIN(e_salary) FROM employee WHERE e_job = 'SALESMAN';
+---------------+
| MIN(e_salary) |
+---------------+
| 1250 |
+---------------+
1 row in set (0.00 sec)

查询名字以字母N或者S结尾的记录
mysql> SELECT * FROM employee WHERE e_name REGEXP '[N,S]$';
±-----±-------±---------±--------±---------±---------±-----------+
| e_no | e_name | e_gender | dept_no | e_job | e_salary | hireDate |
±-----±-------±---------±--------±---------±---------±-----------+
| 1002 | ALLEN | f | 30 | SALESMAN | 1600 | 2003-05-12 |
| 1004 | JONES | m | 20 | MANAGER | 2975 | 1998-05-18 |
| 1005 | MARTIN | m | 30 | SALESMAN | 1250 | 2001-06-12 |
| 1011 | ADAMS | m | 20 | CLERK | 1100 | 1999-10-05 |
| 1012 | JAMES | m | 30 | CLERK | 950 | 2008-06-15 |
±-----±-------±---------±--------±---------±---------±-----------+
5 rows in set (0.00 sec)

查询在BeiJing工作的员工的姓名和职务

mysql> SELECT e_name,e_job FROM employee WHERE dept_no IN (SELECT d_no FROM dept WHERE d_location = 'BeiJing');
+--------+---------+
| e_name | e_job |
+--------+---------+
| SMITH | CLERK |
| JONES | MANAGER |
| SCOTT | ANALYST |
| ADAMS | CLERK |
+--------+---------+
4 rows in set (0.00 sec)

使用左连接方式查询employee表和dept表
mysql> SELECT * FROM employee LEFT OUTER JOIN dept ON dept.d_no = employee.dept_no;
±-----±-------±---------±--------±----------±---------±-----------±-----±-----------±-----------+
| e_no | e_name | e_gender | dept_no | e_job | e_salary | hireDate | d_no | d_name | d_location |
±-----±-------±---------±--------±----------±---------±-----------±-----±-----------±-----------+
| 1007 | CLARK | m | 10 | MANAGER | 2450 | 2002-09-12 | 10 | ACCOUNTING | ShangHai |
| 1009 | KING | f | 10 | PRESIDENT | 5000 | 1995-01-01 | 10 | ACCOUNTING | ShangHai |
| 1001 | SMITH | m | 20 | CLERK | 800 | 2005-11-12 | 20 | RESEARCH | BeiJing |
| 1004 | JONES | m | 20 | MANAGER | 2975 | 1998-05-18 | 20 | RESEARCH | BeiJing |
| 1008 | SCOTT | m | 20 | ANALYST | 3000 | 2003-05-12 | 20 | RESEARCH | BeiJing |
| 1011 | ADAMS | m | 20 | CLERK | 1100 | 1999-10-05 | 20 | RESEARCH | BeiJing |
| 1002 | ALLEN | f | 30 | SALESMAN | 1600 | 2003-05-12 | 30 | SALES | ShenZhen |
| 1003 | WARD | f | 30 | SALESMAN | 1250 | 2003-05-12 | 30 | SALES | ShenZhen |
| 1005 | MARTIN | m | 30 | SALESMAN | 1250 | 2001-06-12 | 30 | SALES | ShenZhen |
| 1006 | BLAKE | f | 30 | MANAGER | 2850 | 1997-02-15 | 30 | SALES | ShenZhen |
| 1010 | TURNER | f | 30 | SALESMAN | 1500 | 1997-10-12 | 30 | SALES | ShenZhen |
| 1012 | JAMES | m | 30 | CLERK | 950 | 2008-06-15 | 30 | SALES | ShenZhen |
±-----±-------±---------±--------±----------±---------±-----------±-----±-----------±-----------+
12 rows in set (0.00 sec)

查询所有2001-2005年入职的员工的信息,查询部门编号为20和30的员工信息并使用UNION合并两个查询结果
mysql> SELECT * FROM employee WHERE YEAR(hireDate) BETWEEN '2001' and '2005' UNION ALL SELECT * FROM employee WHERE dept_no IN (20,30) ;
±-----±-------±---------±--------±---------±---------±-----------+
| e_no | e_name | e_gender | dept_no | e_job | e_salary | hireDate |
±-----±-------±---------±--------±---------±---------±-----------+
| 1001 | SMITH | m | 20 | CLERK | 800 | 2005-11-12 |
| 1002 | ALLEN | f | 30 | SALESMAN | 1600 | 2003-05-12 |
| 1003 | WARD | f | 30 | SALESMAN | 1250 | 2003-05-12 |
| 1005 | MARTIN | m | 30 | SALESMAN | 1250 | 2001-06-12 |
| 1007 | CLARK | m | 10 | MANAGER | 2450 | 2002-09-12 |
| 1008 | SCOTT | m | 20 | ANALYST | 3000 | 2003-05-12 |
| 1001 | SMITH | m | 20 | CLERK | 800 | 2005-11-12 |
| 1002 | ALLEN | f | 30 | SALESMAN | 1600 | 2003-05-12 |
| 1003 | WARD | f | 30 | SALESMAN | 1250 | 2003-05-12 |
| 1004 | JONES | m | 20 | MANAGER | 2975 | 1998-05-18 |
| 1005 | MARTIN | m | 30 | SALESMAN | 1250 | 2001-06-12 |
| 1006 | BLAKE | f | 30 | MANAGER | 2850 | 1997-02-15 |
| 1008 | SCOTT | m | 20 | ANALYST | 3000 | 2003-05-12 |
| 1010 | TURNER | f | 30 | SALESMAN | 1500 | 1997-10-12 |
| 1011 | ADAMS | m | 20 | CLERK | 1100 | 1999-10-05 |
| 1012 | JAMES | m | 30 | CLERK | 950 | 2008-06-15 |
±-----±-------±---------±--------±---------±---------±-----------+

使用LIKE 查询员工姓名中包含字母a的记录
mysql> SELECT * FROM employee WHERE e_name LIKE '%a%';
±-----±-------±---------±--------±---------±---------±-----------+
| e_no | e_name | e_gender | dept_no | e_job | e_salary | hireDate |
±-----±-------±---------±--------±---------±---------±-----------+
| 1002 | ALLEN | f | 30 | SALESMAN | 1600 | 2003-05-12 |
| 1003 | WARD | f | 30 | SALESMAN | 1250 | 2003-05-12 |
| 1005 | MARTIN | m | 30 | SALESMAN | 1250 | 2001-06-12 |
| 1006 | BLAKE | f | 30 | MANAGER | 2850 | 1997-02-15 |
| 1007 | CLARK | m | 10 | MANAGER | 2450 | 2002-09-12 |
| 1011 | ADAMS | m | 20 | CLERK | 1100 | 1999-10-05 |
| 1012 | JAMES | m | 30 | CLERK | 950 | 2008-06-15 |
±-----±-------±---------±--------±---------±---------±-----------+

使用REGEXP查询员工姓名中包含T、C或者M3个字母中任意一个的记录
mysql> SELECT e_name FROM employee WHERE e_name REGEXP '[TCM]' ;
±-------+
| e_name |
±-------+
| SMITH |
| MARTIN |
| CLARK |
| SCOTT |
| TURNER |
| ADAMS |
| JAMES |
±-------+
7 rows in set (0.00 sec)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章