MySQL中文参考手册一个字符串是一个字符序列,由单引号(“'”)或双引号(“"”)字符(后者只有你不在ANSI模式运行)包围。例如:
'a string' "another string"
在字符串内,某个顺序有特殊的意义。这些顺序的每一个以一条反斜线(“\”)开始,称为转义字符。MySQL识别下列转义字符:
\0 NUL)字符。 \n \t \r \b \' \" \\ \% \_ 注意,如果你在某些正文环境中使用“\%”或“\%_”,这些将返回字符串“\%”和“\_”而不是“%”和“_”。
有几种方法在一个字符串内包括引号:
下面显示的SELECT演示引号和转义如何工作:
mysql> SELECT 'hello', '"hello"', '""hello""', 'hel''lo', '\'hello'; +-------+---------+-----------+--------+--------+ | hello | "hello" | ""hello"" | hel'lo | 'hello | +-------+---------+-----------+--------+--------+ mysql> SELECT "hello", "'hello'", "''hello''", "hel""lo", "\"hello"; +-------+---------+-----------+--------+--------+ | hello | 'hello' | ''hello'' | hel"lo | "hello | +-------+---------+-----------+--------+--------+ mysql> SELECT "This\nIs\nFour\nlines"; +--------------------+ | This Is Four lines | +--------------------+
如果你想要把二进制数据插入到一个BLOB列,下列字符必须由转义序列表示:
NUL\ ' " 如果你写C代码,你可以使用C API函数mysql_escape_string()来为INSERT语句转义字符。见20.3 C API 函数概述。在 Perl中,你可以使用DBI包中的quote方法变换特殊的字符到正确的转义序列。见20.5.2 DBI接口。
你应该在任何可能包含上述任何特殊字符的字符串上使用转义函数!
整数表示为一个数字顺序。浮点数使用“.”作为一个十进制分隔符。这两种类型的数字可以前置“-”表明一个负值。
有效整数的例子:
1221 0 -32
有效浮点数的例子:
294.42 -32032.6809e+10 148.00
一个整数可以在浮点上下文使用;它解释为等值的浮点数。
MySQL支持十六进制值。在数字上下文,它们表现类似于一个整数(64位精度)。在字符串上下文,它们表现类似于一个二进制字符串,这里每一对十六进制数字被变换为一个字符。
mysql> SELECT 0xa+0
-> 10
mysql> select 0x5061756c;
-> Paul
十六进制字符串经常被ODBC使用,给出BLOB列的值。
NULL值NULL值意味着“无数据”并且不同于例如数字类型的0为或字符串类型的空字符串。见18.15 NULL值问题。
当使用文本文件导入或导出格式(LOAD DATA INFILE, SELECT
... INTO OUTFILE)时,NULL可以用\N表示。见7.16 LOAD DATA INFILE句法。
数据库、表、索引、列和别名的名字都遵守MySQL同样的规则:
注意,从MySQL3.23.6开始规则改变了,此时我们引入了用'引用的标识符(数据库、表和列命名)(如果你以ANSI模式运行,"也将用于引用标识符)。
| 标识符 | 最大长度 | 允许的字符 |
| 数据库 | 64 | 在一个目录名允许的任何字符,除了/. |
| 表 | 64 | 在文件名中允许的任何字符,除了/或. |
| 列 | 64 | 所有字符 |
| 别名 | 255 | 所有字符 |
注意,除了以上,你在一个标识符中不能有ASCII(0)或ASCII(255)。
注意,如果标识符是一个限制词或包含特殊字符,当你使用它时,你必须总是用`引用它:
SELECT * from `select` where `select`.id > 100;
在 MySQL的先前版本,命名规则如下:
建议你不使用象1e这样的名字,因为一个表达式如1e+1是二义性的。它可以解释为表达式1e
+ 1或数字1e+1。
在MySQL中,你能使用下列表格的任何一种引用列:
| 列引用 | 含义 |
col_name |
来自于任意表的列col_name,用于包含该表的一个列的查询中 |
tbl_name.col_name |
来自当前的数据库的表tbl_name的列col_name |
db_name.tbl_name.col_name |
行列col_name从表格tbl_name数据库db_name。这个形式在MySQL3.22或以后版本可用。
|
`column_name` |
是一个关键词或包含特殊字符的列。 |
在一条语句的列引用中,你不必指定一个tbl_name或db_name.tbl_name前缀,除非引用会有二义性。例如,假定表t1和t2,每个均包含列c,并且你用一个使用t1和t2的SELECT语句检索c。在这种情况下,c有二义性,因为它在使用表的语句中不是唯一的,因此你必须通过写出t1.c或t2.c来指明你想要哪个表。同样,如果你从数据库db1中一个表t和在数据库db2的一个表t检索,你必须用db1.t.col_name和db2.t.col_name引用这些数据表的列。
句法.tbl_name意味着在当前的数据库中的表tbl_name,该句法为了ODBC的兼容性被接受,因为一些ODBC程序用一个“.”字符作为数据库表名的前缀。
在MySQL中,数据库和表对应于在那些目录下的目录和文件,因而,内在的操作系统的敏感性决定数据库和表命名的大小写敏感性。这意味着数据库和表名在Unix上是区分大小写的,而在Win32上忽略大小写。
注意:在Win32上,尽管数据库和表名是忽略大小写的,你不应该在同一个查询中使用不同的大小写来引用一个给定的数据库和表。下列查询将不工作,因为它作为my_table和作为MY_TABLE引用一个表:
mysql> SELECT * FROM my_table WHERE MY_TABLE.col=1;
列名在所有情况下都是忽略大小写的。
表的别名是区分大小写的。下列查询将不工作,:
因为它用a和A引用别名:
mysql> SELECT col_name FROM tbl_name AS a
WHERE a.col_name = 1 OR A.col_name = 2;
列的别名是忽略大小写的。
MySQL支持线程特定的变量,用@variablename句法。一个变量名可以由当前字符集的数字字母字符和“_”、“$”和“.”组成。缺省字符集是ISO-8859-1
Latin1;这可以通过重新编译MySQL改变。见9.1.1 用于数据和排序的字符集。
变量不必被初始化。缺省地,他们包含NULL并能存储整数、实数或一个字符串值。当线程退出时,对于一个线程的所有变量自动地被释放。
你可以用SET句法设置一个变量:
SET @variable= { integer expression | real expression | string expression }
[,@variable= ...].
你也可以用@variable:=expr句法在一个表达式中设置一个变量:
select @t1:=(@t2:=1)+@t3:=4,@t1,@t2,@t3; +----------------------+------+------+------+ | @t1:=(@t2:=1)+@t3:=4 | @t1 | @t2 | @t3 | +----------------------+------+------+------+ | 5 | 5 | 1 | 4 | +----------------------+------+------+------+
(这里,我们不得不使用:=句法,因为=是为比较保留的)
MySQL支持大量的列类型,它可以被分为3类:数字类型、日期和时间类型以及字符串(字符)类型。本节首先给出可用类型的一个概述,并且总结每个列类型的存储需求,然后提供每个类中的类型性质的更详细的描述。概述有意简化,更详细的说明应该考虑到有关特定列类型的附加信息,例如你能为其指定值的允许格式。
由MySQL支持的列类型列在下面。下列代码字母用于描述中:
M D M-2。
方括号(“[”和“]”)指出可选的类型修饰符的部分。
注意,如果你指定一个了为ZEROFILL,MySQL将为该列自动地增加UNSIGNED属性。
TINYINT[(M)] [UNSIGNED] [ZEROFILL] -128到127,无符号的范围是0到255。
SMALLINT[(M)] [UNSIGNED] [ZEROFILL] -32768到32767,无符号的范围是0到65535。
MEDIUMINT[(M)] [UNSIGNED] [ZEROFILL] -8388608到8388607,无符号的范围是0到16777215。
INT[(M)] [UNSIGNED] [ZEROFILL] -2147483648到2147483647,无符号的范围是0到4294967295。
INTEGER[(M)] [UNSIGNED] [ZEROFILL] INT的一个同义词。 BIGINT[(M)] [UNSIGNED] [ZEROFILL] -9223372036854775808到9223372036854775807,无符号的范围是0到18446744073709551615。注意,所有算术运算用有符号的BIGINT或DOUBLE值完成,因此你不应该使用大于9223372036854775807(63位)的有符号大整数,除了位函数!注意,当两个参数是INTEGER值时,-、+和*将使用BIGINT运算!这意味着如果你乘2个大整数(或来自于返回整数的函数),如果结果大于9223372036854775807,你可以得到意外的结果。一个浮点数字,不能是无符号的,对一个单精度浮点数,其精度可以是<=24,对一个双精度浮点数,是在25
和53之间,这些类型如FLOAT和DOUBLE类型马上在下面描述。FLOAT(X)有对应的FLOAT和DOUBLE相同的范围,但是显示尺寸和小数位数是未定义的。在MySQL3.23中,这是一个真正的浮点值。在更早的MySQL版本中,FLOAT(precision)总是有2位小数。该句法为了ODBC兼容性而提供。
FLOAT[(M,D)] [ZEROFILL] -3.402823466E+38到-1.175494351E-38,0
和1.175494351E-38到3.402823466E+38。M是显示宽度而D是小数的位数。没有参数的FLOAT或有<24
的一个参数表示一个单精密浮点数字。
DOUBLE[(M,D)] [ZEROFILL] -1.7976931348623157E+308到-2.2250738585072014E-308、
0和2.2250738585072014E-308到1.7976931348623157E+308。M是显示宽度而D是小数位数。没有一个参数的DOUBLE或FLOAT(X)(25
< = X < = 53)代表一个双精密浮点数字。 DOUBLE PRECISION[(M,D)] [ZEROFILL] REAL[(M,D)] [ZEROFILL] DOUBLE同义词。 DECIMAL[(M[,D])] [ZEROFILL] CHAR列:“未压缩”意味着数字作为一个字符串被存储,值的每一位使用一个字符。小数点,并且对于负数,“-”符号不在M中计算。如果D是0,值将没有小数点或小数部分。DECIMAL值的最大范围与DOUBLE相同,但是对一个给定的DECIMAL列,实际的范围可以通过M和D的选择被限制。如果D被省略,它被设置为0。如果M被省掉,它被设置为10。注意,在MySQL3.22里,M参数包括符号和小数点。
NUMERIC(M,D) [ZEROFILL] DECIMAL的一个同义词。 DATE '1000-01-01'到'9999-12-31'。MySQL以'YYYY-MM-DD'格式来显示DATE值,但是允许你使用字符串或数字把值赋给DATE列。
DATETIME '1000-01-01 00:00:00'到'9999-12-31
23:59:59'。MySQL以'YYYY-MM-DD HH:MM:SS'格式来显示DATETIME值,但是允许你使用字符串或数字把值赋给DATETIME的列。
TIMESTAMP[(M)] '1970-01-01 00:00:00'到2037年的某时。MySQL以YYYYMMDDHHMMSS、YYMMDDHHMMSS、YYYYMMDD或YYMMDD格式来显示TIMESTAMP值,取决于是否M是14(或省略)、12、8或6,但是允许你使用字符串或数字把值赋给TIMESTAMP列。一个TIMESTAMP列对于记录一个INSERT或UPDATE操作的日期和时间是有用的,因为如果你不自己给它赋值,它自动地被设置为最近操作的日期和时间。你以可以通过赋给它一个NULL值设置它为当前的日期和时间。见7.3.6 日期和时间类型。 TIME '-838:59:59'到'838:59:59'。MySQL以'HH:MM:SS'格式来显示TIME值,但是允许你使用字符串或数字把值赋给TIME列。
YEAR[(2|4)] 1901到2155,和0000(4位年格式),如果你使用2位,1970-2069(
70-69)。MySQL以YYYY格式来显示YEAR值,但是允许你把使用字符串或数字值赋给YEAR列。(YEAR类型在MySQL3.22中是新类型。) CHAR(M) [BINARY] M的范围是1
~ 255个字符。当值被检索时,空格尾部被删除。CHAR值根据缺省字符集以大小写不区分的方式排序和比较,除非给出BINARY关键词。NATIONAL
CHAR(短形式NCHAR)是ANSI SQL的方式来定义CHAR列应该使用缺省字符集。这是MySQL的缺省。CHAR是CHARACTER的一个缩写。
[NATIONAL] VARCHAR(M) [BINARY] VARCHAR值根据缺省字符集以大小写不区分的方式排序和比较,除非给出BINARY关键词值。见7.7.1 隐式列指定变化。 VARCHAR是CHARACTER
VARYING一个缩写。 TINYBLOB TINYTEXT BLOB或TEXT列,最大长度为255(2^8-1)个字符。见7.7.1 隐式列指定变化。 BLOB TEXT BLOB或TEXT列,最大长度为65535(2^16-1)个字符。见7.7.1 隐式列指定变化。 MEDIUMBLOB MEDIUMTEXT BLOB或TEXT列,最大长度为16777215(2^24-1)个字符。见7.7.1 隐式列指定变化。 LONGBLOB LONGTEXT BLOB或TEXT列,最大长度为4294967295(2^32-1)个字符。见7.7.1 隐式列指定变化 ENUM('value1','value2',...) 'value1'、'value2',
...,或NULL。一个ENUM最多能有65535不同的值。
SET('value1','value2',...) 'value1',
'value2', ...选出。一个SET最多能有64个成员。
对于每个由MySQL支持的列类型的存储需求在下面按类列出。
| 列类型 | 需要的存储量 |
TINYINT |
1 字节 |
SMALLINT |
2 个字节 |
MEDIUMINT |
3 个字节 |
INT |
4 个字节 |
INTEGER |
4 个字节 |
BIGINT |
8 个字节 |
FLOAT(X) |
4 如果 X < = 24 或 8 如果 25 < = X < = 53 |
FLOAT |
4 个字节 |
DOUBLE |
8 个字节 |
DOUBLE PRECISION |
8 个字节 |
REAL |
8 个字节 |
DECIMAL(M,D) |
M字节(D+2 , 如果M < D) |
NUMERIC(M,D) |
M字节(D+2 , 如果M < D) |
| 列类型 | 需要的存储量 |
DATE |
3 个字节 |
DATETIME |
8 个字节 |
TIMESTAMP |
4 个字节 |
TIME |
3 个字节 |
YEAR |
1 字节 |
| 列类型 | 需要的存储量 |
CHAR(M) |
M字节,1 <= M <= 255 |
VARCHAR(M) |
L+1 字节, 在此L <= M和1 <= M <= 255
|
TINYBLOB, TINYTEXT |
L+1 字节, 在此L< 2 ^ 8 |
BLOB, TEXT |
L+2 字节, 在此L< 2 ^ 16 |
MEDIUMBLOB, MEDIUMTEXT |
L+3 字节, 在此L< 2 ^ 24 |
LONGBLOB, LONGTEXT |
L+4 字节, 在此L< 2 ^ 32 |
ENUM('value1','value2',...) |
1 或 2 个字节, 取决于枚举值的数目(最大值65535) |
SET('value1','value2',...) |
1,2,3,4或8个字节, 取决于集合成员的数量(最多64个成员) |
VARCHAR和BLOB和TEXT类型是变长类型,对于其存储需求取决于列值的实际长度(在前面的表格中用L表示),而不是取决于类型的最大可能尺寸。例如,一个VARCHAR(10)列能保存最大长度为10个字符的一个字符串,实际的存储需要是字符串的长度(L),加上1个字节以记录字符串的长度。对于字符串'abcd',L是4而存储要求是5个字节。
BLOB和TEXT类型需要1,2,3或4个字节来记录列值的长度,这取决于类型的最大可能长度。
如果一个表包括任何变长的列类型,记录格式将也是变长的。注意,当一个表被创建时,MySQL可能在某些条件下将一个列从一个变长类型改变为一个定长类型或相反。见7.7.1 隐式列指定变化。
一个ENUM对象的大小由不同枚举值的数量决定。1字节被用于枚举,最大到255个可能的值;2个字节用于枚举,最大到65535
值。
一个SET对象的大小由不同的集合成员的数量决定。如果集合大小是N,对象占据(N+7)/8个字节,四舍五入为1,2,3,4或8
个字节。一个SET最多能有64个成员。
MySQL支持所有的ANSI/ISO SQL92的数字类型。这些类型包括准确数字的数据类型(NUMERIC,
DECIMAL, INTEGER,和SMALLINT),也包括近似数字的数据类型(FLOAT,
REAL,和DOUBLE PRECISION)。关键词INT是INTEGER的一个同义词,而关键词DEC是DECIMAL一个同义词。
NUMERIC和DECIMAL类型被MySQL实现为同样的类型,这在SQL92标准允许。他们被用于保存值,该值的准确精度是极其重要的值,例如与金钱有关的数据。当声明一个类是这些类型之一时,精度和规模的能被(并且通常是)指定;例如:
salary DECIMAL(9,2)
在这个例子中,9(precision)代表将被用于存储值的总的小数位数,而2(scale)代表将被用于存储小数点后的位数。因此,在这种情况下,能被存储在salary列中的值的范围是从-9999999.99到9999999.99。在ANSI/ISO
SQL92中,句法DECIMAL(p)等价于DECIMAL(p,0)。同样,句法DECIMAL等价于DECIMAL(p,0),这里实现被允许决定值p。MySQL当前不支持DECIMAL/NUMERIC数据类型的这些变种形式的任一种。这一般说来不是一个严重的问题,因为这些类型的主要益处得自于明显地控制精度和规模的能力。
DECIMAL和NUMERIC值作为字符串存储,而不是作为二进制浮点数,以便保存那些值的小数精度。一个字符用于值的每一位、小数点(如果scale>0)和“-”符号(对于负值)。如果scale是0,DECIMAL和NUMERIC值不包含小数点或小数部分。
DECIMAL和NUMERIC值得最大的范围与DOUBLE一样,但是对于一个给定的DECIMAL或NUMERIC列,实际的范围可由制由给定列的precision或scale限制。当这样的列赋给了小数点后面的位超过指定scale所允许的位的值,该值根据scale四舍五入。当一个DECIMAL或NUMERIC列被赋给了其大小超过指定(或缺省的)precision和scale隐含的范围的值,MySQL存储表示那个范围的相应的端点值。
作为对ANSI/ISO SQL92标准的扩展,MySQL也支持上表所列的整型类型TINYINT、MEDIUMINT和BIGINT。另一个扩展是MySQL支持可选地指定一个整型值显示的宽度,用括号跟在基本关键词之后(例如,INT(4))。这个可选的宽度指定被用于其宽度小于列指定宽度的值得左填补显示,但是不限制能在列中被存储的值的范围,也不限制值将被显示的位数,其宽度超过列指定的宽度。当与可选的扩展属性ZEROFILL一起使用时,缺省的空格填补用零代替。例如,对于声明为INT(5)
ZEROFILL的列,一个为4的值作为00004被检索。注意,如果你在一个整型列存储超过显示宽度的更大值,当MySQL对于某些复杂的联结(join)生成临时表时,你可能会遇到问题,因为在这些情况下,MySQL相信数据确实适合原来的列宽度。
所有的整型类型可以有一个可选(非标准的)属性UNSIGNED。当你想要在列中仅允许正数并且你需要一个稍大一点的列范围,可以使用无符号值。
FLOAT类型被用来标示近似数字的数据类型。ANSI/ISO SQL92标准允许一个可选的精度说明(但不是指数的范围),跟在关键词FLOAT后面的括号内位数。MySQL实现也支持这个可选的精度说明。当关键词FLOAT被用于一个列类型而没有精度说明时,MySQL使用4个字节存储值。一个变种的句法也被支持,在FLOAT关键词后面的括号给出2个数字。用这个选项,第一个数字继续表示在字节计算的值存储需求,而第二个数字指定要被存储的和显示跟随小数点后的位数(就象DECIMAL和NUMERIC)。当MySQL要求为这样一个列,一个小数点后的小数位超过列指定的值,存储值时,该值被四舍五入,去掉额外的位。
REAL和DOUBLE PRECISION类型不接受精度说明。作为对
ANSI/ISO SQL92 标准的扩展,MySQL识别出DOUBLE作为DOUBLE
PRECISION类型的一个同义词。与REAL精度比用于DOUBLE
PRECISION的更小的标准要求相反,MySQL实现了两种,作为8字节双精度浮点值(当运行不是“Ansi模式”时)。为了最大的移植性,近似数字的数据值的存储所需代码应该使用没有精度或小数位数说明的FLOAT或DOUBLE
PRECISION。
当要求在数字的列存储超出该列类型允许的范围的值时,MySQL剪切该值到范围内的正确端点值并且存储剪切后的结果值。
例如,一个INT列的范围是-2147483648到2147483647。如果你试图插入-9999999999到一个INT列中,值被剪切到范围的低部端点,并存储-2147483648。同样,如果你试图插入9999999999,2147483647被存储。
如果INT列是UNSIGNED,列的范围的大小是相同的,但是它的端点移到了0和4294967295。如果你试图存储-9999999999和9999999999,在列被存储的值变为0和4294967296。
对于ALTER TABLE、LOAD DATA INFILE、UPDATE和多行INSERT语句,由于剪切所发生的变换作为“警告”被报告。
日期和时间类型是DATETIME、DATE、TIMESTAMP、TIME和YEAR。这些的每一个都有合法值的一个范围,而“零”当你指定确实不合法的值时被使用。注意,MySQL允许你存储某个“不严格地”合法的日期值,例如1999-11-31,原因我们认为它是应用程序的责任来处理日期检查,而不是SQL服务器。为了使日期检查更“快”,MySQL仅检查月份在0-12的范围,天在0-31的范围。上述范围这样被定义是因为MySQL允许你在一个DATE或DATETIME列中存储日期,这里的天或月是零。这对存储你不知道准确的日期的一个生日的应用程序来说是极其有用的,在这种情况下,你简单地存储日期象1999-00-00或1999-01-00。(当然你不能期望从函数如DATE_SUB()或DATE_ADD()得到类似以这些日期的正确值)。
当用日期和时间工作时,这里是的一些要记住的一般考虑:
'98-09-04'),而不是以其他地方常用的月-日-年或日-月-年的次序(例如,'09-04-98'、'04-09-98')。
TIME值被剪切为适当的TIME范围端点值。)下表显示对每种类型的“零”值的格式:
| 列类型 | “零”值 |
DATETIME |
'0000-00-00 00:00:00' |
DATE |
'0000-00-00' |
TIMESTAMP |
00000000000000(长度取决于显示尺寸) |
TIME |
'00:00:00' |
YEAR |
0000 |
'0'或0做到,
这更容易写。 NULL,因为ODBC不能处理这样的值。
MySQL本身Y2K安全的(见1.6 2000年一致性),但是呈交给MySQL的输入值可能不是。一个包含2位年份值的任何输入是由二义性的,因为世纪是未知的。这样的值必须被解释成4位形式,因为MySQL内部使用4位存储年份。
对于DATETIME, DATE, TIMESTAMP和YEAR类型,MySQL使用下列规则的解释二义性的年份值:
00-69的年值被变换到2000-2069。 70-99的年值被变换到1970-1999。记得这些规则仅仅提供对于你数据的含义的合理猜测。如果MySQL使用的启发规则不产生正确的值,你应该提供无二义的包含4位年值的输入。
DATETIME, DATE和TIMESTAMP类型DATETIME, DATE和TIMESTAMP类型是相关的。本节描述他们的特征,他们是如何类似的而又不同的。
DATETIME类型用在你需要同时包含日期和时间信息的值时。MySQL检索并且以'YYYY-MM-DD
HH:MM:SS'格式显示DATETIME值,支持的范围是'1000-01-01
00:00:00'到'9999-12-31 23:59:59'。(“支持”意味着尽管更早的值可能工作,但不能保证他们可以。)
DATE类型用在你仅需要日期值时,没有时间部分。MySQL检索并且以'YYYY-MM-DD'格式显示DATE值,支持的范围是'1000-01-01'到'9999-12-31'。
TIMESTAMP列类型提供一种类型,你可以使用它自动地用当前的日期和时间标记INSERT或UPDATE的操作。如果你有多个TIMESTAMP列,只有第一个自动更新。
自动更新第一个TIMESTAMP列在下列任何条件下发生:
INSERT或LOAD DATA INFILE语句中指定。
UPDATE语句中指定且一些另外的列改变值。(注意一个UPDATE设置一个列为它已经有的值,这将不引起TIMESTAMP列被更新,因为如果你设置一个列为它当前的值,MySQL为了效率而忽略更改。)TIMESTAMP列为NULL. 除第一个以外的TIMESTAMP列也可以设置到当前的日期和时间,只要将列设为NULL,或NOW()。
通过明确地设置希望的值,你可以设置任何TIMESTAMP列为不同于当前日期和时间的值,即使对第一个TIMESTAMP列也是这样。例如,如果,当你创建一个行时,你想要一个TIMESTAMP被设置到当前的日期和时间,但在以后无论何时行被更新时都不改变,你可以使用这个属性:
TIMESTAMP列为它的当前值。
另一方面,你可能发现,当行被创建并且远离随后的更改时,很容易用一个你用NOW()初始化的DATETIME列。
TIMESTAMP值可以从1970的某时的开始一直到2037年,精度为一秒,其值作为数字显示。
在MySQL检索并且显示TIMESTAMP值取决于显示尺寸的格式如下表。“完整”TIMESTAMP格式是14位,但是TIMESTAMP列可以用更短的显示尺寸创造:
| 列类型 | 显示格式 |
TIMESTAMP(14) |
YYYYMMDDHHMMSS |
TIMESTAMP(12) |
YYMMDDHHMMSS |
TIMESTAMP(10) |
YYMMDDHHMM |
TIMESTAMP(8) |
YYYYMMDD |
TIMESTAMP(6) |
YYMMDD |
TIMESTAMP(4) |
YYMM |
TIMESTAMP(2) |
YY |
所有的TIMESTAMP列都有同样的存储大小,不考虑显示尺寸。最常见的显示尺寸是6、8、12、和14。你可以在表创建时间指定一个任意的显示尺寸,但是值0或比14大被强制到14。在从1~13范围的奇数值尺寸被强制为下一个更大的偶数。
使用一个常用的格式集的任何一个,你可以指定DATETIME、DATE和TIMESTAMP值:
'YYYY-MM-DD HH:MM:SS'或'YY-MM-DD HH:MM:SS'格式的一个字符串。允许一种“宽松”的语法--任何标点可用作在日期部分和时间部分之间的分隔符。例如,'98-12-31
11:30:45'、'98.12.31 11+30+45'、'98/12/31 11*30*45'和'98@12@31
11^30^45'是等价的。 'YYYY-MM-DD'或'YY-MM-DD'格式的一个字符串。允许一种“宽松”的语法。例如,'98-12-31',
'98.12.31', '98/12/31'和'98@12@31'是等价的。 'YYYYMMDDHHMMSS'或'YYMMDDHHMMSS'格式的没有任何分隔符的一个字符串,例如,'19970523091528'和'970523091528'被解释为'1997-05-23
09:15:28',但是'971122459015'是不合法的(它有毫无意义的分钟部分)且变成'0000-00-00
00:00:00'。 'YYYYMMDD'或'YYMMDD'格式的没有任何分隔符的一个字符串,如果字符串认为是一个日期。例如,'19970523'和'970523'被解释作为'1997-05-23',但是'971332'是不合法的(
它有无意义的月和天部分)且变成'0000-00-00'。 YYYYMMDDHHMMSS或YYMMDDHHMMSS格式的一个数字,如果数字认为是一个日期。例如,19830905132800和830905132800被解释作为'1983-09-05
13:28:00'。 YYYYMMDD或YYMMDD格式的一个数字,如果数字认为是一个日期。例如,19830905和830905被解释作为'1983-09-05'。
DATETIME, DATE或TIMESTAMP上下文环境中接受的函数,例如NOW()或CURRENT_DATE。
不合法DATETIME, DATE或TIMESTAMP值被变换到适当类型的“零”值('0000-00-00
00:00:00', '0000-00-00'或00000000000000)。
对于包括的日期部分分隔符的指定为字符串的值,不必要为小于10的月或天的值指定2位数字,'1979-6-9'与'1979-06-09'是一样的。同样,
对于包括的时间部分分隔符的指定为字符串的值,不必为小于10的小时、月或秒指定2位数字,'1979-10-30
1:2:3'与'1979-10-30 01:02:03'是一样的。
指定为数字应该是6、8、12或14位长。如果数字是8或14位长,它被假定以YYYYMMDD或YYYYMMDDHHMMSS格式并且年份由头4位数字给出。如果数字是6或12位长,它被假定是以YYMMDD或YYMMDDHHMMSS格式且年份由头2位数字给出。不是这些长度之一的数字通过填补前头的零到最接近的长度来解释。
指定为无分隔符的字符串用它们给定的长度来解释。如果字符串长度是8或14个字符,年份被假定头4个字符给出,否则年份被假定由头2个字符给出。对于字符串中呈现的多个部分,字符串从左到右边被解释,以找出年、月、日、小时、分钟和秒值,这意味着,你不应该使用少于
6 个字符的字符串。例如,如果你指定'9903',认为将代表1999年3月,你会发现MySQL把一个“零”日期插入到你的表中,这是因为年份和月份值99和03,但是日期部分丢失(零),因此该值不是一个合法的日期。
TIMESTAMP列使用被指定的值的完整精度的存储合法的值,不考虑显示大小。这有几个含意:
TIMESTAMP(4)或TIMESTAMP(2)。否则,值将不是一个合法的日期并且0将被存储。
ALTER TABLE拓宽一个狭窄的TIMESTAMP列,以前被“隐蔽”的信息将被显示。
TIMESTAMP列不会导致信息失去,除了感觉上值在显示时,较少的信息被显示出。
TIMESTAMP值被存储为完整精度,直接操作存储值的唯一函数是UNIX_TIMESTAMP(),其他函数操作在格式化了的检索的值上,这意味着你不能使用函数例如HOUR()或SECOND(),除非TIMESTAMP值的相关部分被包含在格式化的值中。例如,一个TIMESTAMP列的HH部分部被显示,除非显示大小至少是10,因此在更短的TIMESTAMP值上试试使用HOUR()产生一个无意义的结果。
在某种程度上,你可以把一种日期类型的值赋给一个不同的日期类型的对象。然而,这可能值有一些改变或信息的损失:
DATE值赋给一个DATETIME或TIMESTAMP对象,结果值的时间部分被设置为'00:00:00',因为DATE值不包含时间信息。
DATETIME或TIMESTAMP值赋给一个DATE对象,结果值的时间部分被删除,因为DATE类型不存储时间信息。
DATETIME, DATE和TIMESTAMP值全都可以用同样的格式集来指定,但所有类型不都有同样的值范围。例如,TIMESTAMP值不能比1970早或比2037网晚,这意味着,一个日期例如'1968-01-01',当作为一个DATETIME或DATE值合法时,它不是一个正确TIMESTAMP值,并且如果赋值给这样一个对象,它将被变换到0。
当指定日期值时,当心某些缺陷:
'10:11:12'可能看起来像时间值,因为“:”分隔符,但是如果在一个日期中使用,上下文将作为年份被解释成'2010-11-12'。值'10:45:15'将被变换到'0000-00-00',因为'45'不是一个合法的月份。
00-69范围的年值被变换到2000-2069。 70-99围的年值被变换到1970-1999。 TIME类型MySQL检索并以'HH:MM:SS'格式显示TIME值(或对大小时值,'HHH:MM:SS'格式)。TIME值的范围可以从'-838:59:59'到'838:59:59'。小时部分可能很大的的原因是TIME类型不仅可以被使用在表示一天的时间(它必须是不到24个小时),而且用在表示在2个事件之间经过的时间或时间间隔(它可以是比24个小时大些,或甚至是负值)。
你能用多中格式指定TIME值:
'HH:MM:SS'格式的一个字符串。“宽松”的语法被允许--任何标点符号可用作时间部分的分隔符,例如,'10:11:12'和'10.11.12'是等价的。
'HHMMSS'格式的一个字符串,如果它作为一个时间解释。例如,'101112'被理解为'10:11:12',但是'109712'是不合法的(它有无意义的分钟部分)并变成'00:00:00'。
HHMMSS格式的一个数字,如果它能解释为一个时间。例如,101112被理解为'10:11:12'。
TIME上下文接受的函数,例如CURRENT_TIME。
对于作为包括一个时间分隔符的字符串被指定的TIME值,不必为小于10的小时、分钟或秒值指定2位数字,'8:3:2'与'08:03:02'是一样的。
将“短的”TIME值赋值给一个TIME行列是要格外小心。MySQL使用最右位代表秒的假设来解释值。(MySQL将TIME值解释为经过的时间,而非作为一天的时间
)例如,你可能想到'11:12'、'1112'和1112意味着'11:12:00'(11点12分),但是MySQL解释他们为'00:11:12'(11分12秒)。同样,'12'和12被解释为'00:00:12'。
但是超出TIME范围之外的值是样合法的,它被剪切到范围适当的端点值。例如,'-850:00:00'和'850:00:00'被变换到'-838:59:59'和'838:59:59'。
不合法的TIME值被变换到'00:00:00'。注意,既然'00:00:00'本身是一个合法的TIME值,没有其他方法区分表中存储的一个'00:00:00'值,原来的值是否被指定为'00:00:00'或它是否是不合法的。
YEAR类型YEAR类型是一个 1 字节类型用于表示年份。
MySQL检索并且以YYYY格式显示YEAR值,其范围是1901到2155。
你能用多种格式指定YEAR值:
'1901'到'2155'范围的一个4位字符串。 1901到2155范围的一个4位数字。 '00'到'99'范围的一个2位字符串.在'00'到'69'和'70'到'99'范围的值被变换到在2000到2069范围和1970到1999的YEAR值。1到99范围的一个2位数字。在范围1到69和70到99的值被变换到在范围2001到2069和1970到1999的YEAR的值。注意对于2位数字的范围略微不同于2位数字字符串的范围,因为你不能直接指定零作为一个数字并且把它解释为2000。你必须作为一个字符串'0'或'00'指定它,它将被解释为0000。
YEAR上下文环境中接受的函数,例如NOW()。
不合法YEAR值被变换到0000。
字符串类型是CHAR、VARCHAR、BLOB、TEXT、ENUM和SET。
CHAR和VARCHAR类型CHAR和VARCHAR类型是类似的,但是在他们被存储和检索的方式不同。
一个CHAR列的长度被修正为在你创造表时你所声明的长度。长度可以是1和255之间的任何值。(在MySQL
3.23中,CHAR长度可以是0~255。) 当CHAR值被存储时,他们被用空格在右边填补到指定的长度。当CHAR值被检索时,拖后的空格被删去。
在VARCHAR列中的值是变长字符串。你可以声明一个VARCHAR列是在1和255之间的任何长度,就像对CHAR列。然而,与CHAR相反,VARCHAR值只存储所需的字符,外加一个字节记录长度,值不被填补;相反,当值被存储时,拖后的空格被删去。(这个空格删除不同于ANSI
SQL规范。)
如果你把一个超过列最大长度的值赋给一个CHAR或VARCHAR列,值被截断以适合它。
下表显示了两种类型的列的不同,通过演示存储变长字符串值到CHAR(4)和VARCHAR(4)列:
| 值 | CHAR(4) |
存储需求 | VARCHAR(4) |
存储需求 |
'' |
' ' |
4 个字节 | '' |
1 字节 |
'ab' |
'ab ' |
4 个字节 | 'ab' |
3 个字节 |
'abcd' |
'abcd' |
4 个字节 | 'abcd' |
5 个字节 |
'abcdefgh' |
'abcd' |
4 个字节 | 'abcd' |
5 个字节 |
从CHAR(4)和VARCHAR(4)列检索的值在每种情况下都是一样的,因为拖后的空格从检索的CHAR列上被删除。
在CHAR和VARCHAR列中存储和比较值是以大小写不区分的方式进行的,除非当桌子被创建时,BINARY属性被指定。BINARY属性意味着该列的值根据MySQL服务器正在运行的机器的ASCII顺序以大小写区分的方式存储和比较。
BINARY属性是“粘性”的。这意味着,如果标记了BINARY的列用于一个表达式中,整个的表达式作为一个BINARY值被比较。
MySQL在表创建时可以隐含地改变一个CHAR或VARCHAR列的类型。见7.7.1 隐含的的列说明改变。
BLOB和TEXT类型一个BLOB是一个能保存可变数量的数据的二进制的大对象。4个BLOB类型TINYBLOB、BLOB、MEDIUMBLOB和LONGBLOB仅仅在他们能保存值的最大长度方面有所不同。见7.3.1 列类型存储需求。
4个TEXT类型TINYTEXT、TEXT、MEDIUMTEXT和LONGTEXT对应于4个BLOB类型,并且有同样的最大长度和存储需求。在BLOB和TEXT类型之间的唯一差别是对BLOB值的排序和比较以大小写敏感方式执行,而对TEXT值是大小写不敏感的。换句话说,一个TEXT是一个大小写不敏感的BLOB。
如果你把一个超过列类型最大长度的值赋给一个BLOB或TEXT列,值被截断以适合它。
在大多数方面,你可以认为一个TEXT行列是你所希望大的一个VARCHAR列。同样,你可以认为一个BLOB列是一个VARCHAR
BINARY列。差别是:
BLOB和TEXT列上索引。更旧的MySQL版本不支持这个。
BLOB和TEXT列没有拖后空格的删除,因为对VARCHAR列有删除。
BLOB和TEXT列不能有DEFAULT值。
MyODBC定义BLOB为LONGVARBINARY,TEXT值为LONGVARCHAR。
因为BLOB和TEXT值可以是非常长的,当使用他们时,你可能遇到一些限制:
BLOB或TEXT列上使用GROUP BY或ORDER
BY,你必须将列值变换成一个定长对象。这样做的标准方法是用SUBSTRING函数。例如:
mysql> select comment from tbl_name,substring(comment,20) as substr ORDER BY substr;
如果你不这样做,在排序时,只有列的首max_sort_length个字节被使用,缺省的max_sort_length是1024;这个值能在启动mysqld服务器时使用-O选择改变。你可以在包含BLOB或TEXT值得一个表达式上分组(group),通过指定列的位置或使用一个别名:
mysql> select id,substring(blob_col,1,100) from tbl_name
GROUP BY 2;
mysql> select id,substring(blob_col,1,100) as b from tbl_name
GROUP BY b;
BLOB或TEXT对象的最大尺寸由其类型决定,但是你能在客户与服务器之间是实际传输的最大值由可用的内存数量和通讯缓冲区的大小来决定。你能改变消息缓冲区大小,但是你必须在服务器和客户两端做。见10.2.3 调节服务器参数。 注意,每个BLOB或TEXT值内部由一个独立分配的对象表示。这与所有的其他列类型相反,它们是在打开表时,按列被分配一次存储。
ENUM类型一个ENUM是一个字符对象,其值通常从一个在表创建时明确被列举的允许值的一张表中选择。
在下列的某个情形下,值也可以空字符串("")或NULL:
ENUM(即,一个不在允许的值列表中的字符串),空字符串作为一个特殊错误的值被插入。
ENUM被声明为NULL,NULL也是列的合法值,并且缺省值是NULL。如果一个ENUM被声明为NOT
NULL,缺省值是允许值的列表的第一成员。 每枚举值有一个编号:
SELECT语句找出被赋给无效ENUM值的行:
mysql> SELECT * FROM tbl_name WHERE enum_col=0;
NULL值的编号是NULL。 例如,指定为ENUM("one", "two", "three")的列可以有显示在下面的值的任何一个。每个值的编号也被显示:
| 值 | 编号 |
NULL |
NULL |
"" |
0 |
"one" |
1 |
"two" |
2 |
"three" |
3 |
枚举可以有最大65535个成员。
当你把值赋给一个ENUM列时,字母的大小写是无关紧要的。然而,以后从列中检索的值大小写匹配在表创建时用来指定允许值的值的大小写。
如果你在一个数字的上下文环境中检索一个ENUM,列值的编号被返回。如果你存储一个数字到一个ENUM中,数字被当作一个标号,并且存储的值是该编号的枚举成员。
ENUM值根据列说明列举的枚举成员的次序被排序。(换句话说,ENUM值根据他们的编号数字被排序)
例如,对ENUM("a", "b"),"a"排在"b"前面,但是对ENUM("b",
"a"),"b"排在"a"前面。空字符串排序非空字符串之前,并且NULL排在所有其他枚举值之前。
如果你想要得到一个ENUM列的所有可能的值,你应该使用:SHOW
COLUMNS FROM table_name LIKE enum_column_name并且分析在第二列的ENUM定义。
SET类型一个SET是可以有零或多个值的一个字符串对象,其每一个必须从表创建造被指定了的允许值的一张列表中被选择。由多个集合成员组成的SET列通过由由逗号分隔(“,”)的成员被指定,其推论是该SET成员值不能包含逗号本身。
例如, 一个指定为SET("one", "two") NOT NULL的列可以有这些值的任何一个:
""
"one"
"two"
"one,two"
一个SET能有最多64个不同的成员。
MySQL用数字值存储SET值,存储值的低阶位对应于第一个集合成员。如果你在数字上下文中检索一个SET值,检索的值把位设置位对应组成列值的集合成员。如果一个数字被存储进一个SET列,在数字的二进制表示中设置的位决定了在列中的集合成员。假定一个列被指定为SET("a","b","c","d"),那么成员有下列位值:
SET 成员 |
十进制的值 | 二进制的值 |
a |
1 |
0001 |
b |
2 |
0010 |
c |
4 |
0100 |
d |
8 |
1000 |
如果你给该列赋值9,即二进制的1001,这样第一个和第四个SET值成员"a"和"d"被选择并且结果值是"a,d"。
对于包含超过一个SET成员的值,当你插入值时,无所谓以什么顺序列举值,也无所谓给定的值列举了多少次。当以后检索值时,在值中的每个成员将出现一次,根据他们在表创建时被指定的顺序列出成员。例如,如果列指定为SET("a","b","c","d"),那么"a,d"、"d,a"和"d,a,a,d,d"在检索时将均作为"a,d"出现。
SET值以数字次序被排序。NULL指排在非NULL
SET值之前。
通常,你使用LIKE操作符或FIND_IN_SET()函数执行在一个SET上的一个SELECT:
mysql> SELECT * FROM tbl_name WHERE set_col LIKE '%value%';
mysql> SELECT * FROM tbl_name WHERE FIND_IN_SET('value',set_col)>0;
但是下列也会工作:
mysql> SELECT * FROM tbl_name WHERE set_col = 'val1,val2'; mysql> SELECT * FROM tbl_name WHERE set_col & 1;
这些语句的第一个语句寻找一个精确的匹配。第二个寻找包含第一个集合成员的值。
如果你想要得到一个SET列的所有可能的值,你应该使用:SHOW
COLUMNS FROM table_name LIKE set_column_name并且分析在第二列的SET定义。
为了最有效地使用存储空间,试着在所有的情况下使用最精确的类型。例如,如果一个整数列被用于在之间1和99999的值,
MEDIUMINT UNSIGNED是最好的类型。
货币值的精确表示是一个常见的问题。在MySQL,你应该使用DECIMAL类型,它作为一个字符串被存储,不会发生精确性的损失。如果精确性不是太重要,DOUBLE类型也是足够好的。
对高精度,你总是能变换到以一个BIGINT存储的定点类型。这允许你用整数做所有的计算,并且仅在必要时将结果转换回浮点值。见10.6 选择一个表类型。
所有的MySQL列类型能被索引。在相关的列上的使用索引是改进SELECT操作性能的最好方法。
一个表最多可有16个索引。最大索引长度是256个字节,尽管这可以在编译MySQL时被改变。
对于CHAR和VARCHAR列,你可以索引列的前缀。这更快并且比索引整个列需要较少的磁盘空间。在CREATE
TABLE语句中索引列前缀的语法看起来像这样:
KEY index_name (col_name(length))
下面的例子为name列的头10个字符创建一个索引:
mysql> CREATE TABLE test (
name CHAR(200) NOT NULL,
KEY index_name (name(10)));
对于BLOB和TEXT列,你必须索引列的前缀,你不能索引列的全部。
MySQL能在多个列上创建索引。一个索引可以由最多15个列组成。(在CHAR和VARCHAR列上,你也可以使用列的前缀作为一个索引的部分)。
一个多重列索引可以认为是包含通过合并(concatenate)索引列值创建的值的一个排序数组。
当你为在一个WHERE子句索引的第一列指定已知的数量时,MySQL以这种方式使用多重列索引使得查询非常快速,即使你不为其他列指定值。
假定一张表使用下列说明创建:
mysql> CREATE TABLE test (
id INT NOT NULL,
last_name CHAR(30) NOT NULL,
first_name CHAR(30) NOT NULL,
PRIMARY KEY (id),
INDEX name (last_name,first_name));
那么索引name是一个在last_name和first_name上的索引,这个索引将被用于在last_name或last_name和first_name的一个已知范围内指定值的查询,因此,name索引将使用在下列查询中:
mysql> SELECT * FROM test WHERE last_name="Widenius";
mysql> SELECT * FROM test WHERE last_name="Widenius"
AND first_name="Michael";
mysql> SELECT * FROM test WHERE last_name="Widenius"
AND (first_name="Michael" OR first_name="Monty");
mysql> SELECT * FROM test WHERE last_name="Widenius"
AND first_name >="M" AND first_name < "N";
然而,name索引将不用在下列询问中:
mysql> SELECT * FROM test WHERE first_name="Michael";
mysql> SELECT * FROM test WHERE last_name="Widenius"
OR first_name="Michael";
关于MySQL使用索引改进性能的方式的更多的信息,见10.4 使用MySQL索引。
为了跟容易地使用为其他供应商的SQL实现编写的代码,下表显示了MySQL映射的列类型。这些映射使得从其他数据库引擎移动表定义到MySQL更容易:
| 其他供应商类型 | MySQL类型 |
BINARY(NUM) |
CHAR(NUM) BINARY |
CHAR VARYING(NUM) |
VARCHAR(NUM) |
FLOAT4 |
FLOAT |
FLOAT8 |
DOUBLE |
INT1 |
TINYINT |
INT2 |
SMALLINT |
INT3 |
MEDIUMINT |
INT4 |
INT |
INT8 |
BIGINT |
LONG VARBINARY |
MEDIUMBLOB |
LONG VARCHAR |
MEDIUMTEXT |
MIDDLEINT |
MEDIUMINT |
VARBINARY(NUM) |
VARCHAR(NUM) BINARY |
列类型映射发生在表创建时。如果你用其他供应商使用的类型创建表,那么发出一个DESCRIBE
tbl_name语句,MySQL使用等价的MySQL类型报告表结构。
SELECT和WHERE子句中的函数在一个SQL语句中的select_expression或where_definition可由使用下面描述的函数的任何表达式组成。
包含NULL的一个表达式总是产生一个NULL值,否则除非表达式所包含的操作符和函数在文档中说明。
注意:在一个函数名和跟随它的括号之间不许没有空格。这帮助MySQL分析器区分函数调用和具有相同名字的对表或列的引用,尽管允许在参数周围有空格。
为了简洁,例子以缩写形式显示从mysql程序输出。因此:
mysql> select MOD(29,9); 1 rows in set (0.00 sec) +-----------+ | mod(29,9) | +-----------+ | 2 | +-----------+
被显示为这样:
mysql> select MOD(29,9);
-> 2
( ... ) mysql> select 1+2*3;
-> 7
mysql> select (1+2)*3;
-> 9
一般的算术操作符是可用的。注意在-、+和*情况下,如果两个参数是整数,结果用BIGINT(64位)精度计算!
+ mysql> select 3+5;
-> 8
- mysql> select 3-5;
-> -2
* mysql> select 3*5;
-> 15
mysql> select 18014398509481984*18014398509481984.0;
-> 324518553658426726783156020576256.0
mysql> select 18014398509481984*18014398509481984;
-> 0
/ mysql> select 3/5;
-> 0.60
被零除产生一个NULL结果:
mysql> select 102/(1-1);
-> NULL
MySQL为位操作使用BIGINT(64位)算法,因此这些操作符有最大64位的一个范围。
| mysql> select 29 | 15;
-> 31
& mysql> select 29 & 15;
-> 13
<< BIGINT)数字。 mysql> select 1 << 2
-> 4
>> BIGINT)数字。 mysql> select 4 >> 2
-> 1
~ mysql> select 5 & ~1
-> 4
BIT_COUNT(N) N设定的位的数量。 mysql> select BIT_COUNT(29);
-> 4
所有的逻辑函数返回1(TRUE)或0(FALSE)。
NOT ! 0,返回1,否则返回0。例外:
NOT NULL返回NULL。 mysql> select NOT 1;
-> 0
mysql> select NOT NULL;
-> NULL
mysql> select ! (1+1);
-> 0
mysql> select ! 1+1;
-> 1
最后的例子返回1,因为表达式作为(!1)+1计算。
OR || 0并且不NULL,返回1。
mysql> select 1 || 0;
-> 1
mysql> select 0 || 0;
-> 0
mysql> select 1 || NULL;
-> 1
AND && 0或NULL,返回0,否则返回1。
mysql> select 1 && NULL;
-> 0
mysql> select 1 && 0;
-> 0
比较操作得出值1(TRUE)、0(FALSE)或NULL等结果。这些函数工作运用在数字和字符串上。当需要时,字符串自动地被变换到数字且数字到字符串(如在Perl)。
MySQL使用下列规则执行比较:
NULL,比较的结果是NULL,除了<=>操作符。
TIMESTAMP或DATETIME列而其他参数是一个常数,在比较执行前,常数被转换为一个时间标记。这样做是为了对ODBC更友好。
缺省地,字符串使用当前的字符集以大小写敏感的方式进行(缺省为ISO-8859-1 Latin1,它对英语运用得很出色)。
下面的例子演示了对于比较操作字符串到数字的转换:
mysql> SELECT 1 > '6x';
-> 0
mysql> SELECT 7 > '6x';
-> 1
mysql> SELECT 0 > 'x6';
-> 0
mysql> SELECT 0 = 'x6';
-> 1
= mysql> select 1 = 0;
-> 0
mysql> select '0' = 0;
-> 1
mysql> select '0.0' = 0;
-> 1
mysql> select '0.01' = 0;
-> 0
mysql> select '.01' = 0.01;
-> 1
<> != mysql> select '.01' <> '0.01';
-> 1
mysql> select .01 <> '0.01';
-> 0
mysql> select 'zapp' <> 'zappp';
-> 1
<= mysql> select 0.1 <= 2;
-> 1
< mysql> select 2 <= 2;
-> 1
>= mysql> select 2 >= 2;
-> 1
> mysql> select 2 > 2;
-> 0
<=> mysql> select 1 <=> 1, NULL <=> NULL, 1 <=> NULL;
-> 1 1 0
IS NULL IS NOT NULL NULL mysql> select 1 IS NULL, 0 IS NULL, NULL IS NULL:
-> 0 0 1
mysql> select 1 IS NOT NULL, 0 IS NOT NULL, NULL IS NOT NULL;
expr BETWEEN min AND max expr对大于或等于min且expr是小于或等于max,BETWEEN返回1,否则它返回0。如果所有的参数类型是一样得,这等价于表达式(min
<= expr AND expr <= max)。第一个参数(expr)决定比较如何被执行。如果expr是一个大小写不敏感的字符串表达式,进行一个大小写不敏感的字符串比较。如果expr是一个大小写敏感的字符串表达式,进行一个大小写敏感的字符串比较。如果expr是一个整数表达式,进行整数比较。否则,进行一个浮点(实数)比较。
mysql> select 1 BETWEEN 2 AND 3;
-> 0
mysql> select 'b' BETWEEN 'a' AND 'c';
-> 1
mysql> select 2 BETWEEN 2 AND '3';
-> 1
mysql> select 2 BETWEEN 2 AND 'x-3';
-> 0
expr IN (value,...) expr是在IN表中的任何值,返回1,否则返回0。如果所有的值是常数,那么所有的值根据expr类型被计算和排序,然后项目的搜索是用二进制的搜索完成。这意味着如果IN值表全部由常数组成,IN是很快的。如果expr是一个大小写敏感的字符串表达式,字符串比较以大小写敏感方式执行。
mysql> select 2 IN (0,3,5,'wefwf');
-> 0
mysql> select 'wefwf' IN (0,3,5,'wefwf');
-> 1
expr NOT IN (value,...) NOT (expr IN (value,...))相同。 ISNULL(expr) expr是NULL,ISNULL()返回1,否则它返回0。
mysql> select ISNULL(1+1);
-> 0
mysql> select ISNULL(1/0);
-> 1
COALESCE(list) NULL的单元。 mysql> select COALESCE(NULL,1);
-> 1
mysql> select COALESCE(NULL,NULL,NULL);
-> NULL
INTERVAL(N,N1,N2,N3,...) N< N1,返回0,如果N<
N2,返回1等等。所有的参数被当作整数。为了函数能正确地工作,它要求N1<N2<N3<
...<Nn。这是因为使用二进制搜索(很快)。 mysql> select INTERVAL(23, 1, 15, 17, 30, 44, 200);
-> 3
mysql> select INTERVAL(10, 1, 10, 100, 1000);
-> 2
mysql> select INTERVAL(22, 23, 30, 44, 200);
-> 0
通常,如果在字符串比较中的任何表达式是区分大小写的,比较以大小写敏感的方式执行。
expr LIKE pat [ESCAPE 'escape-char'] 1(TRUE)或0(FALSE)。用LIKE,你可以在模式中使用下列2个通配符字符:
% |
匹配任何数目的字符,甚至零个字符 |
_ |
精确匹配一个字符 |
mysql> select 'David!' LIKE 'David_';
-> 1
mysql> select 'David!' LIKE '%D%v%';
-> 1
为了测试一个通配符的文字实例,用转义字符的加在字符前面。如果你不指定ESCAPE字符,假定为“\”:
\% |
匹配一%字符 |
\_ |
匹配一_字符 |
mysql> select 'David!' LIKE 'David\_';
-> 0
mysql> select 'David_' LIKE 'David\_';
-> 1
为了指定一个不同的转义字符,使用ESCAPE子句:
mysql> select 'David_' LIKE 'David|_' ESCAPE '|';
-> 1
LIKE允许用在数字的表达式上!(这是MySQL对ANSI
SQL LIKE的一个扩充。)
mysql> select 10 LIKE '1%';
-> 1
注意:因为MySQL在字符串中使用C转义语法(例如,“\n”),你必须在你的LIKE字符串中重复任何“\”。例如,为了查找“\n”,指定它为“
\\n”,为了查找“\”,指定它为“\\\\”(反斜线被分析器剥去一次,另一次是在模式匹配完成时,留下一条单独的反斜线被匹配)。
expr NOT LIKE pat [ESCAPE 'escape-char'] NOT (expr LIKE pat [ESCAPE 'escape-char'])相同。
expr REGEXP pat expr RLIKE pat expr对一个模式pat的模式匹配。模式可以是一个扩充的正则表达式。见MySQL 正则表达式句法的 H 描述.如果expr匹配pat,返回1,否则返回0。RLIKE是REGEXP的一个同义词,提供了与mSQL的兼容性。注意:因为MySQL在字符串中使用C转义语法(例如,“\n”),
你必须在你的REGEXP字符串重复任何“\”。在MySQL3.23.4中,REGEXP对于正常的(不是二进制)字符串是忽略大小写。
mysql> select 'Monty!' REGEXP 'm%y%%';
-> 0
mysql> select 'Monty!' REGEXP '.*';
-> 1
mysql> select 'new*\n*line' REGEXP 'new\\*.\\*line';
-> 1
mysql> select "a" REGEXP "A", "a" REGEXP BINARY "A";
-> 1 0
REGEXP和RLIKE使用当前的字符集(缺省为ISO-8859-1
Latin1)。 expr NOT REGEXP pat expr NOT RLIKE pat NOT (expr REGEXP pat)相同。 STRCMP(expr1,expr2) STRCMP()回来0,如果第一参数根据当前的排序次序小于第二个,返回-1,否则返回1。
mysql> select STRCMP('text', 'text2');
-> -1
mysql> select STRCMP('text2', 'text');
-> 1
mysql> select STRCMP('text', 'text');
-> 0
BINARY BINARY操作符强制跟随它后面的字符串为一个二进制字符串。即使列没被定义为BINARY或BLOB,这是一个强制列比较区分大小写的简易方法。
mysql> select "a" = "A";
-> 1
mysql> select BINARY "a" = "A";
-> 0
BINARY在MySQL 3.23.0中被引入。
IFNULL(expr1,expr2) expr1不是NULL,IFNULL()返回expr1,否则它返回expr2。IFNULL()返回一个数字或字符串值,取决于它被使用的上下文环境。
mysql> select IFNULL(1,0);
-> 1
mysql> select IFNULL(0,10);
-> 0
mysql> select IFNULL(1/0,10);
-> 10
mysql> select IFNULL(1/0,'yes');
-> 'yes'
IF(expr1,expr2,expr3) expr1是TRUE(expr1<>0且expr1<>NULL),那么IF()返回expr2,否则它返回expr3。IF()返回一个数字或字符串值,取决于它被使用的上下文。
mysql> select IF(1>2,2,3);
-> 3
mysql> select IF(1<2,'yes','no');
-> 'yes'
mysql> select IF(strcmp('test','test1'),'yes','no');
-> 'no'
expr1作为整数值被计算,它意味着如果你正在测试浮点或字符串值,你应该使用一个比较操作来做。
mysql> select IF(0.1,1,0);
-> 0
mysql> select IF(0.1<>0,1,0);
-> 1
在上面的第一种情况中,IF(0.1)返回0,因为0.1被变换到整数值,
导致测试IF(0)。这可能不是你期望的。在第二种情况中,比较测试原来的浮点值看它是否是非零,比较的结果被用作一个整数。
CASE value WHEN [compare-value] THEN result [WHEN [compare-value] THEN result ...]
[ELSE result] END CASE WHEN [condition] THEN result [WHEN [condition] THEN result ...] [ELSE result]
END result,其中value=compare-value。第二个版本中如果第一个条件为真,返回result。如果没有匹配的result值,那么结果在ELSE后的result被返回。如果没有ELSE部分,那么NULL被返回。
mysql> SELECT CASE 1 WHEN 1 THEN "one" WHEN 2 THEN "two" ELSE "more" END;
-> "one"
mysql> SELECT CASE WHEN 1>0 THEN "true" ELSE "false" END;
-> "true"
mysql> SELECT CASE BINARY "B" when "a" then 1 when "b" then 2 END;
-> NULL
所有的数学函数在一个出错的情况下返回NULL。
- mysql> select - 2;
注意,如果这个操作符与一个BIGINT使用,返回值是一个BIGINT!这意味着你应该避免在整数上使用-,那可能有值-2^63!
ABS(X) X的绝对值。 mysql> select ABS(2);
-> 2
mysql> select ABS(-32);
-> 32
SIGN(X) -1、0或1,取决于X是否是负数、零或正数。
mysql> select SIGN(-32);
-> -1
mysql> select SIGN(0);
-> 0
mysql> select SIGN(234);
-> 1
MOD(N,M) % %操作符)。返回N被M除的余数。
mysql> select MOD(234, 10);
-> 4
mysql> select 253 % 7;
-> 1
mysql> select MOD(29,9);
-> 2
这个函数可安全用于BIGINT值。
FLOOR(X) X的最大整数值。 mysql> select FLOOR(1.23);
-> 1
mysql> select FLOOR(-1.23);
-> -2
注意返回值被变换为一个BIGINT!
CEILING(X) X的最小整数值。 mysql> select CEILING(1.23);
-> 2
mysql> select CEILING(-1.23);
-> -1
ROUND(X) X的四舍五入的一个整数。 mysql> select ROUND(-1.23);
-> -1
mysql> select ROUND(-1.58);
-> -2
mysql> select ROUND(1.58);
-> 2
ROUND(X,D) X的四舍五入的有D为小数的一个数字。如果D为0,结果将没有小数点或小数部分。
mysql> select ROUND(1.298, 1);
-> 1.3
mysql> select ROUND(1.298, 0);
-> 1
EXP(X) e(自然对数的底)的X次方。 mysql> select EXP(2);
-> 7.389056
mysql> select EXP(-2);
-> 0.135335
LOG(X) X的自然对数。 mysql> select LOG(2);
-> 0.693147
mysql> select LOG(-2);
-> NULL
LOG10(X) X的以10为底的对数。 mysql> select LOG10(2);
-> 0.301030
mysql> select LOG10(100);
-> 2.000000
mysql> select LOG10(-100);
-> NULL
POW(X,Y) POWER(X,Y) X的Y次幂。 mysql> select POW(2,2);
-> 4.000000
mysql> select POW(2,-2);
-> 0.250000
SQRT(X) X的平方根。 mysql> select SQRT(4);
-> 2.000000
mysql> select SQRT(20);
-> 4.472136
PI() mysql> select PI();
-> 3.141593
COS(X) X的余弦, 在这里X以弧度给出。 mysql> select COS(PI());
-> -1.000000
SIN(X) X的正弦值,在此X以弧度给出。 mysql> select SIN(PI());
-> 0.000000
TAN(X) X的正切值,在此X以弧度给出。 mysql> select TAN(PI()+1);
-> 1.557408
ACOS(X) X反余弦,即其余弦值是X。如果X不在-1到1的范围,返回NULL。
mysql> select ACOS(1);
-> 0.000000
mysql> select ACOS(1.0001);
-> NULL
mysql> select ACOS(0);
-> 1.570796
ASIN(X) X反正弦值,即其正弦值是X。L如果X不在-1到1的范围,返回NULL。
mysql> select ASIN(0.2);
-> 0.201358
mysql> select ASIN('foo');
-> 0.000000
ATAN(X) X的反正切值,即其正切值是X。 mysql> select ATAN(2);
-> 1.107149
mysql> select ATAN(-2);
-> -1.107149
ATAN2(X,Y) X和Y的反正切。它类似于计算Y/X的反正切,除了两个参数的符号被用来决定结果的象限。
mysql> select ATAN(-2,2);
-> -0.785398
mysql> select ATAN(PI(),0);
-> 1.570796
COT(X) X的余切。 mysql> select COT(12);
-> -1.57267341
mysql> select COT(0);
-> NULL
RAND() RAND(N) 0到1.0内的随机浮点值。如果一个整数参数N被指定,它被用作种子值。
mysql> select RAND();
-> 0.5925
mysql> select RAND(20);
-> 0.1811
mysql> select RAND(20);
-> 0.1811
mysql> select RAND();
-> 0.2079
mysql> select RAND();
-> 0.7888
你不能在一个ORDER BY子句用RAND()值使用列,因为ORDER
BY将重复计算列多次。然而在MySQL3.23中,你可以做:
SELECT * FROM table_name ORDER BY RAND(),这是有利于得到一个来自SELECT
* FROM table1,table2 WHERE a=b AND c<d ORDER BY RAND() LIMIT 1000的集合的随机样本。注意在一个WHERE子句里的一个RAND()将在每次WHERE被执行时重新评估。
LEAST(X,Y,...) INTEGER上下文,或所有的参数都是整数值,他们作为整数比较。
REAL上下文,或所有的参数是实数值,他们作为实数比较。
mysql> select LEAST(2,0);
-> 0
mysql> select LEAST(34.0,3.0,5.0,767.0);
-> 3.0
mysql> select LEAST("B","A","C");
-> "A"
GREATEST(X,Y,...) LEAST一样的规则进行比较。
mysql> select GREATEST(2,0);
-> 2
mysql> select GREATEST(34.0,3.0,5.0,767.0);
-> 767.0
mysql> select GREATEST("B","A","C");
-> "C"
在MySQL在 3.22.5 以前的版本, 你能使用MAX()而不是GREATEST.
DEGREES(X) X,从弧度变换为角度。 mysql> select DEGREES(PI());
-> 180.000000
RADIANS(X) X,从角度变换为弧度。 mysql> select RADIANS(90);
-> 1.570796
TRUNCATE(X,D) X,截断为D位小数。如果D为0,结果将没有小数点或小数部分。
mysql> select TRUNCATE(1.223,1);
-> 1.2
mysql> select TRUNCATE(1.999,1);
-> 1.9
mysql> select TRUNCATE(1.999,0);
-> 1
如果结果的长度大于服务器参数max_allowed_packet,字符串值函数返回NULL。见10.2.3 调节服务器参数。
对于针对字符串位置的操作,第一个位置被标记为1。
ASCII(str) str的最左面字符的ASCII代码值。如果str是空字符串,返回0。如果str是NULL,返回NULL。
mysql> select ASCII('2');
-> 50
mysql> select ASCII(2);
-> 50
mysql> select ASCII('dx');
-> 100
ORD(str) ((first
byte ASCII code)*256+(second byte ASCII code))[*256+third byte ASCII code...]返回字符的ASCII代码值来返回多字节字符代码。如果最左面的字符不是一个多字节字符。返回与ASCII()函数返回的相同值。mysql> select ORD('2');
-> 50
CONV(N,from_base,to_base) N的字符串数字,从from_base基变换为to_base基,如果任何参数是NULL,返回NULL。参数N解释为一个整数,但是可以指定为一个整数或一个字符串。最小基是2且最大的基是36。如果to_base是一个负数,N被认为是一个有符号数,否则,N被当作无符号数。
CONV以64位点精度工作。 mysql> select CONV("a",16,2);
-> '1010'
mysql> select CONV("6E",18,8);
-> '172'
mysql> select CONV(-17,10,-18);
-> '-H'
mysql> select CONV(10+"10"+'10'+0xa,10,10);
-> '40'
BIN(N) N的一个字符串表示,在此N是一个长整数(BIGINT)数字,这等价于CONV(N,10,2)。如果N是NULL,返回NULL。
mysql> select BIN(12);
-> '1100'
OCT(N) N的一个字符串的表示,在此N是一个长整型数字,这等价于CONV(N,10,8)。如果N是NULL,返回NULL。
mysql> select OCT(12);
-> '14'
HEX(N) N一个字符串的表示,在此N是一个长整型(BIGINT)数字,这等价于CONV(N,10,16)。如果N是NULL,返回NULL。
mysql> select HEX(255);
-> 'FF'
CHAR(N,...) CHAR()将参数解释为整数并且返回由这些整数的ASCII代码字符组成的一个字符串。NULL值被跳过。
mysql> select CHAR(77,121,83,81,'76');
-> 'MySQL'
mysql> select CHAR(77,77.3,'77.3');
-> 'MMM'
CONCAT(str1,str2,...) NULL,返回NULL。可以有超过2个的参数。一个数字参数被变换为等价的字符串形式。
mysql> select CONCAT('My', 'S', 'QL');
-> 'MySQL'
mysql> select CONCAT('My', NULL, 'QL');
-> NULL
mysql> select CONCAT(14.3);
-> '14.3'
LENGTH(str) OCTET_LENGTH(str) CHAR_LENGTH(str) CHARACTER_LENGTH(str) str的长度。 mysql> select LENGTH('text');
-> 4
mysql> select OCTET_LENGTH('text');
-> 4
LOCATE(substr,str) POSITION(substr IN str) substr在字符串str第一个出现的位置,如果substr不是在str里面,返回0.
mysql> select LOCATE('bar', 'foobarbar');
-> 4
mysql> select LOCATE('xbar', 'foobar');
-> 0
该函数是多字节可靠的。
LOCATE(substr,str,pos) substr在字符串str第一个出现的位置,从位置pos开始。如果substr不是在str里面,返回0。mysql> select LOCATE('bar', 'foobarbar',5);
-> 7
INSTR(str,substr) substr在字符串str中的第一个出现的位置。这与有2个参数形式的LOCATE()相同,除了参数被颠倒。
mysql> select INSTR('foobarbar', 'bar');
-> 4
mysql> select INSTR('xbar', 'foobar');
-> 0
LPAD(str,len,padstr) str,左面用字符串padstr填补直到str是len个字符长。
mysql> select LPAD('hi',4,'??');
-> '??hi'
RPAD(str,len,padstr) str,右面用字符串padstr填补直到str是len个字符长。
mysql> select RPAD('hi',5,'?');
-> 'hi???'
LEFT(str,len) str的最左面len个字符。mysql> select LEFT('foobarbar', 5);
-> 'fooba'
RIGHT(str,len) str的最右面len个字符。 mysql> select RIGHT('foobarbar', 4);
-> 'rbar'
SUBSTRING(str,pos,len) SUBSTRING(str FROM pos FOR len) MID(str,pos,len) str返回一个len个字符的子串,从位置pos开始。使用FROM的变种形式是ANSI
SQL92语法。 mysql> select SUBSTRING('Quadratically',5,6);
-> 'ratica'
SUBSTRING(str,pos) SUBSTRING(str FROM pos) str的起始位置pos返回一个子串。 mysql> select SUBSTRING('Quadratically',5);
-> 'ratically'
mysql> select SUBSTRING('foobarbar' FROM 4);
-> 'barbar'
SUBSTRING_INDEX(str,delim,count) str的第count个出现的分隔符delim之后的子串。如果count是正数,返回最后的分隔符到左边(从左边数)
的所有字符。如果count是负数,返回最后的分隔符到右边的所有字符(从右边数)。
mysql> select SUBSTRING_INDEX('www.mysql.com', '.', 2);
-> 'www.mysql'
mysql> select SUBSTRING_INDEX('www.mysql.com', '.', -2);
-> 'mysql.com'
LTRIM(str) str。 mysql> select LTRIM(' barbar');
-> 'barbar'
RTRIM(str) str。 mysql> select RTRIM('barbar ');
-> 'barbar'
该函数对多字节是可靠的。
TRIM([[BOTH | LEADING | TRAILING] [remstr] FROM] str) str,其所有remstr前缀或后缀被删除了。如果没有修饰符BOTH、LEADING或TRAILING给出,BOTH被假定。如果remstr没被指定,空格被删除。
mysql> select TRIM(' bar ');
-> 'bar'
mysql> select TRIM(LEADING 'x' FROM 'xxxbarxxx');
-> 'barxxx'
mysql> select TRIM(BOTH 'x' FROM 'xxxbarxxx');
-> 'bar'
mysql> select TRIM(TRAILING 'xyz' FROM 'barxxyz');
-> 'barx'
SOUNDEX(str) str的一个同音字符串。听起来“大致相同”的2个字符串应该有相同的同音字符串。一个“标准”的同音字符串长是4个字符,但是SOUNDEX()函数返回一个任意长的字符串。你可以在结果上使用SUBSTRING()得到一个“标准”的
同音串。所有非数字字母字符在给定的字符串中被忽略。所有在A-Z之外的字符国际字母被当作元音。
mysql> select SOUNDEX('Hello');
-> 'H400'
mysql> select SOUNDEX('Quadratically');
-> 'Q36324'
SPACE(N) N个空格字符组成的一个字符串。 mysql> select SPACE(6);
-> ' '
REPLACE(str,from_str,to_str) str,其字符串from_str的所有出现由字符串to_str代替。
mysql> select REPLACE('www.mysql.com', 'w', 'Ww');
-> 'WwWwWw.mysql.com'
REPEAT(str,count) countTimes次的字符串str组成的一个字符串。如果count
<= 0,返回一个空字符串。如果str或count是NULL,返回NULL。
mysql> select REPEAT('MySQL', 3);
-> 'MySQLMySQLMySQL'
REVERSE(str) str。 mysql> select REVERSE('abc');
-> 'cba'
INSERT(str,pos,len,newstr) str,在位置pos起始的子串且len个字符长得子串由字符串newstr代替。
mysql> select INSERT('Quadratic', 3, 4, 'What');
-> 'QuWhattic'
ELT(N,str1,str2,str3,...) N= 1,返回str1,如果N= 2,返回str2,等等。如果N小于1或大于参数个数,返回NULL。ELT()是FIELD()反运算。
mysql> select ELT(1, 'ej', 'Heja', 'hej', 'foo');
-> 'ej'
mysql> select ELT(4, 'ej', 'Heja', 'hej', 'foo');
-> 'foo'
FIELD(str,str1,str2,str3,...) str在str1, str2, str3, ...清单的索引。如果str没找到,返回0。FIELD()是ELT()反运算。
mysql> select FIELD('ej', 'Hej', 'ej', 'Heja', 'hej', 'foo');
-> 2
mysql> select FIELD('fo', 'Hej', 'ej', 'Heja', 'hej', 'foo');
-> 0
FIND_IN_SET(str,strlist) str在由N子串组成的表strlist之中,返回一个1到N的值。一个字符串表是被“,”分隔的子串组成的一个字符串。如果第一个参数是一个常数字符串并且第二个参数是一种类型为SET的列,FIND_IN_SET()函数被优化而使用位运算!如果str不是在strlist里面或如果strlist是空字符串,返回0。如果任何一个参数是NULL,返回NULL。如果第一个参数包含一个“,”,该函数将工作不正常。
mysql> SELECT FIND_IN_SET('b','a,b,c,d');
-> 2
MAKE_SET(bits,str1,str2,...) bits集合中的的字符串组成。str1对应于位0,str2对应位1,等等。在str1,
str2, ...中的NULL串不添加到结果中。 mysql> SELECT MAKE_SET(1,'a','b','c');
-> 'a'
mysql> SELECT MAKE_SET(1 | 4,'hello','nice','world');
-> 'hello,world'
mysql> SELECT MAKE_SET(0,'a','b','c');
-> ''
EXPORT_SET(bits,on,off,[separator,[number_of_bits]]) mysql> select EXPORT_SET(5,'Y','N',',',4)
-> Y,N,Y,N
LCASE(str) LOWER(str) str,根据当前字符集映射(缺省是ISO-8859-1
Latin1)把所有的字符改变成小写。该函数对多字节是可靠的。 mysql> select LCASE('QUADRATICALLY');
-> 'quadratically'
UCASE(str) UPPER(str) str,根据当前字符集映射(缺省是ISO-8859-1
Latin1)把所有的字符改变成大写。该函数对多字节是可靠的。 mysql> select UCASE('Hej');
-> 'HEJ'
LOAD_FILE(file_name) max_allowed_packet。如果文件不存在或由于上面原因之一不能被读出,函数返回NULL。
mysql> UPDATE table_name
SET blob_column=LOAD_FILE("/tmp/picture")
WHERE id=1;
MySQL必要时自动变换数字为字符串,并且反过来也如此:
mysql> SELECT 1+"1";
-> 2
mysql> SELECT CONCAT(2,' test');
-> '2 test'
如果你想要明确地变换一个数字到一个字符串,把它作为参数传递到CONCAT()。
如果字符串函数提供一个二进制字符串作为参数,结果字符串也是一个二进制字符串。被变换到一个字符串的数字被当作是一个二进制字符串。这仅影响比较。
对于每个类型拥有的值范围以及并且指定日期何时间值的有效格式的描述见7.3.6 日期和时间类型。
这里是一个使用日期函数的例子。下面的查询选择了所有记录,其date_col的值是在最后30天以内:
mysql> SELECT something FROM table
WHERE TO_DAYS(NOW()) - TO_DAYS(date_col) <= 30;
DAYOFWEEK(date) date的星期索引(1=星期天,2=星期一,
……7=星期六)。这些索引值对应于ODBC标准。 mysql> select DAYOFWEEK('1998-02-03');
-> 3
WEEKDAY(date) date的星期索引(0=星期一,1=星期二,
……6= 星期天)。 mysql> select WEEKDAY('1997-10-04 22:23:00');
-> 5
mysql> select WEEKDAY('1997-11-05');
-> 2
DAYOFMONTH(date) date的月份中日期,在1到31范围内。
mysql> select DAYOFMONTH('1998-02-03');
-> 3
DAYOFYEAR(date) date在一年中的日数, 在1到366范围内。
mysql> select DAYOFYEAR('1998-02-03');
-> 34
MONTH(date) date的月份,范围1到12。 mysql> select MONTH('1998-02-03');
-> 2
DAYNAME(date) date的星期名字。 mysql> select DAYNAME("1998-02-05");
-> 'Thursday'
MONTHNAME(date) date的月份名字。 mysql> select MONTHNAME("1998-02-05");
-> 'February'
QUARTER(date) date一年中的季度,范围1到4。 mysql> select QUARTER('98-04-01');
-> 2
WEEK(date) WEEK(date,first) date的周数,范围在0到52。2个参数形式WEEK()允许你指定星期是否开始于星期天或星期一。如果第二个参数是0,星期从星期天开始,如果第二个参数是1,从星期一开始。
mysql> select WEEK('1998-02-20');
-> 7
mysql> select WEEK('1998-02-20',0);
-> 7
mysql> select WEEK('1998-02-20',1);
-> 8
YEAR(date) date的年份,范围在1000到9999。mysql> select YEAR('98-02-03');
-> 1998
HOUR(time) time的小时,范围是0到23。mysql> select HOUR('10:05:03');
-> 10
MINUTE(time) time的分钟,范围是0到59。mysql> select MINUTE('98-02-03 10:05:03');
-> 5
SECOND(time) time的秒数,范围是0到59。mysql> select SECOND('10:05:03');
-> 3
PERIOD_ADD(P,N) N个月到阶段P(以格式YYMM或YYYYMM)。以格式YYYYMM返回值。注意阶段参数P不是日期值。
mysql> select PERIOD_ADD(9801,2);
-> 199803
PERIOD_DIFF(P1,P2) P1和P2之间月数,P1和P2应该以格式YYMM或YYYYMM。注意,时期参数P1和P2不是日期值。
mysql> select PERIOD_DIFF(9802,199703);
-> 11
DATE_ADD(date,INTERVAL expr type) DATE_SUB(date,INTERVAL expr type) ADDDATE(date,INTERVAL expr type) SUBDATE(date,INTERVAL expr type) ADDDATE()和SUBDATE()是DATE_ADD()和DATE_SUB()的同义词。在MySQL
3.23中,你可以使用+和-而不是DATE_ADD()和DATE_SUB()。(见例子)date是一个指定开始日期的DATETIME或DATE值,expr是指定加到开始日期或从开始日期减去的间隔值一个表达式,expr是一个字符串;它可以以一个“-”开始表示负间隔。type是一个关键词,指明表达式应该如何被解释。EXTRACT(type
FROM date)函数从日期中返回“type”间隔。下表显示了type和expr参数怎样被关联:
type值 |
含义 | 期望的expr格式 |
SECOND |
秒 | SECONDS |
MINUTE |
分钟 | MINUTES |
HOUR |
时间 | HOURS |
DAY |
天 | DAYS |
MONTH |
月 | MONTHS |
YEAR |
年 | YEARS |
MINUTE_SECOND |
分钟和秒 | "MINUTES:SECONDS" |
HOUR_MINUTE |
小时和分钟 | "HOURS:MINUTES" |
DAY_HOUR |
天和小时 | "DAYS HOURS" |
YEAR_MONTH |
年和月 | "YEARS-MONTHS" |
HOUR_SECOND |
小时, 分钟, | "HOURS:MINUTES:SECONDS" |
DAY_MINUTE |
天, 小时, 分钟 | "DAYS HOURS:MINUTES" |
DAY_SECOND |
天, 小时, 分钟, 秒 | "DAYS HOURS:MINUTES:SECONDS" |
MySQL在expr格式中允许任何标点分隔符。表示显示的是建议的分隔符。如果date参数是一个DATE值并且你的计算仅仅包含YEAR、MONTH和DAY部分(即,没有时间部分),结果是一个DATE值。否则结果是一个DATETIME值。
mysql> SELECT "1997-12-31 23:59:59" + INTERVAL 1 SECOND;
-> 1998-01-01 00:00:00
mysql> SELECT INTERVAL 1 DAY + "1997-12-31";
-> 1998-01-01
mysql> SELECT "1998-01-01" - INTERVAL 1 SECOND;
-> 1997-12-31 23:59:59
mysql> SELECT DATE_ADD("1997-12-31 23:59:59",
INTERVAL 1 SECOND);
-> 1998-01-01 00:00:00
mysql> SELECT DATE_ADD("1997-12-31 23:59:59",
INTERVAL 1 DAY);
-> 1998-01-01 23:59:59
mysql> SELECT DATE_ADD("1997-12-31 23:59:59",
INTERVAL "1:1" MINUTE_SECOND);
-> 1998-01-01 00:01:00
mysql> SELECT DATE_SUB("1998-01-01 00:00:00",
INTERVAL "1 1:1:1" DAY_SECOND);
-> 1997-12-30 22:58:59
mysql> SELECT DATE_ADD("1998-01-01 00:00:00",
INTERVAL "-1 10" DAY_HOUR);
-> 1997-12-30 14:00:00
mysql> SELECT DATE_SUB("1998-01-02", INTERVAL 31 DAY);
-> 1997-12-02
mysql> SELECT EXTRACT(YEAR FROM "1999-07-02");
-> 1999
mysql> SELECT EXTRACT(YEAR_MONTH FROM "1999-07-02 01:02:03");
-> 199907
mysql> SELECT EXTRACT(DAY_MINUTE FROM "1999-07-02 01:02:03");
-> 20102
如果你指定太短的间隔值(不包括type关键词期望的间隔部分),MySQL假设你省掉了间隔值的最左面部分。例如,如果你指定一个type是DAY_SECOND,值expr被希望有天、小时、分钟和秒部分。如果你象"1:10"这样指定值,MySQL假设日子和小时部分是丢失的并且值代表分钟和秒。换句话说,"1:10"
DAY_SECOND以它等价于"1:10" MINUTE_SECOND的方式解释,这对那MySQL解释TIME值表示经过的时间而非作为一天的时间的方式有二义性。如果你使用确实不正确的日期,结果是NULL。如果你增加MONTH、YEAR_MONTH或YEAR并且结果日期大于新月份的最大值天数,日子在新月用最大的天调整。
mysql> select DATE_ADD('1998-01-30', Interval 1 month);
-> 1998-02-28
注意,从前面的例子中词INTERVAL和type关键词不是区分大小写的。
TO_DAYS(date) date,返回一个天数(从0年的天数)。 mysql> select TO_DAYS(950501);
-> 728779
mysql> select TO_DAYS('1997-10-07');
-> 729669
FROM_DAYS(N) N,返回一个DATE值。 mysql> select FROM_DAYS(729669);
-> '1997-10-07'
DATE_FORMAT(date,format) format字符串格式化date值。下列修饰符可以被用在format字符串中:
%M |
月名字(January……December) |
%W |
星期名字(Sunday……Saturday) |
%D |
有英语前缀的月份的日期(1st, 2nd, 3rd,
等等。) |
%Y |
年, 数字, 4 位 |
%y |
年, 数字, 2 位 |
%a |
缩写的星期名字(Sun……Sat) |
%d |
月份中的天数, 数字(00……31) |
%e |
月份中的天数, 数字(0……31) |
%m |
月, 数字(01……12) |
%c |
月, 数字(1……12) |
%b |
缩写的月份名字(Jan……Dec) |
%j |
一年中的天数(001……366) |
%H |
小时(00……23) |
%k |
小时(0……23) |
%h |
小时(01……12) |
%I |
小时(01……12) |
%l |
小时(1……12) |
%i |
分钟, 数字(00……59) |
%r |
时间,12 小时(hh:mm:ss [AP]M) |
%T |
时间,24 小时(hh:mm:ss) |
%S |
秒(00……59) |
%s |
秒(00……59) |
%p |
AM或PM |
%w |
一个星期中的天数(0=Sunday ……6=Saturday ) |
%U |
星期(0……52), 这里星期天是星期的第一天 |
%u |
星期(0……52), 这里星期一是星期的第一天 |
%% |
一个文字“%”。 |
所有的其他字符不做解释被复制到结果中。
mysql> select DATE_FORMAT('1997-10-04 22:23:00', '%W %M %Y');
-> 'Saturday October 1997'
mysql> select DATE_FORMAT('1997-10-04 22:23:00', '%H:%i:%s');
-> '22:23:00'
mysql> select DATE_FORMAT('1997-10-04 22:23:00',
'%D %y %a %d %m %b %j');
-> '4th 97 Sat 04 10 Oct 277'
mysql> select DATE_FORMAT('1997-10-04 22:23:00',
'%H %k %I %r %T %S %w');
-> '22 22 10 10:23:00 PM 22:23:00 00 6'
TIME_FORMAT(time,format) DATE_FORMAT()函数一样使用,但是format字符串只能包含处理小时、分钟和秒的那些格式修饰符。其他修饰符产生一个NULL值或0。
CURDATE() CURRENT_DATE 'YYYY-MM-DD'或YYYYMMDD格式返回今天日期值,取决于函数是在一个字符串还是数字上下文被使用。
mysql> select CURDATE();
-> '1997-12-15'
mysql> select CURDATE() + 0;
-> 19971215
CURTIME() CURRENT_TIME 'HH:MM:SS'或HHMMSS格式返回当前时间值,取决于函数是在一个字符串还是在数字的上下文被使用。
mysql> select CURTIME();
-> '23:50:26'
mysql> select CURTIME() + 0;
-> 235026
NOW() SYSDATE() CURRENT_TIMESTAMP 'YYYY-MM-DD HH:MM:SS'或YYYYMMDDHHMMSS格式返回当前的日期和时间,取决于函数是在一个字符串还是在数字的上下文被使用。
mysql> select NOW();
-> '1997-12-15 23:50:26'
mysql> select NOW() + 0;
-> 19971215235026
UNIX_TIMESTAMP() UNIX_TIMESTAMP(date) '1970-01-01 00:00:00'GMT开始的秒数)。如果UNIX_TIMESTAMP()用一个date参数被调用,它返回从'1970-01-01
00:00:00' GMT开始的秒数值。date可以是一个DATE字符串、一个DATETIME字符串、一个TIMESTAMP或以YYMMDD或YYYYMMDD格式的本地时间的一个数字。
mysql> select UNIX_TIMESTAMP();
-> 882226357
mysql> select UNIX_TIMESTAMP('1997-10-04 22:23:00');
-> 875996580
当UNIX_TIMESTAMP被用于一个TIMESTAMP列,函数将直接接受值,没有隐含的“string-to-unix-timestamp”变换。
FROM_UNIXTIME(unix_timestamp) 'YYYY-MM-DD HH:MM:SS'或YYYYMMDDHHMMSS格式返回unix_timestamp参数所表示的值,取决于函数是在一个字符串还是或数字上下文中被使用。
mysql> select FROM_UNIXTIME(875996580);
-> '1997-10-04 22:23:00'
mysql> select FROM_UNIXTIME(875996580) + 0;
-> 19971004222300
FROM_UNIXTIME(unix_timestamp,format) format字符串格式化。format可以包含与DATE_FORMAT()函数列出的条目同样的修饰符。
mysql> select FROM_UNIXTIME(UNIX_TIMESTAMP(),
'%Y %D %M %h:%i:%s %x');
-> '1997 23rd December 03:43:30 x'
SEC_TO_TIME(seconds) seconds参数,变换成小时、分钟和秒,值以'HH:MM:SS'或HHMMSS格式化,取决于函数是在一个字符串还是在数字上下文中被使用。
mysql> select SEC_TO_TIME(2378);
-> '00:39:38'
mysql> select SEC_TO_TIME(2378) + 0;
-> 3938
TIME_TO_SEC(time) time参数,转换成秒。 mysql> select TIME_TO_SEC('22:23:00');
-> 80580
mysql> select TIME_TO_SEC('00:39:38');
-> 2378