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

MySQL入门-4:检索数据

2014-06-04 10:44 232 查看
大纲
1、SELECT语句
2、检索数据
3、排除重复的行
4、LIMIT限制显示结果
5、ORDER BY排序数据

一、DQL : SELECT 语句

我们最最经常用的SQL语句大概就是SELECT,它的作用是从一个或多个表中检索数据。为了使用SELECT检索表数据,必须至少给出两条信息 -- 想选择什么(指定列),以及从什么地方选择(指定表)。

二、检索语句

a、检索单个列
需要检索的列名放到SELECT关键字后面,FROM关键字指出从哪个表中检索数据。
mysql> SELECT prod_name
-> FROM products;

select 5  from  products;  -- ok , 输出的行数是products所有的行,只有一个字段,值都是 5

select 5;        -- 和具体实现相关
select 5 * 5;    -- 和具体实现相关
通常,展示数据遵循以下原则: “字符串”是左对齐的,而“数值”是右对齐的。
b、检索多个列
必须在SELECT关键字后给出多个列名,列名之间必须以逗号分隔,但是最后一个列名的后面绝不能添加。如果在最后一个列名后面加了逗号,将出现错误。
mysql> SELECT prod_id, prod_name, prod_price
-> FROM products;
c、检索所有列
SELECT语句可以检索所有的列而不必逐个列出它们,使用*通配符。
mysql> SELECT *
-> FROM products;
列的顺序一般是表定义中出现的顺序。但有时侯并不是这样,比如表结构发生变化(添加或删除列),可能导致顺序的变化。除非确实需要表中的每个列,否则最好不要使用*通配符,这会降低检索和应用程序的性能。使用通配符的最大的好处在于,可以检索出名字未知的列。
在交互执行的特定查询中, 使用SELECT * 更容易些。然而,在写程序代码的时候,最好是分别指定每一列。它们的性能相同,但是显示的指定列后,就可以很清楚查询中究竟返回了哪些列。

未排序的数据:
如果在查询中没有明确排序查询结果,则返回的数据顺序没有特殊意义。返回数据的顺序可能是数据被添加到表中的顺序,也可能不是。因为经过更新和删除操作,顺序将会受到MySQL重用回收存储空间的影响。如果不明确控制的话,不能(也不应该)依赖该顺序。二维表从理论上来说是一个集合(set),集合并没有顺序之说。
结束SQL语句:
多条SQL语句必须以分号(;)分隔。而且分号必须是英文的,这里需要注意。
SQL语句和大小写:
SQL
语句是不区分大小写的,因此SELECT与select是完全相同的。但是,一定要认识到虽然SQL语句关键字是不区分大小写的,但有些标识符(如数据库
名、表名、列名)可能不同(如windows平台,Linux平台)。最佳方式是按照大小写的惯例,且使用时保持一致。

三、DISTINCT 排除重复的行

如果只想知道有多少不同的行,不希望重复的行出现,怎么办?解决办法是使用DISTINCT关键字,它指示MySQL只返回不同的值。如果使用DISTINCT关键字,它必须直接放在列名的前面。DISTINCT关键字应用于其后所有的列,而不仅仅是紧随其后的单个列。也就是说不能部分使用DISTINCT。 SELECT DISTINCT prod_id, prod_price,那么将同时应用于prod_id和prod_price两列的组合。DISTINCT会把其后的字段组合进行过滤(可以这样理解:SELECT语句产生的输出是二维表不可能一列返回10行,而另一列只返回1行,你想想会是什么效果。也就是说必须遵循:各个列返回的行数必须一致)
想想一种情况,distinct作用于 null 值得列,是什么效果呢? distinct 可以过滤掉重复的NULL, 对于多行NULL,最终会返回一个NULL行。

mysql> SELECT DISTINCT vend_id
-> FROM products;

SELECT distinct ename, deptno from emp;   -- ok
SELECT ename, distinct deptno from emp;   -- error


四、限制返回的行数(分页查询)

MySQL, PostgreSQL
为了显示特定的行或者前几行,可以使用 LIMIT子句 。
mysql> SELECT prod_name
-> FROM products
-> LIMIT 0,5;
指定检索的开始行和行数。第一个数为开始位置OFFSET,第二个数为需要检索的行数line-numbers。检索出来的行数从0开始编号,第一行的行号为0。使用LIMIT,对我们编写分页显示时非常有帮助。
The
LIMIT clause can be used to constrain the number of rows returned by the SELECT
statement. LIMIT takes one or two numeric arguments, which must both be
nonnegative integer constants (except when using prepared statements).
With
two arguments, the first argument specifies the offset of the first row to
return, and the second specifies the maximum number of rows to return. The
offset of the initial row is 0 (not 1):
SELECT *
FROM tbl
LIMIT 5,10;     # Retrieve rows 6-15

With
one argument, the value specifies the number of rows to return from the
beginning of the result set:
SELECT *
FROM tbl
LIMIT 5;         # Retrieve first 5 rows
In other words, LIMIT row_count is equivalent to LIMIT 0, row_count.
LIMIT 5: 指示 mysql返回不多余5行。好好理解这句话,当表中行数不够时,假设只有3行,那么仅能返回它能够返回的3行数据而已。

Oracle
可以使用 ROWNUM 来限制行数。

SELECT *
FROM emp
WHERE rownum <= 5;
Oracle 伪列:
在集合论中,是没有顺序之说的。但是Oracle提供了 rowid, rownum。

Rowid 与 Rownum 虽都被称为伪列,但它们的存在方式是不一样的,rowid 可以说是物理存在的(指针,该记录在物理文件中的位置),表示记录在表空间中的唯一位置 ID,在DB中唯一。只要记录没被搬动过,rowid是不变的。 rowid 相对于表来说又像表中的一般列,所以以 rowid 为条件就不会有 rownum那些情况发生。 rownum不能以任何基表的名称作为前缀。
对于rownum来说它是oracle系统顺序分配为从查询返回的行的编号,返回的第一行分配的是1,第二行是2,依此类推,这个伪字段可以用于限制查询返回的总行数,而且rownum不能以任何表的名称作为前缀。

书上告诫,不能对 rownum用 ">",这也就意味着,如果你想用
select * from emp where rownum > 5
则是失败的。要知道为什么会失败,则需要了解rownum背后的机制:
1 Oracle executes your query.2 Oracle fetches the first row and calls it row number 1.3 Have we gotten past row number meets the criteria? If no, then Oracle discards the row, If yes, then Oracle return the row.4 Oracle fetches the next row and advances the row number (to 2, and then to 3, and then to 4, and so forth).5 Go to step 3.了解了原理,就知道rownum>不会成功,因为在第三步的时候查询出的行已经被丢弃,第四步查出来的rownum仍然是1,这样永远也不会成功。同样道理,rownum如果单独用=,也只有在rownum=1时才有用。

SQL Server

使用 TOP 关键字,来限制返回的行数。

SELECT TOP 5 *
FROM  emp;


五、查询结果排序

其实,检索出的数据并不是以纯粹的随机顺序显示的。如果不排序,数据一般将以它在底层表中出现的顺序显示。这可以是数据最初添加到表中的顺序。但是如果数据后来进行过更新或删除,则此顺序将会受到MySQL重用回收存储空间的影响。因此,如果不明确控制的话,不能(也不应该)依赖该排序顺序。关系数据库设计理论认为,如果不明确规定排序顺序,则不应该假定检索出的数据的顺序有意义。(因为表是一个数据集合,而集合是没有顺序的)
为了明确的排序,可使用ORDER BY子句。ORDER BY子句选取一个或多个列,然后据此对输出进行排序。如果某列的值相同时,我们期望根据另一列进行排序,我们只需指定多个列名,列名之间用逗号分开即可。
不一定要指定排序所基于的列名,也可以给出表示这列的编号。这个编号从1开始,从左到右依次对应 SELECT 列表中的各项目。
mysql> SELECT prod_id, prod_price, prod_name
-> FROM products
-> ORDER BY prod_price, prod_name DESC;
ORDER BY 子句可以指定一个或多个列。用非检索的列进行排序是完全合法的(只要该列存在于表中)。
重要的是理解在按多个列进行排序时,排序完全按所规定的顺序进行,指定列的先后顺序(优先次序是从左到右)进行。如上述例子中,仅当多行具有相同的prod_price值时,才会对prod_name进行排序。如果prod_price列中的所有的值都是唯一的,则不会按prod_name排序。
按字串排序:按照 列值 的某一部分对查询结果进行排序。可以使用 substr() 等函数。
指定排序方向:升序(ASC), 降序(DESC), ASC,DESC关键字只应用到直接位于其前面的列名(紧邻)。如果想在多个列上进行降序排序,必须对每个列指定 DESC/ASC关键字。

区分大小写和排序顺序:
在对文本数据排序时,A和a相同吗?这个问题取决于数据库如何设置[字符集校对], 以及字符集。在字典排序顺序中,A被视为与a相同,这是MySQL和大多数DBMS的默认行为。

ORDER BY子句的位置:要用好SELECT,理解SQL执行顺序非常重要。
在给出ORDER BY子句时,应该保证它位于FROM子句之后,如果使用LIMIT,它必须位于ORDER BY之后。使用子句的次序不对将产生错误。

六、在SELECT语句中使用条件逻辑

要在 SELECT 语句中,对数值执行 IF-ELSE 操作。比如:工资<=2000,返回“under”;如果工资>=4000,返回“over”;如果这两者之间,返回“ok”
解决方案:使用CASE表达式直接在SELECT语句中执行条件逻辑

mysql> SELECT ename, sal,
case when sal <= 2000 then 'under'
when sal >= 4000 then 'over'
else 'ok'  -- 如果没有else ,对于不满足条件的,返回NULL
end AS status   -- 别名 status
FROM emp;

+--------+------+--------+
| ename  | sal  | status |
+--------+------+--------+
| SMITH  |  800 | under  |
| ALLEN  | 1600 | under  |
| WARD   | 1250 | under  |
| JONES  | 2975 | ok     |
| MARTIN | 1250 | under  |
| BLAKE  | 2850 | ok     |
| CLARK  | 2450 | ok     |
| SCOTT  | 3000 | ok     |
| KING   | 5000 | over   |
| TURNER | 1500 | under  |
| ADAMS  | 1100 | under  |
| JAMES  |  950 | under  |
| FORD   | 3000 | ok     |
| MILLER | 1300 | under  |
+--------+------+--------+
14 rows in set (0.00 sec)

七、连接列值

要将多列值组合为一列返回,可以进行连接操作。
对于DB2, Oracle, PostgreSQL
使用 | | 作为连接操作符。

对于 MySQL
使用 CONCAT() 函数进行连接。

对于SQL Server
使用 + 作为连接操作符。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  SELECT 数据检索