Author: Allen
微信公众号:疾风java
数据库是一个以某种有组织的方式存储的数据集合。理解数据库的一种最简单的办法是将其想象为一个文件柜。此文件柜是一个存放数据的物理位置,不管数据是什么以及如何组织的。
在你将资料放入自己的文件柜时,并不是随便将它们扔进某个抽屉就完事了,而是在文件柜中创建文件,然后将相关的资料放入特定的文件中。在数据库领域中,这种文件称为表。表是一种结构化的文件,可用来存储某种特定类型的数据。表可以保存顾客清单、产品目录,或者其他信息清单。
表由列组成。列中存储着表中某部分的信息。列(column) 表中的一个字段。所有表都是由一个或多个列组成的。理解列的最好办法是将数据库表想象为一个网格。网格中每一列存储着一条特定的信息。例如,在顾客表中,一个列存储着顾客编号,另一个列存储着顾客名,而地址、城市、州以及邮政编码全都存储在各自
的列中。
表中的数据是按行存储的,所保存的每个记录存储在自己的行内。如果将表想象为网格,网格中垂直的列为表列,水平行为表行。
表中每一行都应该有可以唯一标识自己的一列(或一组列)。一个顾客表可以使用顾客编号列,而订单表可以使用订单ID,雇员表可以使用雇员ID或雇员社会保险号。
SQL(发音为字母S-Q-L或sequel)是结构化查询语言(Structured Query Language)的缩写。SQL是一种专门用来与数据库通信的语言。
正如第1章所述,SQL语句是由简单的英语单词构成的。这些单词称为关键字,每个SQL语句都是由一个或多个关键字构成的。大概,最经常
使用的SQL语句就是SELECT语句了。它的用途是从一个或多个表中检索信息。为了使用SELECT检索表数据,必须至少给出两条信息——想选择什
么,以及从什么地方选择。
我们将从简单的SQL SELECT语句开始介绍,此语句如下所示:
SELECT name FROM students;
上述语句利用SELECT语句从students表中检索一个名为name的列。所需的列名在SELECT关键字之后给出,FROM关键字指出从其中检索数据的表名。
要想从一个表中检索多个列,使用相同的SELECT语句。唯一的不同是必须在SELECT关键字后给出多个列名,列名之间必须以逗号分隔。
当心逗号 在选择多个列时,一定要在列名之间加上逗号,但最后一个列名后不加。如果在最后一个列名后加了逗号,将出现错误。
下面的SELECT语句从products表中选择3列:
SELECT id,name,age FROM students;
与前一个例子一样,这条语句使用SELECT语句从表students中选择数据。在这个例子中,指定了3个列名,列名之间用逗号分隔。
除了指定所需的列外(如上所述,一个或多个列),SELECT语句还可以检索所有的列而不必逐个列出它们。这可以通过在实际列名的位置使用星号(*)通配符来达到,如下所示:
SELECT * FROM students;
如果给定一个通配符(*),则返回表中所有列。列的顺序一般是列在表定义中出现的顺序。但有时候并不是这样的,表的模式的变化(如添加或删除列)可能会导致顺序的变化。
正如所见,SELECT返回所有匹配的行。但是,如果你不想要每个值每次都出现,怎么办?例如,假如你想得出students表中的所有学生年龄,解决办法是使用DISTINCT关键字,顾名思义,此关键字指示MySQL只返回不同的值。
SELECT DISTINCT age FROM students;
SELECT语句返回所有匹配的行,它们可能是指定表中的每个行。为了返回第一行或前几行,可使用LIMIT子句。下面举一个例子:
SELECT * FROM student LIMIT 5;
此语句使用SELECT语句检索单个列。LIMIT 5指示MySQL返回不多于5行。为得出下一个5行,可指定要检索的开始行和行数,如下所示:
SELECT * FROM student LIMIT 5,5;
LIMIT 5, 5指示MySQL返回从行5开始的5行。第一个数为开始位置,第二个数为要检索的行数。所以,带一个值的LIMIT总是从第一行开始,给出的数为返回的行数。带两个值的LIMIT可以指定从行号为第一个值的位置开始。
迄今为止使用的SQL例子只通过列名引用列。也可能会使用完全限定的名字来引用列(同时使用表名和列字)。请看以下例子:
SELECT students.name FROM students;
排序检索数据
本章将讲授如何使用SELECT语句的ORDER BY子句,根据需要排序检索出的数据。
正如前一章所述,下面的SQL语句返回某个数据库表的单个列。但请看其输出,并没有特定的顺序。其实,检索出的数据并不是以纯粹的随机顺序显示的。如果不排序,数据一般将以它在底层表中出现的顺序显示。这可以是数据最初添加到表中的顺序。但是,如果数据后来进行过更新或删除,则此顺序将会受到MySQL重用回收存储空间的影响。因此,如果不明确控制的话,不能(也不应该)依赖该排序顺序。关系数据库设计理论认为,如果不明确规定排序顺序,则不应该假定检索出的数据的顺序有意义。
为了明确地排序用SELECT语句检索出的数据,可使用ORDER BY子句。ORDER BY子句取一个或多个列的名字,据此对输出进行排序。请看下面的例子:
SELECT name FROM students ORDER BY id;
经常需要按不止一个列进行数据排序。例如,如果要显示雇员清单,可能希望按姓和名排序(首先按姓排序,然后在每个姓中再按名排序)。如果多个雇员具有相同的姓,这样做很有用。为了按多个列排序,只要指定列名,列名之间用逗号分开即可(就像选择多个列时所做的那样)。
SELECT id,name,age FROM students ORDER BY id,name;
下面的代码检索3个列,并按其中两个列对结果进行排序——首先按id,然后再按姓名排序。
数据排序不限于升序排序(从A到Z)。这只是默认的排序顺序,还可以使用ORDER BY子句以降序(从Z到A)顺序排序。为了进行降序排序,必须指定DESC关键字。
下面的例子按年龄以降序排序产品(最大的排在最前面):
SELECT id,name,age FROM students ORDER BY age DESC,id;
DESC关键字只应用到直接位于其前面的列名。在上例中,只对age列指定DESC,对id列不指定。因此,age列以降序排序,而id列仍然按标准的升序排序。
在多个列上降序排序 如果想在多个列上进行降序排序,必须对每个列指定DESC关键字。与DESC相反的关键字是ASC(ASCENDING),在升序排序时可以指定它。但实际上,ASC没有多大用处,因为升序是默认的(如果既不指定ASC也不指定DESC,则假定为ASC)。
区分大小写和排序顺序 在对文本性的数据进行排序时,A与 a相同吗?a位于B之前还是位于Z之后?这些问题不是理论问题,其答案取决于数据库如何设置。在字典(dictionary)排序顺序中,A被视为与a相同,这是MySQL(和大多数数据库管理系统)的默认行为。但是,许多数据库管理员能够在需要时改变这种行为(如果你的数据库包含大量外语字符,可能必须这样做)。这里,关键的问题是,如果确实需要改变这种排序顺序,用简单的ORDER BY子句做不到。你必须请求数据库管理员的帮助。
本章将讲授如何使用SELECT语句的WHERE子句指定搜索条件。
数据库表一般包含大量的数据,很少需要检索表中所有行。通常只会根据特定操作或报告的需要提取表数据的子集。只检索所需数据需要指定搜索条件(search criteria),搜索条件也称为过滤条件(filter condition)。 在SELECT语句中,数据根据WHERE子句中指定的搜索条件进行过滤。WHERE子句在表名(FROM子句)之后给出,如下所示
SELECT id,name,age FROM students WHERE id = 1
这个例子采用了简单的相等测试:它检查一个列是否具有指定的值,据此进行过滤。但是SQL允许做的事情不仅仅是相等测试。
我们在关于相等的测试时看到了第一个WHERE子句,它确定一个列是否包含特定的值。MySQL支持表种列出的所有条件操作符。
操作符 | 说明 |
---|---|
= | 等于 |
<> | 不等于 |
!= | 不等于 |
< | 小于 |
<= | 小于等于 |
> | 大于 |
>= | 大于等于 |
between | 在指定两个值之间 |
以下例子列出id不是3的学生:
SELECT id,name,age FROM students WHERE id != 3;
为了检查某个范围的值,可使用BETWEEN操作符。其语法与其他WHERE子句的操作符稍有不同,因为它需要两个值,即范围的开始值和结束值。
例如,BETWEEN操作符可用来检索年龄5到10之间的学生。
SELECT id,name,age FROM students WHERE age BETWEEN 5 AND 10 ;
从这个例子中可以看到,在使用BETWEEN时,必须指定两个值——所需范围的低端值和高端值。这两个值必须用AND关键字分隔。BETWEEN匹配范围中所有的值,包括指定的开始值和结束值。
在创建表时,表设计人员可以指定其中的列是否可以不包含值。在一个列不包含值时,称其为包含空值NULL。NULL 无值(no value),它与字段包含0、空字符串或仅仅包含空格不同。SELECT语句有一个特殊的WHERE子句,可用来检查具有NULL值的列。
这个WHERE子句就是IS NULL子句。其语法如下:
SECLECT * FROM students WHRER name IS NULL;
这条语句返回没有姓名的学生。
本章讲授如何组合WHERE子句以建立功能更强的更高级的搜索条件。我们还将学习如何使用NOT和IN操作符。
第4章中介绍的所有WHERE子句在过滤数据时使用的都是单一的条件。为了进行更强的过滤控制,MySQL允许给出多个WHERE子句。这些子句可以两种方式使用:以AND子句的方式或OR子句的方式使用。操作符(operator) 用来联结或改变WHERE子句中的子句的关键字。也称为逻辑操作符(logical operator)。
为了通过不止一个列进行过滤,可使用AND操作符给WHERE子句附加条件。
下面的代码给出了一个例子:
SECLECT * FROM students WHRER id > 10 AND age > 10;
此SQL语句检索id大于10并且年龄大于10的所有学生信息。这条SELECT语句中的WHERE子句包含两个条件,并且用AND关键字联结它们。AND指示DBMS只返回满足所有给定条件的行。
OR操作符与AND操作符不同,它指示MySQL检索匹配任一条件的行。
请看如下的SELECT语句:
SECLECT * FROM students WHRER id > 10 OR age > 10;
此SQL语句检索id大于10或者年龄大于10的所有学生信息。。OR操作符告诉DBMS匹配任一条件而不是同时匹配两个条件。
WHERE可包含任意数目的AND和OR操作符。允许两者结合以进行复杂和高级的过滤。但是,组合AND和OR带来了一个有趣的问题。
SECLECT * FROM students WHRER (id > 10 OR id > 11 ) AND age > 10;
这条SELECT语句与前一条的唯一差别是,这条语句中,前两个条件用圆括号括了起来。因为圆括号具有较AND或OR操作符高的计算次序,DBMS首先过滤圆括号内的OR条件。这时,SQL语句变成了选择由id=10或id=11的学生且年龄都在10岁以上的。
在WHERE子句中使用圆括号 任何时候使用具有AND和OR操作符的WHERE子句,都应该使用圆括号明确地分组操作符。不要过分依赖默认计算次序,即使它确实是你想要的东西也是如此。使用圆括号没有什么坏处,它能消除歧义。
圆括号在WHERE子句中还有另外一种用法。IN操作符用来指定条件范围,范围中的每个条件都可以进行匹配。IN取合法值的由逗号分隔的清单,全都括在圆括号中。下面的例子说明了这个操作符:
SECLECT * FROM students WHRER id in (10,11,12);
如果你认为IN操作符完成与OR相同的功能,那么你的这种猜测是对的。下面的SQL语句完成与上面的例子相同的工作:
为什么要使用IN操作符?其优点具体如下。
在使用长的合法选项清单时,IN操作符的语法更清楚且更直观。
在使用IN时,计算的次序更容易管理(因为使用的操作符更少)。
IN操作符一般比OR操作符清单执行更快。
IN的最大优点是可以包含其他SELECT语句,使得能够更动态地建立WHERE子句。
WHERE子句中的NOT操作符有且只有一个功能,那就是否定它之后所跟的任何条件。NOT WHERE子句中用来否定后跟条件的关键字。
下面的例子说明NOT的使用。为了列出除10和11之外的所有学生,可编写如下的代码:
SECLECT * FROM students WHRER id not in (10,11,12);
本章介绍什么是通配符、如何使用通配符以及怎样使用LIKE操作符进行通配搜索,以便对数据进行复杂过滤。
前面介绍的所有操作符都是针对已知值进行过滤的。不管是匹配一个还是多个值,测试大于还是小于已知值,或者检查某个范围的值,共同点是过滤中使用的值都是已知的。但是,这种过滤方法并不是任何时候都好用。例如,怎样搜索产品名中包含文本anvil的所有产品?用简单
的比较操作符肯定不行,必须使用通配符。利用通配符可创建比较特定数据的搜索模式。在这个例子中,如果你想找出名称包含anvil的所有产品,可构造一个通配符搜索模式,找出产品名中任何位置出现anvil的产品。
通配符(wildcard) 用来匹配值的一部分的特殊字符。
搜索模式(search pattern)
① 由字面值、通配符或两者组合构成的搜索条件。通配符本身实际是SQL的WHERE子句中有特殊含义的字符,SQL支持几种通配符。为在搜索子句中使用通配符,必须使用LIKE操作符。LIKE指示MySQL,后跟的搜索模式利用通配符匹配而不是直接相等匹配进行比较。谓词 操作符何时不是操作符?答案是在它作为谓词(predicate)时。从技术上说,LIKE是谓词而不是操作符。虽然最终的结果是相同的,但应该对此术语有所了解,以免在SQL文档中遇到此术语时不知道。
最常使用的通配符是百分号(%)。在搜索串中,%表示任何字符出现任意次数。例如,为了找出所有以词jet起头的产品,可使用以下SELECT语句:
SECLECT * FROM students WHRER name like '李%';
此例子使用了搜索模式‘李%'。在执行这条子句时,将检索任意以‘李’起头的词。%告诉MySQL接受‘李’之后的任意字符,不管它有多少字符。区分大小写 根据MySQL的配置方式,
SECLECT * FROM students WHRER name like '%李%';
搜索模式'%李%'表示匹配任何位置包含文本李的值,而不论它之前或之后出现什么字符。通配符也可以出现在搜索模式的中间,虽然这样做不太有用。下面的例子找出以李起头以四结尾的所有学生:
SECLECT * FROM students WHRER name like '李%四';
重要的是要注意到,除了一个或多个字符外,%还能匹配0个字符。%代表搜索模式中给定位置的0个、1个或多个字符。注意尾空格 尾空格可能会干扰通配符匹配。
另一个有用的通配符是下划线(_)。下划线的用途与%一样,但下划
线只匹配单个字符而不是多个字符。
举一个例子:
SECLECT * FROM students WHRER name like '李_';
结果返回姓李的学生并且姓名只有两个字。
正如所见,MySQL的通配符很有用。但这种功能是有代价的:通配符搜索的处理一般要比前面讨论的其他搜索所花时间更长。这里给出一
些使用通配符要记住的技巧。
不要过度使用通配符。如果其他操作符能达到相同的目的,应该使用其他操作符。
在确实需要使用通配符时,除非绝对有必要,否则不要把它们用在搜索模式的开始处。把通配符置于搜索模式的开始处,搜索起来是最慢的。
仔细注意通配符的位置。如果放错地方,可能不会返回想要的数
用正则表达式
进行搜索
本章将学习如何在MySQL WHERE子句内使用正则表达式来更好地控
制数据过滤。
前两章中的过滤例子允许用匹配、比较和通配操作符寻找数据。对于基本的过滤(或者甚至是某些不那么基本的过滤),这样就足够了。但随着过滤条件的复杂性的增加,WHERE子句本身的复杂性也有必要增加。这也就是正则表达式变得有用的地方。正则表达式是用来匹配文本的特殊的串(字符集合)。如果你想从一个文本文件中提取电话号码,可以使用正则表达式。如果你需要查找名字中间有数字的所有文件,可以使用一个正则表达式。如果你想在一个文本块中找到所有重复的单词,可以使用一个正则表达式。如果你想替换一个页面中的所有URL为这些URL的实际HTML链接,也可以使用一个正则表达式(对于最后这个例子,或者是两个正则表达式)。所有种类的程序设计语言、文本编辑器、操作系统等都支持正则表达式。有见识的程序员和网络管理员已经关注作为他们技术工具重要内容的正则表达式很长时间了。正则表达式用正则表达式语言来建立,正则表达式语言是用来完成刚讨论的所有工作以及更多工作的一种特殊语言。与任意语言一样,正则表达式具有你必须学习的特殊的语法和指令。
在前面的章节我们已经了解到MySQL可以通过 LIKE ...% 来进行模糊匹配。
MySQL 同样也支持其他正则表达式的匹配, MySQL中使用 REGEXP 操作符来进行正则表达式匹配。
如果您了解PHP或Perl,那么操作起来就非常简单,因为MySQL的正则表达式匹配与这些脚本的类似。
下表中的正则模式可应用于 REGEXP 操作符中。
模式 | 描述 |
---|---|
^ | 匹配输入字符串的开始位置。如果设置了 RegExp 对象的 Multiline 属性,^ 也匹配 '\n' 或 '\r' 之后的位置。 |
$ | 匹配输入字符串的结束位置。如果设置了RegExp 对象的 Multiline 属性,$ 也匹配 '\n' 或 '\r' 之前的位置。 |
. | 匹配除 "\n" 之外的任何单个字符。要匹配包括 '\n' 在内的任何字符,请使用像 '[.\n]' 的模式。 |
[...] | 字符集合。匹配所包含的任意一个字符。例如, '[abc]' 可以匹配 "plain" 中的 'a'。 |
[^...] | 负值字符集合。匹配未包含的任意字符。例如, '[^abc]' 可以匹配 "plain" 中的'p'。 |
p1|p2|p3 | 匹配 p1 或 p2 或 p3。例如,'z|food' 能匹配 "z" 或 "food"。'(z|f)ood' 则匹配 "zood" 或 "food"。 |
* | 匹配前面的子表达式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。* 等价于{0,}。 |
+ | 匹配前面的子表达式一次或多次。例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等价于 {1,}。 |
{n} | n 是一个非负整数。匹配确定的 n 次。例如,'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food" 中的两个 o。 |
{n,m} | m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。 |
了解以上的正则需求后,我们就可以根据自己的需求来编写带有正则表达式的SQL语句。以下我们将列出几个小实例(表名:students)来加深我们的理解:
查找name字段中以'st'为开头的所有数据:
SELECT name FROM students WHERE name REGEXP '^st';
查找name字段中以'ok'为结尾的所有数据:
SELECT name FROM students WHERE name REGEXP 'ok$';
查找name字段中包含'mar'字符串的所有数据:
SELECT name FROM students WHERE name REGEXP 'mar';
查找name字段中以元音字符开头或以'ok'字符串结尾的所有数据:
SELECT name FROM students WHERE name REGEXP '^[aeiou]|ok$';
本章介绍什么是计算字段,如何创建计算字段以及怎样从应用程序中使用别名引用它们。
存储在数据库表中的数据一般不是应用程序所需要的格式。下面举几个例子。
如果想在一个字段中既显示公司名,又显示公司的地址,但这两个信息一般包含在不同的表列中。
城市、州和邮政编码存储在不同的列中(应该这样),但邮件标签打印程序却需要把它们作为一个恰当格式的字段检索出来。
列数据是大小写混合的,但报表程序需要把所有数据按大写表示出来。
物品订单表存储物品的价格和数量,但不需要存储每个物品的总价格(用价格乘以数量即可)。为打印发票,需要物品的总价格。
需要根据表数据进行总数、平均数计算或其他计算。在上述每个例子中,存储在表中的数据都不是应用程序所需要的。我们需要直接从数据库中检索出转换、计算或格式化过的数据;而不是检索出数据,然后再在客户机应用程序或报告程序中重新格式化。这就是计算字段发挥作用的所在了。与前面各章介绍过的列不同计算字段并不实际存在于数据库表中。计算字段是运行时在SELECT语句内创建的。
字段(field) 基本上与列(column)的意思相同,经常互换使用,不过数据库列一般称为列,而术语字段通常用在计算字段的连接上。重要的是要注意到,只有数据库知道SELECT语句中哪些列是实际的表列,哪些列是计算字段。从客户机(如应用程序)的角度来看,计算字段的数据是以与其他列的数据相同的方式返回的。客户机与服务器的格式 可在SQL语句内完成的许多转换和格式化工作都可以直接在客户机应用程序内完成。但一般来说,在数据库服务器上完成这些操作比在客户机中完成要快得多,因为DBMS是设计来快速有效地完成这种处理的。
为了说明如何使用计算字段,举一个创建由两列组成的标题的简单例子。
vendors表包含供应商名和位置信息。假如要生成一个供应商报表,需要在供应商的名字中按照name(location)这样的格式列出供应商的位置。此报表需要单个值,而表中数据存储在两个列vend_name和vend_ country中。此外,需要用括号将vend_country括起来,这些东西都没有明确存储在数据库表中。我们来看看怎样编写返回供应商名和位置的
SELECT语句。
拼接(concatenate) 将值联结到一起构成单个值。解决办法是把两个列拼接起来。在MySQL的SELECT语句中,可使用Concat()函数来拼接两个列。创建计算字段
SELECT CONCAT(name,'(',age,')') FROM students;
Concat()拼接串,即把多个串连接起来形成一个较长的串。
Concat()需要一个或多个指定的串,各个串之间用逗号分隔。
上面的SELECT语句连接以下4个元素:
存储在name列中的名字;
包含一个空格和一个左圆括号的串;
存储在age列中的年龄;
包含一个右圆括号的串。
从上述输出中可以看到,SELECT语句返回包含上述4个元素的单个列(计算字段)。
使用数据处理函数
本章介绍什么是函数,MySQL支持何种函数,以及如何使用这些函数。
与其他大多数计算机语言一样,SQL支持利用函数来处理数据。函数一般是在数据上执行的,它给数据的转换和处理提供了方便。在前一章中用来去掉串尾空格的RTrim()就是一个函数的例子。函数没有SQL的可移植性强 能运行在多个系统上的代码称为可移植的(portable)。相对来说,多数SQL语句是可移植的,在SQL实现之间有差异时,这些差异通常不那么难处理。而函数的可移植性却不强。几乎每种主要的DBMS的实现都支持其他实现不支持的函数,而且有时差异还很大。 为了代码的可移植,许多SQL程序员不赞成使用特殊实现的功能。虽然这样做很有好处,但不总是利于应用程序的性能。如果不使用这些函数,编写某些应用程序代码会很艰难。必须利用其他方法来实现DBMS非常有效地完成的工作。 如果你决定使用函数,应该保证做好代码注释,以便以后你(或其他人)能确切地知道所编写SQL代码的含义。
大多数SQL实现支持以下类型的函数。
用于处理文本串(如删除或填充值,转换值为大写或小写)
用于在数值数据上进行算术操作(如返回绝对值,进行代数运算)的数值函数。
用于处理日期和时间值并从这些值中提取特定成分(例如,返回两个日期之差,检查日期有效性等)的日期和时间函数。
返回DBMS正使用的特殊信息(如返回用户登录信息,检查版本细节)的系统函数。
上一章中我们已经看过一个文本处理函数的例子,其中使用RTrim()函数来去除列值右边的空格。下面是另一个例子,这次使用Upper()函数:
SELECT Upper(name) FROM students;
Upper()将字母文本转换为大写。
函 数 | 说 明 |
---|---|
Left() | 返回串左边的字符 |
Length() | 返回串的长度 |
Locate() | 找出串的一个子串 |
Lower() | 将串转换为小写 |
LTrim() | 去掉串左边的空格 |
Right() | 返回串右边的字符 |
函 数 | 说 明 |
---|---|
RTrim() | 去掉串右边的空格 |
Soundex() | 返回串的SOUNDEX值 |
SubString() | 返回子串的字符 |
Upper() | 将串转换为大写 |
日期和时间采用相应的数据类型和特殊的格式存储,以便能快速和有效地排序或过滤,并且节省物理存储空间。一般,应用程序不使用用来存储日期和时间的格式,因此日期和时间函数总是被用来读取、统计和处理这些值。由于这个原因,日期和时间函数在MySQL语言中具有重要的作用。
函 数 | 说 明 |
---|---|
AddDate() | 增加一个日期(天、周等) |
AddTime() | 增加一个时间(时、分等) |
CurDate() | 返回当前日期 |
CurTime() | 返回当前时间 |
Date() | 返回日期时间的日期部分 |
DateDiff() | 计算两个日期之差 |
Date_Add() | 高度灵活的日期运算函数 |
Date_Format() | 返回一个格式化的日期或时间串 |
Day() | 返回一个日期的天数部分 |
DayOfWeek() | 对于一个日期,返回对应的星期几 |
Hour() | 返回一个时间的小时部分 |
Minute() | 返回一个时间的分钟部分 |
Month() | 返回一个日期的月份部分 |
Now() | 返回当前日期和时间 |
Second() | 返回一个时间的秒部分 |
Time() | 返回一个日期时间的时间部分 |
Year() | 返回一个日期的年份部分 |
这是重新复习用WHERE进行数据过滤的一个好时机。迄今为止,我们都是用比较数值和文本的WHERE子句过滤数据,但数据经常需要用日期进行过滤。用日期进行过滤需要注意一些别的问题和使用特殊的MySQL函数。首先需要注意的是MySQL使用的日期格式。无论你什么时候指定一个日期,不管是插入或更新表值还是用WHERE子句进行过滤,日期必须为格式yyyy-mm-dd。因此,2005年9月1日,给出为2005-09-01。虽然其他的日期格式可能也行,但这是首选的日期格式,因为它排除了多义性(如,04/05/06是2006年5月4日或2006年4月5日或2004年5月6日或……)。
应该总是使用4位数字的年份 支持2位数字的年份,MySQL处理00-69为2000-2069,处理70-99为1970-1999。虽然它们可能是打算要的年份,但使用完整的4位数字年份更可靠,因为MySQL不必做出任何假定。因此,基本的日期比较应该很简单:
SELECT * FROM orders WHERE order_date = '2005-09-01';
此SELECT语句正常运行。它检索出一个订单记录,该订单记录的order_date为2005-09-01。但是,使用WHERE order_date = '2005-09-01'可靠吗?order_ date的数据类型为datetime。这种类型存储日期及时间值。样例表中的值全都具有时间值00:00:00,但实际中很可能并不总是这样。如果用当前日期和时间存储订单日期(因此你不仅知道订单日期,还知道下 订 单 当 天 的 时 间 ), 怎 么 办 ? 比 如 , 存 储 的 order_date 值 为2005-09-01 11:30:05,则WHERE order_date = '2005-09-01'失败。即使给出具有该日期的一行,也不会把它检索出来,因为WHERE匹配失败。解决办法是指示MySQL仅将给出的日期与列中的日期部分进行比较,而不是将给出的日期与整个列值进行比较。为此,必须使用Date()函数。Date(order_date)指示MySQL仅提取列的日期部分,更可靠的
SELECT语句为:
SELECT * FROM orders WHERE Date(order_date) = '2005-09-01';
如果要的是日期,请使用Date() 如果你想要的仅是日期,则使用Date()是一个良好的习惯,即使你知道相应的列只包含日期也是如此。这样,如果由于某种原因表中以后有日期和时间值,你的SQL代码也不用改变。当然,也存在一个Time()函数,在你只想要时间时应该使用它。 Date()和Time()都是在MySQL 4.1.1中第一次引入的。在你知道了如何用日期进行相等测试后,其他操作符的使用也就很清楚了。不过,还有一种日期比较需要说明。如果你想检索出2005年9月下的
所有订单,怎么办?简单的相等测试不行,因为它也要匹配月份中的天数。有几种解决办法,其中之一如下所示:
SELECT * FROM orders WHERE Date(order_date) BETWEEN '2005-09-01' AND '2005-09-30';
其中,BETWEEN操作符用来把2005-09-01和2005-09-30定义为一个要匹配的日期范围。
还有另外一种办法(一种不需要记住每个月中有多少天或不需要操心闰年2月的办法):Year()是一个从日期(或日期时间)中返回年份的函数。类似,Month()从日期中返回月份。因此,WHERE Year(order_date)
SELECT * FROM orders WHERE YEAR(order_date) = 2005 AND MONTH(order_date) = 9
数值处理函数仅处理数值数据。这些函数一般主要用于代数、三角或几何运算,因此没有串或日期—时间处理函数的使用那么频繁。具有讽刺意味的是,在主要DBMS的函数中,数值函数是最一致最统一的函数。表11-3列出一些常用的数值处理函数。
函 数 | 说 明 |
---|---|
Abs() | 返回一个数的绝对值 |
Cos() | 返回一个角度的余弦 |
Exp() | 返回一个数的指数值 |
Mod() | 返回除操作的余数 |
Rand() | 返回一个随机数 |
Pi() | 返回圆周率 |
Sin() | 返回一个角度的正弦 |
Sqrt() | 返回一个数的平方根 |
Tan() | 返回一个角度的正切 |
本章介绍什么是SQL的聚集函数以及如何利用它们汇总表的数据。
我们经常需要汇总数据而不用把它们实际检索出来,为此MySQL提供了专门的函数。使用这些函数,MySQL查询可用于检索数据,以便分
析和报表生成。这种类型的检索例子有以下几种。
确定表中行数(或者满足某个条件或包含某个特定值的行数)。
获得表中行组的和。
找出表列(或所有行或某些特定的行)的最大值、最小值和平均值。
上述例子都需要对表中数据(而不是实际数据本身)汇总。因此,返回实际表数据是对时间和处理资源的一种浪费(更不用说带宽了)。重复一遍,实际想要的是汇总信息。
为方便这种类型的检索,MySQL给出了5个聚集函数.
函 数 | 说 明 |
---|---|
AVG() | 返回某列的平均值 |
COUNT() | 返回某列的行数 |
MAX() | 返回某列的最大值 |
MIN() | 返回某列的最小值 |
SUM() | 返回某列值之和 |
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。