【MySQL】SELECT语句 - 查询数据
第4章 检索数据
简单记录 - MySQL必知必会 - [英]Ben Forta
如何使用SELECT语句从表中检索一个或多个数据列。
检索、查询数据
1、SELECT语句
SQL语句是由简单的英语单词构成的。这些单词称为关键字,每个SQL语句都是由一个或多个关键字构成的。
应该最经常使用的SQL语句就是SELECT语句了。
SELECT语句用途是从一个或多个表中检索信息。
为了使用SELECT检索表数据,必须至少给出两条信息——想选择什么,以及从什么地方选择。
检索表数据,使用SELECT语句,使用SELECT至少要知道想选择什么数据,从哪里来选这数据。
SELECT ... FROM ...
2、检索单个列
使用简单的SQL SELECT语句开始来检索数据吧,
我们要检索表中的单个列的所有数据怎么办?
例子, 输入:SELECT prod_name FROM products;
输出如下所示:
mysql> SELECT prod_name FROM products;
+----------------+
| prod_name |
+----------------+
| .5 ton anvil |
| 1 ton anvil |
| 2 ton anvil |
| Detonator |
| Bird seed |
| Carrots |
| Fuses |
| JetPack 1000 |
| JetPack 2000 |
| Oil can |
| Safe |
| Sling |
| TNT (1 stick) |
| TNT (5 sticks) |
+----------------+
14 rows in set (0.00 sec)
分析:
SELECT prod_name FROM products;
语句利用SELECT语句从products表中检索一个名叫prod_name的列。平常我们要检索单个列的时候,可以用这个语句SELECT ...FROM ...
, 所需的列名在SELECT关键字之后给出,FROM关键字后面是要检索数据的表名。
注意:简单SELECT语句将返回表中所有行,但数据没有过滤(过滤将得出结果集的一个子集),也没有排序。
注意,SQL语句不区分大小写,因此SELECT与select是相同的。同样,写成SeLect也没有关系。但一般是所有SQL关键字使用大写,而对所有列和表名使用小写,这样做使代码更易于阅读和调试。
3、检索多个列
要想从一个表中检索多个列,还是使用SELECT语句。唯一的不同是必须在SELECT关键字后给出多个列名,列名之间必须以逗号分隔。
例子:SELECT prod_id,prod_name,prod_price FROM products;
mysql> SELECT prod_id,prod_name,prod_price FROM products;
+---------+----------------+------------+
| prod_id | prod_name | prod_price |
+---------+----------------+------------+
| ANV01 | .5 ton anvil | 5.99 |
| ANV02 | 1 ton anvil | 9.99 |
| ANV03 | 2 ton anvil | 14.99 |
| DTNTR | Detonator | 13.00 |
| FB | Bird seed | 10.00 |
| FC | Carrots | 2.50 |
| FU1 | Fuses | 3.42 |
| JP1000 | JetPack 1000 | 35.00 |
| JP2000 | JetPack 2000 | 55.00 |
| OL1 | Oil can | 8.99 |
| SAFE | Safe | 50.00 |
| SLING | Sling | 4.49 |
| TNT1 | TNT (1 stick) | 2.50 |
| TNT2 | TNT (5 sticks) | 10.00 |
+---------+----------------+------------+
14 rows in set (0.00 sec)
分析:
这条语句使用SELECT语句从表products中选择数据。在这个例子中,指定了3个列名prod_id,prod_name,prod_price,列名之间用逗号分隔。
说明 数据表示: 从上述输出可以看到,SQL语句一般返回原始的、无格式的数据。一般在显示在应用程序的数据是格式化了的,很少使用实际检索出的原始数据。
在选择多个列时,一定要在列名之间加上逗号,但最后一个列名后不加。如果在最后一个列名后加了逗号,将出现错误。
例如:SELECT prod_id,prod_name,prod_price, FROM products;
mysql> SELECT prod_id,prod_name,prod_price, FROM products;
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 'FROM products' at line 1
mysql>
4、检索所有列
除了指定所需的列外(一个或多个列), SELECT语句还可以检索所有的列而不必逐个列出它们。这可以通过在实际列名的位置使用星号(*)通配符来达到,如下所示:
SELECT * FROM products;
mysql> SELECT * FROM products;
+---------+---------+----------------+------------+----------------------------------------------------------------+
| prod_id | vend_id | prod_name | prod_price | prod_desc |
+---------+---------+----------------+------------+----------------------------------------------------------------+
| ANV01 | 1001 | .5 ton anvil | 5.99 | .5 ton anvil, black, complete with handy hook |
| ANV02 | 1001 | 1 ton anvil | 9.99 | 1 ton anvil, black, complete with handy hook and carrying case |
| ANV03 | 1001 | 2 ton anvil | 14.99 | 2 ton anvil, black, complete with handy hook and carrying case |
| DTNTR | 1003 | Detonator | 13.00 | Detonator (plunger powered), fuses not included |
| FB | 1003 | Bird seed | 10.00 | Large bag (suitable for road runners) |
| FC | 1003 | Carrots | 2.50 | Carrots (rabbit hunting season only) |
| FU1 | 1002 | Fuses | 3.42 | 1 dozen, extra long |
| JP1000 | 1005 | JetPack 1000 | 35.00 | JetPack 1000, intended for single use |
| JP2000 | 1005 | JetPack 2000 | 55.00 | JetPack 2000, multi-use |
| OL1 | 1002 | Oil can | 8.99 | Oil can, red |
| SAFE | 1003 | Safe | 50.00 | Safe with combination lock |
| SLING | 1003 | Sling | 4.49 | Sling, one size fits all |
| TNT1 | 1003 | TNT (1 stick) | 2.50 | TNT, red, single stick |
| TNT2 | 1003 | TNT (5 sticks) | 10.00 | TNT, red, pack of 10 sticks |
+---------+---------+----------------+------------+----------------------------------------------------------------+
14 rows in set (0.00 sec)
分析:如果给定一个通配符(*),则返回表中所有列。列的顺序一般是列在表定义中出现的顺序。但有时候并不是这样的,表的模式的变化(如添加或删除列)可能会导致顺序的变化。
注意:使用通配符 一般,除非确实需要表中的每个列,否则最好别使用*通配符。虽然使用通配符可能会使你自己省事,不用明确列出所需列,但检索不需要的列通常会降低检索和应用程序的性能。
提示:检索未知列 使用通配符有一个大优点。由于不明确指定列名(因为星号检索每个列),所以能检索出名字未知的列。
5、检索不同的行
SELECT能返回所有匹配的行。但是,如果不想要每个值每次都出现(重复的数出现一次就好了),怎么办?
例如,想知道products表中产品的所有供应商ID:
SELECT vend_id FROM products;
mysql> SELECT vend_id FROM products;
+---------+
| vend_id |
+---------+
| 1001 |
| 1001 |
| 1001 |
| 1002 |
| 1002 |
| 1003 |
| 1003 |
| 1003 |
| 1003 |
| 1003 |
| 1003 |
| 1003 |
| 1005 |
| 1005 |
+---------+
14 rows in set (0.00 sec)
SELECT语句返回14行(但表中只有4个供应商),products表中列出了14个产品。
那么,如何检索出有不同值的列表呢?解决办法是使用DISTINCT关键字,顾名思义,此关键字指示MySQL只返回不同的值。distinct
SELECT DISTINCT vend_id FROM products;
mysql> SELECT DISTINCT vend_id FROM products;
+---------+
| vend_id |
+---------+
| 1001 |
| 1002 |
| 1003 |
| 1005 |
+---------+
4 rows in set (0.00 sec)
mysql>
分析:
SELECT DISTINCT vend_id告诉MySQL只返回不同(唯一)的vend_id行,因此只返回4行。如果使用DISTINCT关键字,它必须直接放在列名的前面。
DISTINCT vend_id, prod_price
作用两个 看这个两列,两列的组合重复就过滤掉。
mysql> SELECT vend_id, prod_price FROM products;
+---------+------------+
| vend_id | prod_price |
+---------+------------+
| 1001 | 5.99 |
| 1001 | 9.99 |
| 1001 | 14.99 |
| 1003 | 13.00 |
| 1003 | 10.00 |
| 1003 | 2.50 |
| 1002 | 3.42 |
| 1005 | 35.00 |
| 1005 | 55.00 |
| 1002 | 8.99 |
| 1003 | 50.00 |
| 1003 | 4.49 |
| 1003 | 2.50 |
| 1003 | 10.00 |
+---------+------------+
14 rows in set (0.00 sec)
SELECT DISTINCT vend_id, prod_price
看vend_id, prod_price列的组合有没有重复的,有的话就过滤。
mysql> SELECT DISTINCT vend_id, prod_price FROM products;
+---------+------------+
| vend_id | prod_price |
+---------+------------+
| 1001 | 5.99 |
| 1001 | 9.99 |
| 1001 | 14.99 |
| 1003 | 13.00 |
| 1003 | 10.00 |
| 1003 | 2.50 |
| 1002 | 3.42 |
| 1005 | 35.00 |
| 1005 | 55.00 |
| 1002 | 8.99 |
| 1003 | 50.00 |
| 1003 | 4.49 |
+---------+------------+
12 rows in set (0.00 sec)
6、限制结果
SELECT语句返回所有匹配的行,它们可能是指定表中的每个行。
但有时我们需要返回第一行或前几行,怎么办呢?
可使用LIMIT子句。
例子: 返回prod_name的前5行 SELECT prod_name FROM products LIMIT 5;
mysql> SELECT prod_name FROM products LIMIT 5;
+--------------+
| prod_name |
+--------------+
| .5 ton anvil |
| 1 ton anvil |
| 2 ton anvil |
| Detonator |
| Bird seed |
+--------------+
5 rows in set (0.00 sec)
mysql>
分析:
此语句使用SELECT语句检索单个列。LIMIT 5指示MySQL返回不多于5行。
我想要得到下一个5行,怎么做呢?
为得出下一个5行,可指定要检索的开始行和行数,
如下所示:SELECT prod_name FROM products LIMIT 5,5;
mysql> SELECT prod_name FROM products LIMIT 5,5;
+--------------+
| prod_name |
+--------------+
| Carrots |
| Fuses |
| JetPack 1000 |
| JetPack 2000 |
| Oil can |
+--------------+
5 rows in set (0.00 sec)
mysql>
LIMIT 5, 5指示MySQL返回从行5开始的5行。第一个数为开始位置,第二个数为要检索的行数。
所以,带一个值的LIMIT总是从第一行开始,给出的数为返回的行数。带两个值的LIMIT可以指定从行号为第一个值的位置开始。(带两个值的LIMIT,相对某行开始返回)
注意:行0 检索出来的第一行为行0而不是行1。因此,LIMIT 1, 1将检索出第二行而不是第一行。
mysql> SELECT prod_name FROM products LIMIT 1,1;
+-------------+
| prod_name |
+-------------+
| 1 ton anvil |
+-------------+
1 row in set (0.00 sec)
mysql> SELECT prod_name FROM products LIMIT 0,5;
+--------------+
| prod_name |
+--------------+
| .5 ton anvil |
| 1 ton anvil |
| 2 ton anvil |
| Detonator |
| Bird seed |
+--------------+
5 rows in set (0.00 sec)
mysql>
说明;在行数不够时 ,当LIMIT中指定要检索的行数为检索的最大行数,如果没有足够的行, MySQL将只返回它能返回的那么多行。(例如,给出LIMIT 10, 5,但只有0-13行,返回10 、11、12、13 四行)
mysql> SELECT prod_name FROM products LIMIT 10,5;
+----------------+
| prod_name |
+----------------+
| Safe |
| Sling |
| TNT (1 stick) |
| TNT (5 sticks) |
+----------------+
4 rows in set (0.00 sec)
mysql>
提示:MySQL 5的LIMIT语法 LIMIT 3, 4的含义是从行4开始的3行还是从行3开始的4行?如前所述,它的意思是从行3开始的4行,这容易把人搞糊涂。由于这个原因,MySQL 5支持LIMIT的另一种替代语法。LIMIT 4 OFFSET 3意为从行3开始取4行,就像LIMIT 3, 4一样。从行3开始的4行 3,4,5,6,
mysql> SELECT prod_name FROM products LIMIT 4 OFFSET 3;
+-----------+
| prod_name |
+-----------+
| Detonator |
| Bird seed |
| Carrots |
| Fuses |
+-----------+
4 rows in set (0.00 sec)
mysql> SELECT prod_name FROM products LIMIT 3,4;
+-----------+
| prod_name |
+-----------+
| Detonator |
| Bird seed |
| Carrots |
| Fuses |
+-----------+
4 rows in set (0.00 sec)
LIMIT 4 OFFSET 3意为从行3开始取4行,就像LIMIT 3, 4一样。
7、使用完全限定的表名
之前的SQL例子只通过列名引用列,可以使用完全限定的名字来引用列(同时使用表名和列字)。
例子:SELECT products.prod_name FROM products;
mysql> SELECT products.prod_name FROM products;
+----------------+
| prod_name |
+----------------+
| .5 ton anvil |
| 1 ton anvil |
| 2 ton anvil |
| Detonator |
| Bird seed |
| Carrots |
| Fuses |
| JetPack 1000 |
| JetPack 2000 |
| Oil can |
| Safe |
| Sling |
| TNT (1 stick) |
| TNT (5 sticks) |
+----------------+
14 rows in set (0.00 sec)
mysql>
这条SQL语句在功能上等于SELECT prod_name FROM products;
语句,
mysql> SELECT prod_name FROM products;
+----------------+
| prod_name |
+----------------+
| .5 ton anvil |
| 1 ton anvil |
| 2 ton anvil |
| Detonator |
| Bird seed |
| Carrots |
| Fuses |
| JetPack 1000 |
| JetPack 2000 |
| Oil can |
| Safe |
| Sling |
| TNT (1 stick) |
| TNT (5 sticks) |
+----------------+
14 rows in set (0.00 sec)
但这里指定了一个完全限定的列名。表名也可以是完全限定的,如下所示:
SELECT products.prod_name FROM mysqlcrashcourse.products;
mysql> SELECT products.prod_name FROM mysqlcrashcourse.products;
+----------------+
| prod_name |
+----------------+
| .5 ton anvil |
| 1 ton anvil |
| 2 ton anvil |
| Detonator |
| Bird seed |
| Carrots |
| Fuses |
| JetPack 1000 |
| JetPack 2000 |
| Oil can |
| Safe |
| Sling |
| TNT (1 stick) |
| TNT (5 sticks) |
+----------------+
14 rows in set (0.00 sec)
mysql>
这条语句在功能上也等于SELECT products.prod_name FROM products;
语句(products表必须位于mysqlcrashcourse数据库中)。在有一些情形需要完全限定名,就会用到这个语法,需注意,以便在遇到时知道它的作用。
8、小结
学习了如何使用SQL的SELECT语句来检索单个表列、多个表列以及所有表列。
SELECT语句用途是从一个或多个表中检索信息。使用SELECT检索表数据,必须至少给出两条信息——想选择什么,以及从什么地方选择。 SELECT ... FROM ...
单个列,例如SELECT prod_name FROM products;
多个列,例如SELECT prod_id,prod_name,prod_price FROM products;
检索所有列,例如SELECT * FROM products;
不重复的列,例如SELECT DISTINCT vend_id FROM products;
返回前几行,例如 SELECT prod_name FROM products LIMIT 5;
SELECT prod_name FROM products LIMIT 3,4;
等于 SELECT prod_name FROM products LIMIT 4 OFFSET 3;
从0行开始算的,返回 3、4、5、6四行。
完全限定的名字来引用列、表,例如SELECT products.prod_name FROM mysqlcrashcourse.products;
搞定,复习排序检索数据去了。