目录
表达式可以在几个点中使用
SQL
语句,比如在
ORDER BY
或
HAVING
子句
SELECT
语句时,在
WHERE
一个条款
SELECT
,
DELETE
或
UPDATE
陈述,或
SET
陈述。
表达式可以使用文字值,列值,
NULL
内置函数,存储函数,用户定义函数和运算符
来编写
。
本章描述了在MySQL中编写表达式所允许的函数和运算符。
第24.2节“使用存储的例程”
和
第29.4节“向MySQL添加新函数”
中给出了编写存储函数和用户定义函数的说明。
。
有关
描述服务器如何解释对不同类型函数的引用的规则
,
请参见
第9.2.4节“函数名称解析和解析”
。
除非在特定函数或运算符的文档中另有说明,否则
包含的表达式
NULL
始终会生成一个
NULL
值。
默认情况下,函数名称和后面的括号之间不能有空格。 这有助于MySQL解析器区分函数调用和对恰好与函数同名的表或列的引用。 但是,允许使用函数参数周围的空格。
您可以通过使用该
--sql-mode=IGNORE_SPACE
选项
启动它来告诉MySQL服务器在函数名后面接受空格
。
(请参见
第5.1.11节“服务器SQL模式”
。)单个客户端程序可以使用
CLIENT_IGNORE_SPACE
选项for
来请求此行为
mysql_real_connect()
。
在任何一种情况下,所有函数名称都成为保留字。
为简洁起见,本章中的大多数示例都 以缩写形式 显示 mysql 程序 的输出 。 而不是以这种格式显示示例:
MySQL的> SELECT MOD(29,9);
+ ----------- +
| mod(29,9)|
+ ----------- +
| 2 |
+ ----------- +
1行(0.00秒)
使用此格式:
MySQL的> SELECT MOD(29,9);
- > 2
表12.1函数和操作符
名称 | 描述 |
---|---|
ABS() |
返回绝对值 |
ACOS() |
返回反余弦 |
ADDDATE() |
将时间值(间隔)添加到日期值 |
ADDTIME() |
添加时间 |
AES_DECRYPT() |
使用AES解密 |
AES_ENCRYPT() |
使用AES加密 |
AND
,
&&
|
逻辑和 |
ANY_VALUE() |
抑制ONLY_FULL_GROUP_BY值拒绝 |
ASCII() |
返回最左侧字符的数值 |
ASIN() |
返回圆弧正弦 |
= |
分配值(作为
SET
语句的
一部分
,或作为
语句中
SET
子句的
一部分
UPDATE
)
|
:= |
分配值 |
ASYMMETRIC_DECRYPT() |
使用私钥或公钥解密密文 |
ASYMMETRIC_DERIVE() |
从非对称密钥导出对称密钥 |
ASYMMETRIC_ENCRYPT() |
使用私钥或公钥加密明文 |
ASYMMETRIC_SIGN() |
从摘要生成签名 |
ASYMMETRIC_VERIFY() |
验证签名是否与摘要匹配 |
ATAN() |
返回反正切 |
ATAN2()
,
ATAN()
|
返回两个参数的反正切 |
AVG() |
返回参数的平均值 |
BENCHMARK() |
反复执行表达式 |
BETWEEN ... AND
... |
检查值是否在值范围内 |
BIN() |
返回包含数字的二进制表示的字符串 |
BIN_TO_UUID() |
将二进制UUID转换为字符串 |
BINARY |
将字符串转换为二进制字符串 |
BIT_AND() |
按位返回AND |
BIT_COUNT() |
返回设置的位数 |
BIT_LENGTH() |
以位为单位返回参数长度 |
BIT_OR() |
按位返回OR |
BIT_XOR() |
按位返回异或 |
& |
按位AND |
~ |
按位反转 |
| |
按位OR |
^ |
按位异或 |
CAN_ACCESS_COLUMN() |
限内部使用 |
CAN_ACCESS_DATABASE() |
限内部使用 |
CAN_ACCESS_TABLE() |
限内部使用 |
CAN_ACCESS_VIEW() |
限内部使用 |
CASE |
案例运营商 |
CAST() |
将值转换为特定类型 |
CEIL() |
返回不小于参数的最小整数值 |
CEILING() |
返回不小于参数的最小整数值 |
CHAR() |
返回传递的每个整数的字符 |
CHAR_LENGTH() |
返回参数中的字符数 |
CHARACTER_LENGTH() |
CHAR_LENGTH()的同义词 |
CHARSET() |
返回参数的字符集 |
COALESCE() |
返回第一个非NULL参数 |
COERCIBILITY() |
返回字符串参数的归类强制性值 |
COLLATION() |
返回字符串参数的排序规则 |
COMPRESS() |
将结果作为二进制字符串返回 |
CONCAT() |
返回连接字符串 |
CONCAT_WS() |
返回与分隔符连接 |
CONNECTION_ID() |
返回连接的连接ID(线程ID) |
CONV() |
转换不同数字基数之间的数字 |
CONVERT() |
将值转换为特定类型 |
CONVERT_TZ() |
从一个时区转换为另一个时区 |
COS() |
返回余弦 |
COT() |
归还余切 |
COUNT() |
返回返回的行数 |
COUNT(DISTINCT) |
返回许多不同值的计数 |
CRC32() |
计算循环冗余校验值 |
CREATE_ASYMMETRIC_PRIV_KEY() |
创建私钥 |
CREATE_ASYMMETRIC_PUB_KEY() |
创建公钥 |
CREATE_DH_PARAMETERS() |
生成共享DH密钥 |
CREATE_DIGEST() |
从字符串生成摘要 |
CUME_DIST() |
累积分配值 |
CURDATE() |
返回当前日期 |
CURRENT_DATE()
,
CURRENT_DATE
|
CURDATE()的同义词 |
CURRENT_ROLE() |
返回当前活动角色 |
CURRENT_TIME()
,
CURRENT_TIME
|
CURTIME()的同义词 |
CURRENT_TIMESTAMP()
,
CURRENT_TIMESTAMP
|
同义词NOW() |
CURRENT_USER()
,
CURRENT_USER
|
经过身份验证的用户名和主机名 |
CURTIME() |
返回当前时间 |
DATABASE() |
返回默认(当前)数据库名称 |
DATE() |
提取日期或日期时间表达式的日期部分 |
DATE_ADD() |
将时间值(间隔)添加到日期值 |
DATE_FORMAT() |
格式化日期指定 |
DATE_SUB() |
从日期中减去时间值(间隔) |
DATEDIFF() |
减去两个日期 |
DAY() |
DAYOFMONTH()的同义词 |
DAYNAME() |
返回工作日的名称 |
DAYOFMONTH() |
返回月中的某一天(0-31) |
DAYOFWEEK() |
返回参数的工作日索引 |
DAYOFYEAR() |
返回一年中的某一天(1-366) |
DECODE() |
解码使用ENCODE()加密的字符串 |
DEFAULT() |
返回表列的默认值 |
DEGREES() |
将弧度转换为度数 |
DENSE_RANK() |
其分区内当前行的排名,没有间隙 |
DES_DECRYPT() |
解密一个字符串 |
DES_ENCRYPT() |
加密字符串 |
DIV |
整数除法 |
/ |
分部运营商 |
ELT() |
返回索引号处的字符串 |
ENCODE() |
编码一个字符串 |
ENCRYPT() |
加密字符串 |
= |
平等的运营商 |
<=> |
NULL-safe等于运算符 |
EXP() |
提升到的力量 |
EXPORT_SET() |
返回一个字符串,使得对于值位中设置的每个位,您获得一个on字符串,并且对于每个未设置的位,您将获得一个关闭字符串 |
EXTRACT() |
提取部分日期 |
ExtractValue() |
使用XPath表示法从XML字符串中提取值 |
FIELD() |
后续参数中第一个参数的索引(位置) |
FIND_IN_SET() |
第二个参数中第一个参数的索引(位置) |
FIRST_VALUE() |
窗口框架第一行的参数值 |
FLOOR() |
返回不大于参数的最大整数值 |
FORMAT() |
返回格式化为指定小数位数的数字 |
FORMAT_BYTES() |
将字节数转换为带单位的值 |
FORMAT_PICO_TIME() |
将时间(皮秒)转换为单位值 |
FOUND_ROWS() |
对于带有LIMIT子句的SELECT,返回的行数没有LIMIT子句 |
FROM_BASE64() |
解码base64编码的字符串并返回结果 |
FROM_DAYS() |
将日期号码转换为日期 |
FROM_UNIXTIME() |
将Unix时间戳格式化为日期 |
GeomCollection() |
从几何构造几何集合 |
GeometryCollection() |
从几何构造几何集合 |
GET_DD_COLUMN_PRIVILEGES() |
限内部使用 |
GET_DD_CREATE_OPTIONS() |
限内部使用 |
GET_DD_INDEX_SUB_PART_LENGTH() |
限内部使用 |
GET_FORMAT() |
返回日期格式字符串 |
GET_LOCK() |
获取命名锁 |
> |
大于运营商 |
>= |
大于或等于运营商 |
GREATEST() |
返回最大的参数 |
GROUP_CONCAT() |
返回连接的字符串 |
GROUPING() |
区分超级聚合ROLLUP行与常规行 |
GTID_SUBSET() |
如果子集中的所有GTID也已设置,则返回true;否则返回true。 否则是假的。 |
GTID_SUBTRACT() |
返回集合中不在子集中的所有GTID。 |
HEX() |
十进制或字符串值的十六进制表示 |
HOUR() |
提取小时 |
ICU_VERSION() |
ICU库版本 |
IF() |
如果/ else构造 |
IFNULL() |
Null if / else构造 |
IN() |
检查值是否在一组值内 |
INET_ATON() |
返回IP地址的数值 |
INET_NTOA() |
从数值返回IP地址 |
INET6_ATON() |
返回IPv6地址的数值 |
INET6_NTOA() |
从数值返回IPv6地址 |
INSERT() |
在指定位置插入子字符串,直到指定的字符数 |
INSTR() |
返回第一次出现的子串的索引 |
INTERNAL_AUTO_INCREMENT() |
限内部使用 |
INTERNAL_AVG_ROW_LENGTH() |
限内部使用 |
INTERNAL_CHECK_TIME() |
限内部使用 |
INTERNAL_CHECKSUM() |
限内部使用 |
INTERNAL_DATA_FREE() |
限内部使用 |
INTERNAL_DATA_LENGTH() |
限内部使用 |
INTERNAL_DD_CHAR_LENGTH() |
限内部使用 |
INTERNAL_GET_COMMENT_OR_ERROR() |
限内部使用 |
INTERNAL_GET_VIEW_WARNING_OR_ERROR() |
限内部使用 |
INTERNAL_INDEX_COLUMN_CARDINALITY() |
限内部使用 |
INTERNAL_INDEX_LENGTH() |
限内部使用 |
INTERNAL_KEYS_DISABLED() |
限内部使用 |
INTERNAL_MAX_DATA_LENGTH() |
限内部使用 |
INTERNAL_TABLE_ROWS() |
限内部使用 |
INTERNAL_UPDATE_TIME() |
限内部使用 |
INTERVAL() |
返回小于第一个参数的参数的索引 |
IS |
针对布尔值测试值 |
IS_FREE_LOCK() |
命名锁是否免费 |
IS_IPV4() |
参数是否为IPv4地址 |
IS_IPV4_COMPAT() |
参数是否是IPv4兼容的地址 |
IS_IPV4_MAPPED() |
参数是否是IPv4映射地址 |
IS_IPV6() |
参数是否是IPv6地址 |
IS NOT |
针对布尔值测试值 |
IS NOT NULL |
NOT NULL值测试 |
IS NULL |
NULL值测试 |
IS_USED_LOCK() |
命名锁是否正在使用; 返回连接标识符,如果为true |
IS_UUID() |
参数是否是有效的UUID |
ISNULL() |
测试参数是否为NULL |
JSON_ARRAY() |
创建JSON数组 |
JSON_ARRAY_APPEND() |
将数据附加到JSON文档 |
JSON_ARRAY_INSERT() |
插入JSON数组 |
JSON_ARRAYAGG() |
将结果集作为单个JSON数组返回 |
-> |
评估路径后从JSON列返回值; 相当于JSON_EXTRACT()。 |
JSON_CONTAINS() |
JSON文档是否包含路径中的特定对象 |
JSON_CONTAINS_PATH() |
JSON文档是否包含路径中的任何数据 |
JSON_DEPTH() |
JSON文档的最大深度 |
JSON_EXTRACT() |
从JSON文档返回数据 |
->> |
在评估路径并取消引用结果后,从JSON列返回值; 相当于JSON_UNQUOTE(JSON_EXTRACT())。 |
JSON_INSERT() |
将数据插入JSON文档 |
JSON_KEYS() |
来自JSON文档的键数组 |
JSON_LENGTH() |
JSON文档中的元素数量 |
JSON_MERGE()
(已弃用8.0.3)
|
合并JSON文档,保留重复键。 JSON_MERGE_PRESERVE()的弃用词不再使用 |
JSON_MERGE_PATCH() |
合并JSON文档,替换重复键的值 |
JSON_MERGE_PRESERVE() |
合并JSON文档,保留重复键 |
JSON_OBJECT() |
创建JSON对象 |
JSON_OBJECTAGG() |
将结果集作为单个JSON对象返回 |
JSON_OVERLAPS() |
比较两个JSON文档,如果它们具有任何共同的键值对或数组元素,则返回TRUE(1),否则返回FALSE(0) |
JSON_PRETTY() |
以人类可读的格式打印JSON文档 |
JSON_QUOTE() |
引用JSON文档 |
JSON_REMOVE() |
从JSON文档中删除数据 |
JSON_REPLACE() |
替换JSON文档中的值 |
JSON_SCHEMA_VALID() |
根据JSON模式验证JSON文档; 如果文档针对模式进行验证,则返回TRUE / 1;否则返回FALSE / 0 |
JSON_SCHEMA_VALIDATION_REPORT() |
根据JSON模式验证JSON文档; 以JSON格式返回有关验证结果的报告,包括成功或失败以及失败原因 |
JSON_SEARCH() |
JSON文档中的值路径 |
JSON_SET() |
将数据插入JSON文档 |
JSON_STORAGE_FREE() |
在部分更新之后释放JSON列值的二进制表示内的空间 |
JSON_STORAGE_SIZE() |
用于存储JSON文档的二进制表示的空间 |
JSON_TABLE() |
将JSON表达式中的数据作为关系表返回 |
JSON_TYPE() |
JSON值的类型 |
JSON_UNQUOTE() |
取消引用JSON值 |
JSON_VALID() |
JSON值是否有效 |
LAG() |
行中滞后当前行的参数值 |
LAST_DAY |
返回参数的月份的最后一天 |
LAST_INSERT_ID() |
最后一次INSERT的AUTOINCREMENT列的值 |
LAST_VALUE() |
窗口框架最后一行的参数值 |
LCASE() |
LOWER()的同义词 |
LEAD() |
分区中行前导行的参数值 |
LEAST() |
返回最小的参数 |
LEFT() |
返回指定的最左边的字符数 |
<< |
左移 |
LENGTH() |
以字节为单位返回字符串的长度 |
< |
不到运营商 |
<= |
小于或等于运营商 |
LIKE |
简单的模式匹配 |
LineString() |
从Point值构造LineString |
LN() |
返回参数的自然对数 |
LOAD_FILE() |
加载指定的文件 |
LOCALTIME()
,
LOCALTIME
|
NOW()的同义词 |
LOCALTIMESTAMP
,
LOCALTIMESTAMP()
|
NOW()的同义词 |
LOCATE() |
返回第一次出现的子串的位置 |
LOG() |
返回第一个参数的自然对数 |
LOG10() |
返回参数的以10为底的对数 |
LOG2() |
返回参数的base-2对数 |
LOWER() |
以小写形式返回参数 |
LPAD() |
返回字符串参数,使用指定的字符串进行左填充 |
LTRIM() |
删除前导空格 |
MAKE_SET() |
返回一组以逗号分隔的字符串,这些字符串具有相应的位设置位 |
MAKEDATE() |
创建年份和年中的日期 |
MAKETIME() |
从小时,分钟,秒创建时间 |
MASTER_POS_WAIT() |
阻止,直到从站已读取并应用所有更新到指定位置 |
MATCH |
执行全文搜索 |
MAX() |
返回最大值 |
MBRContains() |
一个几何的MBR是否包含另一个几何的MBR |
MBRCoveredBy() |
一个MBR是否被另一个MBR覆盖 |
MBRCovers() |
一个MBR是否涵盖另一个MBR |
MBRDisjoint() |
两个几何形状的MBR是否不相交 |
MBREquals() |
两个几何的MBR是否相等 |
MBRIntersects() |
两个几何的MBR是否相交 |
MBROverlaps() |
两个几何的MBR是否重叠 |
MBRTouches() |
两种几何形状的MBR是否接触 |
MBRWithin() |
一个几何的MBR是否在另一个几何的MBR内 |
MD5() |
计算MD5校验和 |
MEMBER OF() |
如果第一个操作数匹配作为第二个操作数传递的JSON数组的任何元素,则返回true(1),否则返回false(0) |
MICROSECOND() |
从参数返回微秒 |
MID() |
返回从指定位置开始的子字符串 |
MIN() |
返回最小值 |
- |
减号运算符 |
MINUTE() |
从论证中返回分钟 |
MOD() |
归还剩下的 |
%
,
MOD
|
模数运算符 |
MONTH() |
从过去的日期返回月份 |
MONTHNAME() |
返回月份名称 |
MultiLineString() |
从LineString值构造MultiLineString |
MultiPoint() |
从Point值构造MultiPoint |
MultiPolygon() |
从Polygon值构造MultiPolygon |
NAME_CONST() |
导致列具有给定名称 |
NOT
,
!
|
否定价值 |
NOT BETWEEN
... AND ... |
检查值是否不在值范围内 |
!=
,
<>
|
不等于运营商 |
NOT IN() |
检查值是否不在一组值内 |
NOT LIKE |
简单模式匹配的否定 |
NOT REGEXP |
REGEXP的否定 |
NOW() |
返回当前日期和时间 |
NTH_VALUE() |
第N行窗口框架的参数值 |
NTILE() |
其分区中当前行的存储桶编号。 |
NULLIF() |
如果expr1 = expr2,则返回NULL |
OCT() |
返回包含数字的八进制表示的字符串 |
OCTET_LENGTH() |
LENGTH()的同义词 |
OR
,
||
|
逻辑或 |
ORD() |
返回参数最左侧字符的字符代码 |
PASSWORD() |
计算并返回密码字符串 |
PERCENT_RANK() |
百分比等级值 |
PERIOD_ADD() |
将期间添加到年 - 月 |
PERIOD_DIFF() |
返回句点之间的月数 |
PI() |
返回pi的值 |
+ |
加法运算符 |
Point() |
从坐标构造点 |
Polygon() |
从LineString参数构造多边形 |
POSITION() |
LOCATE()的同义词 |
POW() |
将引发的参数返回到指定的幂 |
POWER() |
将引发的参数返回到指定的幂 |
PS_CURRENT_THREAD_ID() |
当前线程的性能架构线程ID |
PS_THREAD_ID() |
给定线程的性能架构线程ID |
QUARTER() |
从日期参数返回季度 |
QUOTE() |
转义参数以在SQL语句中使用 |
RADIANS() |
返回参数转换为弧度 |
RAND() |
返回随机浮点值 |
RANDOM_BYTES() |
返回一个随机字节向量 |
RANK() |
其分区内当前行的排名,有差距 |
REGEXP |
string是否匹配正则表达式 |
REGEXP_INSTR() |
匹配正则表达式的子串的起始索引 |
REGEXP_LIKE() |
string是否匹配正则表达式 |
REGEXP_REPLACE() |
替换匹配正则表达式的子字符串 |
REGEXP_SUBSTR() |
返回子串匹配正则表达式 |
RELEASE_ALL_LOCKS() |
释放所有当前命名的锁 |
RELEASE_LOCK() |
释放命名锁 |
REPEAT() |
重复指定次数的字符串 |
REPLACE() |
替换指定字符串的出现次数 |
REVERSE() |
反转字符串中的字符 |
RIGHT() |
返回指定的最右边的字符数 |
>> |
右转 |
RLIKE |
string是否匹配正则表达式 |
ROLES_GRAPHML() |
返回表示内存角色子图的GraphML文档 |
ROUND() |
围绕论点 |
ROW_COUNT() |
行数已更新 |
ROW_NUMBER() |
其分区中当前行的数量 |
RPAD() |
追加指定次数的字符串 |
RTRIM() |
删除尾随空格 |
SCHEMA() |
DATABASE()的同义词 |
SEC_TO_TIME() |
将秒转换为'hh:mm:ss'格式 |
SECOND() |
返回秒(0-59) |
SESSION_USER() |
USER()的同义词 |
SHA1()
,
SHA()
|
计算SHA-1 160位校验和 |
SHA2() |
计算SHA-2校验和 |
SIGN() |
返回参数的符号 |
SIN() |
返回参数的正弦值 |
SLEEP() |
睡几秒钟 |
SOUNDEX() |
返回soundex字符串 |
SOUNDS LIKE |
比较声音 |
SPACE() |
返回指定数量的空格的字符串 |
SQRT() |
返回参数的平方根 |
ST_Area() |
返回Polygon或MultiPolygon区域 |
ST_AsBinary()
,
ST_AsWKB()
|
从内部几何格式转换为WKB |
ST_AsGeoJSON() |
从几何体生成GeoJSON对象 |
ST_AsText()
,
ST_AsWKT()
|
从内部几何格式转换为WKT |
ST_Buffer() |
返回距离几何体的给定距离内的点的几何 |
ST_Buffer_Strategy() |
为ST_Buffer()生成策略选项 |
ST_Centroid() |
返回质心作为一个点 |
ST_Contains() |
一个几何是否包含另一个 |
ST_ConvexHull() |
返回几何体的凸包 |
ST_Crosses() |
一个几何是否与另一个几何相交 |
ST_Difference() |
两个几何的返回点集差异 |
ST_Dimension() |
几何尺寸 |
ST_Disjoint() |
一个几何是否与另一个几何脱节 |
ST_Distance() |
一个几何与另一个几何的距离 |
ST_Distance_Sphere() |
两个几何形状之间的最小地球距离 |
ST_EndPoint() |
LineString的终点 |
ST_Envelope() |
返回几何的MBR |
ST_Equals() |
一个几何是否与另一个几何相等 |
ST_ExteriorRing() |
返回Polygon的外环 |
ST_GeoHash() |
产生geohash值 |
ST_GeomCollFromText()
,
ST_GeometryCollectionFromText()
,
ST_GeomCollFromTxt()
|
从WKT返回几何集合 |
ST_GeomCollFromWKB()
,
ST_GeometryCollectionFromWKB()
|
从WKB返回几何集合 |
ST_GeometryN() |
从几何集合中返回第N个几何 |
ST_GeometryType() |
返回几何类型的名称 |
ST_GeomFromGeoJSON() |
从GeoJSON对象生成几何 |
ST_GeomFromText()
,
ST_GeometryFromText()
|
从WKT返回几何 |
ST_GeomFromWKB()
,
ST_GeometryFromWKB()
|
从WKB返回几何 |
ST_InteriorRingN() |
返回Polygon的第N个内环 |
ST_Intersection() |
返回点设置两个几何的交集 |
ST_Intersects() |
一个几何是否与另一个相交 |
ST_IsClosed() |
几何是否封闭且简单 |
ST_IsEmpty() |
占位符功能 |
ST_IsSimple() |
几何是否简单 |
ST_IsValid() |
几何是否有效 |
ST_LatFromGeoHash() |
从geohash值返回纬度 |
ST_Latitude() |
返回Point的纬度 |
ST_Length() |
返回LineString的长度 |
ST_LineFromText()
,
ST_LineStringFromText()
|
从WKT构造LineString |
ST_LineFromWKB()
,
ST_LineStringFromWKB()
|
从WKB构造LineString |
ST_LongFromGeoHash() |
从geohash值返回经度 |
ST_Longitude() |
返回Point的经度 |
ST_MakeEnvelope() |
两点左右的矩形 |
ST_MLineFromText()
,
ST_MultiLineStringFromText()
|
从WKT构造MultiLineString |
ST_MLineFromWKB()
,
ST_MultiLineStringFromWKB()
|
从WKB构造MultiLineString |
ST_MPointFromText()
,
ST_MultiPointFromText()
|
从WKT构造MultiPoint |
ST_MPointFromWKB()
,
ST_MultiPointFromWKB()
|
从WKB构造MultiPoint |
ST_MPolyFromText()
,
ST_MultiPolygonFromText()
|
从WKT构造MultiPolygon |
ST_MPolyFromWKB()
,
ST_MultiPolygonFromWKB()
|
从WKB构造MultiPolygon |
ST_NumGeometries() |
返回几何集合中的几何数量 |
ST_NumInteriorRing()
,
ST_NumInteriorRings()
|
返回多边形内圈的数量 |
ST_NumPoints() |
返回LineString中的点数 |
ST_Overlaps() |
一个几何是否与另一个重叠 |
ST_PointFromGeoHash() |
将geohash值转换为POINT值 |
ST_PointFromText() |
从WKT构建点 |
ST_PointFromWKB() |
从WKB构造点 |
ST_PointN() |
从LineString返回第N个点 |
ST_PolyFromText()
,
ST_PolygonFromText()
|
从WKT构造多边形 |
ST_PolyFromWKB()
,
ST_PolygonFromWKB()
|
从WKB构造多边形 |
ST_Simplify() |
返回简化几何 |
ST_SRID() |
返回几何的空间参考系统ID |
ST_StartPoint() |
LineString的起始点 |
ST_SwapXY() |
交换X / Y坐标的返回参数 |
ST_SymDifference() |
返回点设置两个几何的对称差异 |
ST_Touches() |
一个几何是否接触另一个 |
ST_Transform() |
变换几何的坐标 |
ST_Union() |
返回点集两个几何的并集 |
ST_Validate() |
返回验证的几何体 |
ST_Within() |
一个几何是否在另一个之内 |
ST_X() |
返回Point的X坐标 |
ST_Y() |
返回Point的Y坐标 |
STATEMENT_DIGEST() |
计算语句摘要哈希值 |
STATEMENT_DIGEST_TEXT() |
计算规范化语句摘要 |
STD() |
返回人口标准差 |
STDDEV() |
返回人口标准差 |
STDDEV_POP() |
返回人口标准差 |
STDDEV_SAMP() |
返回样本标准差 |
STR_TO_DATE() |
将字符串转换为日期 |
STRCMP() |
比较两个字符串 |
SUBDATE() |
使用三个参数调用时DATE_SUB()的同义词 |
SUBSTR() |
返回指定的子字符串 |
SUBSTRING() |
返回指定的子字符串 |
SUBSTRING_INDEX() |
在指定的分隔符出现次数之前从字符串返回子字符串 |
SUBTIME() |
减去时间 |
SUM() |
归还总和 |
SYSDATE() |
返回函数执行的时间 |
SYSTEM_USER() |
USER()的同义词 |
TAN() |
返回参数的正切值 |
TIME() |
提取传递的表达式的时间部分 |
TIME_FORMAT() |
格式化为时间 |
TIME_TO_SEC() |
返回转换为秒的参数 |
TIMEDIFF() |
减去时间 |
* |
乘法运算符 |
TIMESTAMP() |
使用单个参数,此函数返回日期或日期时间表达式; 有两个参数,参数的总和 |
TIMESTAMPADD() |
在datetime表达式中添加间隔 |
TIMESTAMPDIFF() |
从日期时间表达式中减去间隔 |
TO_BASE64() |
返回转换为base-64字符串的参数 |
TO_DAYS() |
返回转换为days的日期参数 |
TO_SECONDS() |
返回自0年以来转换为秒的日期或日期时间参数 |
TRIM() |
删除前导和尾随空格 |
TRUNCATE() |
截断到指定的小数位数 |
UCASE() |
UPPER()的同义词 |
- |
更改参数的符号 |
UNCOMPRESS() |
解压缩压缩的字符串 |
UNCOMPRESSED_LENGTH() |
压缩前返回字符串的长度 |
UNHEX() |
返回包含数字的十六进制表示的字符串 |
UNIX_TIMESTAMP() |
返回Unix时间戳 |
UpdateXML() |
返回替换的XML片段 |
UPPER() |
转换为大写 |
USER() |
客户端提供的用户名和主机名 |
UTC_DATE() |
返回当前的UTC日期 |
UTC_TIME() |
返回当前的UTC时间 |
UTC_TIMESTAMP() |
返回当前的UTC日期和时间 |
UUID() |
返回通用唯一标识符(UUID) |
UUID_SHORT() |
返回整数值通用标识符 |
UUID_TO_BIN() |
将字符串UUID转换为二进制 |
VALIDATE_PASSWORD_STRENGTH() |
确定密码的强度 |
VALUES() |
定义INSERT期间要使用的值 |
VAR_POP() |
返回人口标准差异 |
VAR_SAMP() |
返回样本方差 |
VARIANCE() |
返回人口标准差异 |
VERSION() |
返回表示MySQL服务器版本的字符串 |
WAIT_FOR_EXECUTED_GTID_SET() |
等到给定的GTID在slave上执行。 |
WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS() |
等到给定的GTID在slave上执行。 |
WEEK() |
返回周数 |
WEEKDAY() |
返回工作日索引 |
WEEKOFYEAR() |
返回日期的日历周(1-53) |
WEIGHT_STRING() |
返回字符串的权重字符串 |
XOR |
逻辑异或 |
YEAR() |
回归年份 |
YEARWEEK() |
返回年份和星期 |
当操作符与不同类型的操作数一起使用时,会发生类型转换以使操作数兼容。 某些转换是隐式发生的。 例如,MySQL会根据需要自动将字符串转换为数字,反之亦然。
MySQL的>SELECT 1+'1';
- > 2 MySQL的>SELECT CONCAT(2,' test');
- >'2测试'
也可以使用该
CAST()
函数
显式地将数字转换为字符串
。
转换与
CONCAT()
函数
隐式发生,
因为它需要字符串参数。
MySQL的>SELECT 38.8, CAST(38.8 AS CHAR);
- > 38.8,'38 .8' MySQL的>SELECT 38.8, CONCAT(38.8);
- > 38.8,'38 .8'
有关隐式数字到字符串转换的字符集以及适用于
CREATE TABLE ... SELECT
语句的已
修改规则的信息,请参阅本节后面的内容
。
以下规则描述了比较操作的转换方式:
如果是一个或两个参数
NULL
,则比较的结果是
NULL
,除了
NULL
-safe
<=>
等式比较运算符。
因为
NULL <=>
NULL
,结果是真的。
无需转换。
如果比较操作中的两个参数都是字符串,则将它们作为字符串进行比较。
如果两个参数都是整数,则将它们作为整数进行比较。
如果不与数字进行比较,十六进制值将被视为二进制字符串。
如果其中一个参数是a
TIMESTAMP
或
DATETIME
列而另一个参数是常量,则在执行比较之前将常量转换为时间戳。
这样做是为了更友好的ODBC。
这不是针对参数的
IN()
。
为安全起见,在进行比较时始终使用完整的日期时间,日期或时间字符串。
例如,要在使用
BETWEEN
日期或时间值
时获得最佳结果
,请使用
CAST()
显式将值转换为所需的数据类型。
来自一个或多个表的单行子查询不被视为常量。
例如,如果子查询返回要与
DATETIME
值
进行比较的整数
,则比较将作为两个整数完成。
整数不会转换为时间值。
要将操作数作为
DATETIME
值
进行比较
,请使用
CAST()
显式转换子查询值
DATETIME
。
如果其中一个参数是十进制值,则比较取决于另一个参数。 如果另一个参数是十进制或整数值,则将参数作为十进制值进行比较,如果另一个参数是浮点值,则将参数作为浮点值进行比较。
在所有其他情况下,参数被比较为浮点(实数)。
有关将值从一种时间类型转换为另一种时间类型的信息,请参见 第11.3.6节“日期和时间类型之间的转换” 。
JSON值的比较发生在两个级别。 第一级比较基于比较值的JSON类型。 如果类型不同,则比较结果仅由哪种类型具有更高优先级来确定。 如果这两个值具有相同的JSON类型,则使用特定于类型的规则进行第二级比较。 为了比较JSON和非JSON值,将非JSON值转换为JSON,并将值作为JSON值进行比较。 有关详细信息,请参阅 JSON值的比较和排序 。
以下示例说明了将字符串转换为数字以进行比较操作:
MySQL的>SELECT 1 > '6x';
- > 0 MySQL的>SELECT 7 > '6x';
- > 1 MySQL的>SELECT 0 > 'x6';
- > 0 MySQL的>SELECT 0 = 'x6';
- > 1
为了比较字符串列和数字,MySQL不能使用列上的索引来快速查找值。
如果
str_col
是索引字符串列,则在以下语句中执行查找时,不能使用索引:
SELECT * FROMtbl_name
WHEREstr_col
= 1;
这样做的原因是,有许多不同的字符串可以转换为价值
1
,例如
'1'
,
' 1'
或
'1a'
。
使用浮点数(或转换为浮点数的值)的比较是近似的,因为这些数字是不精确的。 这可能会导致结果看起来不一致:
MySQL的>SELECT '18015376320243458' = 18015376320243458;
- > 1 MySQL的>SELECT '18015376320243459' = 18015376320243459;
- > 0
这样的结果可能会发生,因为值被转换为浮点数,它只有53位的精度并且可以进行舍入:
MySQL的> SELECT '18015376320243459'+0.0;
- > 1.8015376320243e + 16
此外,从字符串到浮点以及从整数到浮点的转换不一定以相同的方式发生。 整数可以由CPU转换为浮点数,而字符串在涉及浮点乘法的运算中逐位转换。
显示的结果将因系统而异,并且可能受计算机体系结构或编译器版本或优化级别等因素的影响。
避免此类问题的一种方法是使用,
CAST()
以便不将值隐式转换为浮点数:
MySQL的> SELECT CAST('18015376320243459' AS UNSIGNED) = 18015376320243459;
- > 1
有关浮点比较的更多信息,请参见 第B.4.4.8节“浮点值的问题” 。
服务器包括
dtoa
一个转换库,它提供了改进字符串或
DECIMAL
值与近似值(
FLOAT
/
DOUBLE
)数字
之间转换的基础
:
跨平台的一致转换结果,例如,消除了Unix与Windows转换差异。
在结果先前未提供足够精度的情况下精确表示值,例如接近IEEE限制的值。
将数字转换为字符串格式,并尽可能精确。
精度
dtoa
始终与标准C库函数
的精度
相同或更好。
由于此库生成的转换在某些情况下与非
dtoa
结果不同,因此可能存在依赖于先前结果的应用程序中的不兼容性。
例如,依赖于先前转换的特定精确结果的应用程序可能需要进行调整以适应额外的精度。
该
dtoa
库提供具有以下属性的转换。
D
表示具有
DECIMAL
或字符串
表示的值
,并
F
表示本机二进制(IEEE)格式的浮点数。
F
- >
D
转换以尽可能高的精度完成,返回
D
为
F
读回时
产生的最短字符串,
并以IEEE指定的本机二进制格式舍入为最接近的值。
D
- >
F
转换完成,这
F
是输入十进制字符串最接近的本机二进制数
D
。
这些性质暗示
F
- >
D
- >
F
转换是无损除非
F
是
-inf
,
+inf
,或
NaN
。
不支持后面的值,因为SQL标准将它们定义为
FLOAT
or的
无效值
DOUBLE
。
对于
D
- >
F
- >
D
转换,用于losslessness的充分条件是,
D
使用的精度15个或更少位数字,是不是反规范值,
-inf
,
+inf
,或
NaN
。
在某些情况下,即使
D
精度超过15位,
转换也是无损
的,但情况并非总是如此。
将数值或时间值隐式转换为字符串会生成一个值,该值具有由
系统变量
character_set_connection
和
collation_connection
系统变量
确定的字符集和排序规则
。
(这些变量通常设置为
SET
NAMES
。有关连接字符集的信息,请参见
第10.4节“连接字符集和排序”
。)
这意味着,这样的转换结果中的字符(非二进制的)字符串(一个
CHAR
,
VARCHAR
或
LONGTEXT
值),除了在该连接字符集设置到壳体
binary
。
在这种情况下,转换结果是一个二进制串(一个
BINARY
,
VARBINARY
或
LONGBLOB
值)。
对于整数表达式,约表达前述备注 评价 申请略有不同表达 分配 ; 例如,在这样的声明中:
CREATE TABLE t SELECT integer_expr
;
在这种情况下,由表达式生成的列中的表具有类型
INT
或
BIGINT
取决于整数表达式的长度。
如果表达式的最大长度不适合
INT
,
BIGINT
则使用。
长度取自
结果集元数据
的
max_length
值
SELECT
(请参见
第28.7.5节“C API数据结构”
)。
这意味着您可以强制使用
BIGINT
而不是
INT
使用足够长的表达式:
CREATE TABLE t SELECT 000000000000000000000;
表12.2运算符
名称 | 描述 |
---|---|
AND
,
&&
|
逻辑和 |
= |
分配值(作为
SET
语句的
一部分
,或作为
语句中
SET
子句的
一部分
UPDATE
)
|
:= |
分配值 |
BETWEEN ... AND
... |
检查值是否在值范围内 |
BINARY |
将字符串转换为二进制字符串 |
& |
按位AND |
~ |
按位反转 |
| |
按位OR |
^ |
按位异或 |
CASE |
案例运营商 |
DIV |
整数除法 |
/ |
分部运营商 |
= |
平等的运营商 |
<=> |
NULL-safe等于运算符 |
> |
大于运营商 |
>= |
大于或等于运营商 |
IN() |
检查值是否在一组值内 |
IS |
针对布尔值测试值 |
IS NOT |
针对布尔值测试值 |
IS NOT NULL |
NOT NULL值测试 |
IS NULL |
NULL值测试 |
-> |
评估路径后从JSON列返回值; 相当于JSON_EXTRACT()。 |
->> |
在评估路径并取消引用结果后,从JSON列返回值; 相当于JSON_UNQUOTE(JSON_EXTRACT())。 |
<< |
左移 |
< |
不到运营商 |
<= |
小于或等于运营商 |
LIKE |
简单的模式匹配 |
MEMBER OF() |
如果第一个操作数匹配作为第二个操作数传递的JSON数组的任何元素,则返回true(1),否则返回false(0) |
- |
减号运算符 |
%
,
MOD
|
模数运算符 |
NOT
,
!
|
否定价值 |
NOT BETWEEN
... AND ... |
检查值是否不在值范围内 |
!=
,
<>
|
不等于运营商 |
NOT IN() |
检查值是否不在一组值内 |
NOT LIKE |
简单模式匹配的否定 |
NOT REGEXP |
REGEXP的否定 |
OR
,
||
|
逻辑或 |
+ |
加法运算符 |
REGEXP |
string是否匹配正则表达式 |
>> |
右转 |
RLIKE |
string是否匹配正则表达式 |
SOUNDS LIKE |
比较声音 |
* |
乘法运算符 |
- |
更改参数的符号 |
XOR |
逻辑异或 |
运算符优先级显示在以下列表中,从最高优先级到最低优先级。 一行显示的运算符具有相同的优先级。
间隔 BINARY,COLLATE ! - (一元减号),〜(一元位反转) ^ *,/,DIV,%,MOD - ,+ <<,>> & | =(比较),<=>,> =,>,<=,<,<>,!=,IS,LIKE,REGEXP,IN 之间,情况,时间,然后,那么 不 AND,&& XOR 或者,|| =(赋值),:=
优先级
=
取决于它是用作比较运算符(
=
)还是用作赋值运算符(
=
)。
当作为比较操作符使用,它具有相同的优先级
<=>
,
>=
,
>
,
<=
,
<
,
<>
,
!=
,
IS
,
LIKE
,
REGEXP
,和
IN
。
当用作赋值运算符时,它具有相同的优先级
:=
。
第13.7.5.1节“变量赋值的SET语法”
和
第9.4节“用户定义的变量”
解释了MySQL如何确定
=
应该适用。
对于在表达式中以相同优先级发生的运算符,评估从左到右进行,但赋值从右到左进行求值。
一些运算符的优先级和含义取决于SQL模式:
默认情况下,它
||
是一个逻辑
OR
运算符。
与
PIPES_AS_CONCAT
启用,
||
是字符串连接,与之间的优先级
^
和元运算符。
默认情况下,
!
优先级高于
NOT
。
随着
HIGH_NOT_PRECEDENCE
启用,
!
并且
NOT
具有相同的优先级。
请参见 第5.1.11节“服务器SQL模式” 。
运算符的优先级决定了表达式中术语的评估顺序。 要明确覆盖此订单和组术语,请使用括号。 例如:
MySQL的>SELECT 1+2*3;
- > 7 MySQL的>SELECT (1+2)*3;
- > 9
表12.3比较运算符
名称 | 描述 |
---|---|
BETWEEN ... AND
... |
检查值是否在值范围内 |
COALESCE() |
返回第一个非NULL参数 |
= |
平等的运营商 |
<=> |
NULL-safe等于运算符 |
> |
大于运营商 |
>= |
大于或等于运营商 |
GREATEST() |
返回最大的参数 |
IN() |
检查值是否在一组值内 |
INTERVAL() |
返回小于第一个参数的参数的索引 |
IS |
针对布尔值测试值 |
IS NOT |
针对布尔值测试值 |
IS NOT NULL |
NOT NULL值测试 |
IS NULL |
NULL值测试 |
ISNULL() |
测试参数是否为NULL |
LEAST() |
返回最小的参数 |
< |
不到运营商 |
<= |
小于或等于运营商 |
LIKE |
简单的模式匹配 |
NOT BETWEEN
... AND ... |
检查值是否不在值范围内 |
!=
,
<>
|
不等于运营商 |
NOT IN() |
检查值是否不在一组值内 |
NOT LIKE |
简单模式匹配的否定 |
STRCMP() |
比较两个字符串 |
比较操作导致值为
1
(
TRUE
),
0
(
FALSE
)或
NULL
。
这些操作适用于数字和字符串。
根据需要,字符串会自动转换为数字和数字。
以下关系比较运算符不仅可用于比较标量操作数,还可用于比较行操作数:
=> <> = <= <>!=
本节后面的那些操作符的描述详细说明了它们如何与行操作数一起使用。 有关行子查询上下文中行比较的其他示例,请参见 第13.2.11.5节“行子查询” 。
本节中的某些函数返回除
1
(
TRUE
),
0
(
FALSE
)或之外的值
NULL
。
LEAST()
并且
GREATEST()
是这些功能的例子;
第12.2节“表达式评估中的类型转换”
描述了由这些和类似函数执行的比较操作的规则,用于确定它们的返回值。
在MySQL的
早期
版本中,当评估包含
LEAST()
or
的表达式时
GREATEST()
,服务器试图猜测使用该函数的上下文,并强制函数的参数作为整体表达式的数据类型。
例如,要对参数进行
LEAST("11",
"45", "2")
求值并将其排序为字符串,以便返回此表达式
"11"
。
在MySQL 8.0.3及更早版本中,在计算表达式时
LEAST("11", "45", "2") + 0
,服务器在对它们进行排序之前将参数转换为整数(预期向结果添加整数0),从而返回2。
从MySQL 8.0.4开始,服务器不再尝试以这种方式推断上下文。
相反,该函数使用提供的参数执行,对一个或多个参数执行数据类型转换,当且仅当它们不是全部相同类型时。
现在,在函数执行之后执行由使用返回值的表达式强制执行的任何类型强制。
这意味着,在MySQl 8.0.4及更高版本中,
LEAST("11", "45", "2") +
0
计算结果为
"11" + 0
11,因此
计算结果为
11.(Bug#83895,Bug#25123839)
要将值转换为特定类型以进行比较,可以使用该
CAST()
函数。
可以使用将字符串值转换为不同的字符集
CONVERT()
。
请参见
第12.10节“强制转换函数和运算符”
。
默认情况下,字符串比较不区分大小写并使用当前字符集。
默认是
utf8mb4
。
等于:
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
对于行比较,
(a, b) = (x, y)
相当于:
(a = x)AND(b = y)
NULL
- 等于。
这个运算符像
=
运算符
一样执行相等比较
,但返回
1
而不是
NULL
两个操作数都是
NULL
,
0
而不是
NULL
一个操作数
NULL
。
该
<=>
操作相当于标准的SQL
IS NOT
DISTINCT FROM
操作。
MySQL的>SELECT 1 <=> 1, NULL <=> NULL, 1 <=> NULL;
- > 1,1,0 MySQL的>SELECT 1 = 1, NULL = NULL, 1 = NULL;
- > 1,NULL,NULL
对于行比较,
(a, b) <=> (x,
y)
相当于:
(a <=> x)AND(b <=> y)
不相等:
MySQL的>SELECT '.01' <> '0.01';
- > 1 MySQL的>SELECT .01 <> '0.01';
- > 0 MySQL的>SELECT 'zapp' <> 'zappp';
- > 1
对于行比较,
(a, b) <> (x,
y)
并
(a, b) != (x, y)
等同于:
(a <> x)OR(b <> y)
小于或等于:
MySQL的> SELECT 0.1 <= 2;
- > 1
对于行比较,
(a, b) <= (x, y)
相当于:
(a <x)OR((a = x)AND(b <= y))
少于:
MySQL的> SELECT 2 < 2;
- > 0
对于行比较,
(a, b) < (x, y)
相当于:
(a <x)OR((a = x)AND(b <y))
大于或等于:
MySQL的> SELECT 2 >= 2;
- > 1
对于行比较,
(a, b) >= (x, y)
相当于:
(a> x)OR((a = x)AND(b> = y))
比...更棒:
MySQL的> SELECT 2 > 2;
- > 0
对于行比较,
(a, b) > (x, y)
相当于:
(a> x)OR((a = x)AND(b> y))
测试针对一个布尔值,其中值
boolean_value
可以是
TRUE
,
FALSE
,或
UNKNOWN
。
MySQL的> SELECT 1 IS TRUE, 0 IS FALSE, NULL IS UNKNOWN;
- > 1,1,1
测试针对一个布尔值,其中值
boolean_value
可以是
TRUE
,
FALSE
,或
UNKNOWN
。
MySQL的> SELECT 1 IS NOT UNKNOWN, 0 IS NOT UNKNOWN, NULL IS NOT UNKNOWN;
- > 1,1,0
测试值是否为
NULL
。
MySQL的> SELECT 1 IS NULL, 0 IS NULL, NULL IS NULL;
- > 0,0,1
为了与ODBC程序配合使用,MySQL在使用时支持以下额外功能
IS
NULL
:
如果
sql_auto_is_null
variable设置为1,那么在成功插入自动生成的
AUTO_INCREMENT
值
的语句之后
,您可以通过发出以下形式的语句来查找该值:
SELECT * FROMtbl_name
WHERE为auto_col
NULL
如果语句返回一行,则返回的值与调用该
LAST_INSERT_ID()
函数时
的值相同
。
有关详细信息,包括多行插入后的返回值,请参见
第12.15节“信息函数”
。
如果未
AUTO_INCREMENT
成功插入
任何
值,则该
SELECT
语句不返回任何行。
可以通过设置禁用
AUTO_INCREMENT
使用
IS NULL
比较
检索
值
的行为
sql_auto_is_null
= 0
。
请参见
第5.1.8节“服务器系统变量”
。
默认值为
sql_auto_is_null
0。
对于
DATE
和
DATETIME
声明为列
NOT NULL
,您可以找到特殊的日子
'0000-00-00'
用这样的语句:
SELECT * FROMtbl_name
WHERE为date_column
NULL
这是使一些ODBC应用程序工作所必需的,因为ODBC不支持
'0000-00-00'
日期值。
请参阅
获取自动增量值
,以及
Connector / ODBC连接参数
FLAG_AUTO_IS_NULL
选项
的说明
。
测试值是否不是
NULL
。
MySQL的> SELECT 1 IS NOT NULL, 0 IS NOT NULL, NULL IS NOT NULL;
- > 1,1,0
如果
expr
大于或等于
min
且
expr
小于或等于
max
,则
BETWEEN
返回
1
,否则返回
0
。
如果所有参数都是相同类型,则
这相当于表达式
。
否则,类型转换将根据
第12.2节“表达式评估中的类型转换”中
所述的规则进行
,但应用于所有三个参数。
(
min
<=
expr
AND
expr
<=
max
)
MySQL的>SELECT 2 BETWEEN 1 AND 3, 2 BETWEEN 3 and 1;
- > 1,0 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
为了在使用
BETWEEN
日期或时间值
时获得最佳结果
,请使用
CAST()
显式将值转换为所需的数据类型。
示例:如果将a
DATETIME
与两个
DATE
值
进行比较
,请将
DATE
值
转换
为
DATETIME
值。
如果使用字符串常量(例如与
'2001-1-1'
a进行比较)
DATE
,则将字符串强制转换为a
DATE
。
这是一样的
。
NOT
(
expr
BETWEEN
min
AND
max
)
返回
NULL
列表
中的第一个非
值,或者
NULL
如果没有非
NULL
值。
返回类型
COALESCE()
是参数类型的聚合类型。
MySQL的>SELECT COALESCE(NULL,1);
- > 1 MySQL的>SELECT COALESCE(NULL,NULL,NULL);
- > NULL
使用两个或多个参数,返回最大(最大值)参数。
使用与之相同的规则比较参数
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'
GREATEST()
NULL
如果有任何参数则
返回
NULL
。
返回
1
if
expr
等于
IN
列表
中的任何值
,否则返回
0
。
如果所有值都是常量,则根据类型
expr
和已排序
来评估它们
。
然后使用二分搜索完成对项目的搜索。
IN
如果
IN
值列表完全由常量组成,
则
这意味着
非常快
。
否则,类型转换将根据
第12.2节“表达式评估中的类型转换”中
所述的规则进行
,但应用于所有参数。
MySQL的>SELECT 2 IN (0,3,5,7);
- > 0 MySQL的>SELECT 'wefwf' IN ('wee','wefwf','weg');
- > 1
IN
可用于比较行构造函数:
MySQL的>SELECT (3,4) IN ((1,2), (3,4));
- > 1 MySQL的>SELECT (3,4) IN ((1,2), (3,5));
- > 0
您不应该在
IN
列表中
混合引用和不引用的值,
因为引用值(例如字符串)和不带引号的值(例如数字)的比较规则不同。
因此,混合类型可能导致不一致的结果。
例如,不要写这样的
IN
表达式:
SELECT val1 FROM tbl1 WHERE val1 IN(1,2,'a');
相反,写这样:
SELECT val1 FROM tbl1 WHERE val1 IN('1','2','a');
IN
列表中
的值数量
仅受
max_allowed_packet
值
限制
。
为了符合SQL标准,
不仅
IN
返回
NULL
左侧的表达式
NULL
,而且还返回列表中没有匹配项且列表中的一个表达式
NULL
。
IN()
语法也可用于编写某些类型的子查询。
请参见
第13.2.11.3节“带有ANY,IN或SOME的子查询”
。
这是一样的
。
NOT
(
expr
IN
(value
,...))
如果
expr
是
NULL
,则
ISNULL()
返回
1
,否则返回
0
。
MySQL的>SELECT ISNULL(1+1);
- > 0 MySQL的>SELECT ISNULL(1/0);
- > 1
ISNULL()
可以用来代替
=
测试值是否
NULL
。
(一值比较,以
NULL
使用
=
总是产率
NULL
)。
返回
0
如果
N
<
N1
,
1
如果
N
<
N2
等等或
-1
如果
N
是
NULL
。
所有参数都被视为整数。
它要求
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
使用两个或多个参数,返回最小(最小值)参数。 使用以下规则比较参数:
返回类型
LEAST()
是比较参数类型的聚合类型。
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'
在SQL中,所有逻辑运算符来评估
TRUE
,
FALSE
或
NULL
(
UNKNOWN
)。
在MySQL中,这些实现为1(
TRUE
),0(
FALSE
)和
NULL
。
大多数情况对于不同的SQL数据库服务器是常见的,尽管某些服务器可能会返回任何非零值
TRUE
。
MySQL评估任何非零非
NULL
值
TRUE
。
例如,以下语句都评估为
TRUE
:
MySQL的>SELECT 10 IS TRUE;
- > 1 MySQL的>SELECT -10 IS TRUE;
- > 1 MySQL的>SELECT 'string' IS NOT NULL;
- > 1
逻辑不。
计算
1
操作数是否为
0
,
0
如果操作数非零,则
NOT NULL
返回
NULL
。
MySQL的>SELECT NOT 10;
- > 0 MySQL的>SELECT NOT 0;
- > 1 MySQL的>SELECT NOT NULL;
- > NULL MySQL的>SELECT ! (1+1);
- > 0 MySQL的>SELECT ! 1+1;
- > 1
最后一个示例生成,
1
因为表达式的计算方式与
(!1)+1
。
的
!
,运营商是一个非标准MySQL扩展。
从MySQL 8.0.17开始,不推荐使用此运算符,并且在将来的MySQL版本中将删除对它的支持。
应调整应用程序以使用标准SQL
NOT
运算符。
逻辑和。
计算
1
所有操作数是否为非零而不是
NULL
,
0
如果是一个或多个操作数
0
,
NULL
则返回。
MySQL的>SELECT 1 AND 1;
- > 1 MySQL的>SELECT 1 AND 0;
- > 0 MySQL的>SELECT 1 AND NULL;
- > NULL MySQL的>SELECT 0 AND NULL;
- > 0 MySQL的>SELECT NULL AND 0;
- > 0
的
&&
,运营商是一个非标准MySQL扩展。
从MySQL 8.0.17开始,不推荐使用此运算符,并且在将来的MySQL版本中将删除对它的支持。
应调整应用程序以使用标准SQL
AND
运算符。
逻辑或。
当两个操作数都是非操作数时
NULL
,结果是
1
任何操作数是非零的,
0
否则。
对于
NULL
操作数,结果是
1
如果另一个操作数非零,
NULL
否则。
如果两个操作数都是
NULL
,则结果为
NULL
。
MySQL的>SELECT 1 OR 1;
- > 1 MySQL的>SELECT 1 OR 0;
- > 1 MySQL的>SELECT 0 OR 0;
- > 0 MySQL的>SELECT 0 OR NULL;
- > NULL MySQL的>SELECT 1 OR NULL;
- > 1
如果
PIPES_AS_CONCAT
启用
了
SQL模式,则
||
表示SQL标准字符串连接运算符(如
CONCAT()
)。
的
||
,运营商是一个非标准MySQL扩展。
从MySQL 8.0.17开始,不推荐使用此运算符,并且在将来的MySQL版本中将删除对它的支持。
应调整应用程序以使用标准SQL
OR
运算符。
例外:如果
PIPES_AS_CONCAT
启用了
弃用,则不适用,
因为在这种情况下,
||
表示字符串连接。
逻辑异或。
NULL
如果任一操作数是,则
返回
NULL
。
对于非
NULL
操作数,评估
1
奇数个操作数是否为非零,否则
0
返回。
MySQL的>SELECT 1 XOR 1;
- > 0 MySQL的>SELECT 1 XOR 0;
- > 1 MySQL的>SELECT 1 XOR NULL;
- > NULL MySQL的>SELECT 1 XOR 1 XOR 1;
- > 1
a XOR b
在数学上等于
(a AND (NOT b)) OR ((NOT a) and b)
。
分配操作员。
使操作员左侧的用户变量采用其右侧的值。
右侧的值可以是文字值,另一个存储值的变量,或产生标量值的任何合法表达式,包括查询结果(假设此值是标量值)。
您可以在同一
SET
语句中
执行多个分配
。
您可以在同一语句中执行多个分配。
与此不同
=
,
:=
操作符永远不会被解释为比较运算符。
这意味着您可以
:=
在任何有效的SQL语句(不仅仅是
SET
语句中)中使用它来为变量赋值。
MySQL的>SELECT @var1, @var2;
- > NULL,NULL MySQL的>SELECT @var1 := 1, @var2;
- > 1,NULL MySQL的>SELECT @var1, @var2;
- > 1,NULL MySQL的>SELECT @var1, @var2 := @var1;
- > 1,1 MySQL的>SELECT @var1, @var2;
- > 1,1 MySQL的>SELECT @var1:=COUNT(*) FROM t1;
- > 4 MySQL的>SELECT @var1;
- > 4
您可以使用
:=
其他语句
进行值赋值
SELECT
,例如
UPDATE
,如下所示:
MySQL的>SELECT @var1;
- > 4 MySQL的>SELECT * FROM t1;
- > 1,3,5,7 MySQL的>UPDATE t1 SET c1 = 2 WHERE c1 = @var1:= 1;
查询正常,1行受影响(0.00秒) 匹配的行数:1已更改:1警告:0 MySQL的>SELECT @var1;
- > 1 MySQL的>SELECT * FROM t1;
- > 2,3,5,7
虽然也可以使用
:=
运算符
在单个SQL语句中设置和读取同一变量的值,但
不建议这样做。
第9.4节“用户定义的变量”
解释了为什么要避免这样做。
此运算符用于在两种情况下执行值赋值,如下两段所述。
在
SET
语句中,
=
被视为赋值运算符,它使运算符左侧的用户变量采用其右侧的值。
(换句话说,当在
SET
语句中
使用时
,
=
被视为相同
:=
。)右侧的值可以是文字值,另一个存储值的变量,或产生标量值的任何合法表达式,包括结果查询(假设此值是标量值)。
您可以在同一
SET
语句中
执行多个分配
。
在
声明
的
SET
条款中
UPDATE
,
=
也充当赋值运算符;
但是,在这种情况下,只要满足任何
WHERE
条件
,它就会使运算符左侧的列成为赋予右侧的值
UPDATE
。
您可以在
语句
的同一
SET
子句中
进行多项赋值
UPDATE
。
在任何其他上下文中,
=
被视为
比较运算符
。
MySQL的>SELECT @var1, @var2;
- > NULL,NULL MySQL的>SELECT @var1 := 1, @var2;
- > 1,NULL MySQL的>SELECT @var1, @var2;
- > 1,NULL MySQL的>SELECT @var1, @var2 := @var1;
- > 1,1 MySQL的>SELECT @var1, @var2;
- > 1,1
有关更多信息,请参见 第13.7.5.1节“变量赋值的SET语法” , 第13.2.12节“更新语法” 和 第13.2.11节“子查询语法” 。
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
第一个
CASE
语法返回
result
第一个
为true的比较。
第二种语法返回第一个条件为true的结果。
如果没有比较或条件为真,
则返回
结果
,或者
如果没有
部分。
value
=compare_value
ELSE
NULL
ELSE
此处描述
的
expr
的语法
与
第13.6.5.1节“CASE语法”中
描述
的SQL
语句
略有不同
,用于在存储程序中使用。
该
语句不能有一个
子句,它以for
而不是
。
CASE
CASE
CASE
ELSE NULL
END CASE
END
CASE
表达式结果
的返回类型
是所有结果值的聚合类型:
mysql>SELECT CASE 1 WHEN 1 THEN 'one'
- >WHEN 2 THEN 'two' ELSE 'more' END;
- >'一个' 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
如果
expr1
是
TRUE
(
和
expr1
<>
0
),则
expr1
<> NULLIF()
返回
expr2
。
否则,它返回
expr3
。
还有一个
声明
,与
此处描述
的
功能
不同
。
请参见
第13.6.5.2节“IF语法”
。
IF
IF()
如果只有一个
expr2
或
expr3
明确
NULL
,则
IF()
函数
的结果类型
是非
NULL
表达式
的类型
。
默认返回类型
IF()
(在存储到临时表时可能很重要)计算如下:
如果
expr2
或
expr3
生成一个字符串,结果是一个字符串。
如果
expr2
和
expr3
都是字符串,则如果任一字符串区分大小写,则结果区分大小写。
如果
expr2
或
expr3
生成浮点值,则结果为浮点值。
如果
expr2
或
expr3
生成整数,则结果为整数。
MySQL的>SELECT IF(1>2,2,3);
- > 3 MySQL的>SELECT IF(1<2,'yes','no');
- >'是' MySQL的>SELECT IF(STRCMP('test','test1'),'no','yes');
- >'不'
如果
expr1
不是
NULL
,则
IFNULL()
返回
expr1
;
否则它会返回
expr2
。
MySQL的>SELECT IFNULL(1,0);
- > 1 MySQL的>SELECT IFNULL(NULL,10);
- > 10 MySQL的>SELECT IFNULL(1/0,10);
- > 10 MySQL的>SELECT IFNULL(1/0,'yes');
- >'是'
的默认返回值类型
是更为
“
一般
”
两个表达式的,顺序
,
或
。
考虑基于表达式的表的情况,或者MySQL必须在内部存储
临时表中
返回的值的情况
:
IFNULL(
expr1
,expr2
)STRING
REAL
INTEGER
IFNULL()
mysql>CREATE TABLE tmp SELECT IFNULL(1,'test') AS test;
mysql>DESCRIBE tmp;
+ ------- + -------------- + ------ + ------ + --------- + --- ---- + | 领域| 输入| 空| 钥匙| 默认| 额外的| + ------- + -------------- + ------ + ------ + --------- + --- ---- + | 测试| varbinary(4)| 没有| | | | + ------- + -------------- + ------ + ------ + --------- + --- ---- +
在此示例中,
test
列
的类型
是
VARBINARY(4)
(字符串类型)。
返回
NULL
if
为true,否则返回
。
这是一样的
。
expr1
=
expr2
expr1
CASE
WHEN
expr1
=
expr2
THEN NULL ELSE
expr1
END
返回值与第一个参数的类型相同。
MySQL的>SELECT NULLIF(1,1);
- > NULL MySQL的>SELECT NULLIF(1,2);
- > 1
expr1
如果参数不相等,
MySQL将评估
两次。
表12.7字符串运算符
名称 | 描述 |
---|---|
ASCII() |
返回最左侧字符的数值 |
BIN() |
返回包含数字的二进制表示的字符串 |
BIT_LENGTH() |
以位为单位返回参数长度 |
CHAR() |
返回传递的每个整数的字符 |
CHAR_LENGTH() |
返回参数中的字符数 |
CHARACTER_LENGTH() |
CHAR_LENGTH()的同义词 |
CONCAT() |
返回连接字符串 |
CONCAT_WS() |
返回与分隔符连接 |
ELT() |
返回索引号处的字符串 |
EXPORT_SET() |
返回一个字符串,使得对于值位中设置的每个位,您获得一个on字符串,并且对于每个未设置的位,您将获得一个关闭字符串 |
FIELD() |
后续参数中第一个参数的索引(位置) |
FIND_IN_SET() |
第二个参数中第一个参数的索引(位置) |
FORMAT() |
返回格式化为指定小数位数的数字 |
FROM_BASE64() |
解码base64编码的字符串并返回结果 |
HEX() |
十进制或字符串值的十六进制表示 |
INSERT() |
在指定位置插入子字符串,直到指定的字符数 |
INSTR() |
返回第一次出现的子串的索引 |
LCASE() |
LOWER()的同义词 |
LEFT() |
返回指定的最左边的字符数 |
LENGTH() |
以字节为单位返回字符串的长度 |
LIKE |
简单的模式匹配 |
LOAD_FILE() |
加载指定的文件 |
LOCATE() |
返回第一次出现的子串的位置 |
LOWER() |
以小写形式返回参数 |
LPAD() |
返回字符串参数,使用指定的字符串进行左填充 |
LTRIM() |
删除前导空格 |
MAKE_SET() |
返回一组以逗号分隔的字符串,这些字符串具有相应的位设置位 |
MATCH |
执行全文搜索 |
MID() |
返回从指定位置开始的子字符串 |
NOT LIKE |
简单模式匹配的否定 |
NOT REGEXP |
REGEXP的否定 |
OCT() |
返回包含数字的八进制表示的字符串 |
OCTET_LENGTH() |
LENGTH()的同义词 |
ORD() |
返回参数最左侧字符的字符代码 |
POSITION() |
LOCATE()的同义词 |
QUOTE() |
转义参数以在SQL语句中使用 |
REGEXP |
string是否匹配正则表达式 |
REGEXP_INSTR() |
匹配正则表达式的子串的起始索引 |
REGEXP_LIKE() |
string是否匹配正则表达式 |
REGEXP_REPLACE() |
替换匹配正则表达式的子字符串 |
REGEXP_SUBSTR() |
返回子串匹配正则表达式 |
REPEAT() |
重复指定次数的字符串 |
REPLACE() |
替换指定字符串的出现次数 |
REVERSE() |
反转字符串中的字符 |
RIGHT() |
返回指定的最右边的字符数 |
RLIKE |
string是否匹配正则表达式 |
RPAD() |
追加指定次数的字符串 |
RTRIM() |
删除尾随空格 |
SOUNDEX() |
返回soundex字符串 |
SOUNDS LIKE |
比较声音 |
SPACE() |
返回指定数量的空格的字符串 |
STRCMP() |
比较两个字符串 |
SUBSTR() |
返回指定的子字符串 |
SUBSTRING() |
返回指定的子字符串 |
SUBSTRING_INDEX() |
在指定的分隔符出现次数之前从字符串返回子字符串 |
TO_BASE64() |
返回转换为base-64字符串的参数 |
TRIM() |
删除前导和尾随空格 |
UCASE() |
UPPER()的同义词 |
UNHEX() |
返回包含数字的十六进制表示的字符串 |
UPPER() |
转换为大写 |
WEIGHT_STRING() |
返回字符串的权重字符串 |
NULL
如果结果的长度大于
max_allowed_packet
系统变量
的值,则
返回字符串值函数
。
请参见
第5.1.1节“配置服务器”
。
对于在字符串位置上操作的函数,第一个位置编号为1。
对于采用长度参数的函数,非整数参数将四舍五入为最接近的整数。
返回字符串最左侧字符的数值
str
。
返回
0
if
str
是否为空字符串。
NULL
如果
str
是,则
返回
NULL
。
ASCII()
适用于8位字符。
MySQL的>SELECT ASCII('2');
- > 50 MySQL的>SELECT ASCII(2);
- > 50 MySQL的>SELECT ASCII('dx');
- > 100
另请参见该
ORD()
功能。
返回二进制值的字符串表示形式
N
,其中
N
longlong(
BIGINT
)数字。
这相当于
。
如果
是,则
返回
。
CONV(
N
,10,2)NULL
N
NULL
MySQL的> SELECT BIN(12);
- >'1100'
str
以位
为单位返回字符串的长度
。
MySQL的> SELECT BIT_LENGTH('text');
- > 32
CHAR(
N
,...
[USING charset_name
])
CHAR()
将每个参数解释
N
为一个整数,并返回一个字符串,该字符串由这些整数的代码值给出的字符组成。
NULL
值被跳过。
MySQL的>SELECT CHAR(77,121,83,81,'76');
- >'MySQL' MySQL的>SELECT CHAR(77,77.3,'77.3');
- >'MMM'
CHAR()
大于255的参数将转换为多个结果字节。
例如,
CHAR(256)
等同于
CHAR(1,0)
,
CHAR(256*256)
等同于
CHAR(1,0,0)
:
MySQL的>SELECT HEX(CHAR(1,0)), HEX(CHAR(256));
+ ---------------- + ---------------- + | 十六进制(CHAR(1,0))| HEX(CHAR(256))| + ---------------- + ---------------- + | 0100 | 0100 | + ---------------- + ---------------- + MySQL的>SELECT HEX(CHAR(1,0,0)), HEX(CHAR(256*256));
+ ------------------ + -------------------- + | 十六进制(CHAR(1,0,0))| HEX(CHAR(256 * 256))| + ------------------ + -------------------- + | 010000 | 010000 | + ------------------ + -------------------- +
默认情况下,
CHAR()
返回二进制字符串。
要在给定字符集中生成字符串,请使用optional
USING
子句:
MySQL的> SELECT CHARSET(CHAR(X'65')), CHARSET(CHAR(X'65' USING utf8));
+ ---------------------- + -------------------------- ------- +
| CHARSET(CHAR(X'65'))| CHARSET(CHAR(X'65'使用utf8))|
+ ---------------------- + -------------------------- ------- +
| 二进制| utf8 |
+ ---------------------- + -------------------------- ------- +
如果
USING
给定并且结果字符串对于给定字符集是非法的,则发出警告。
此外,如果启用了严格的SQL模式,则结果
CHAR()
将变为
NULL
。
返回字符串的长度
str
,以字符为单位。
多字节字符计为单个字符。
这意味着对于包含五个2字节字符的字符串,
LENGTH()
返回
10
,而
CHAR_LENGTH()
返回
5
。
CHARACTER_LENGTH()
是...的同义词
CHAR_LENGTH()
。
返回连接参数产生的字符串。 可能有一个或多个参数。 如果所有参数都是非二进制字符串,则结果为非二进制字符串。 如果参数包含任何二进制字符串,则结果为二进制字符串。 数字参数将转换为其等效的非二进制字符串形式。
CONCAT()
NULL
如果有任何参数则
返回
NULL
。
MySQL的>SELECT CONCAT('My', 'S', 'QL');
- >'MySQL' MySQL的>SELECT CONCAT('My', NULL, 'QL');
- > NULL MySQL的>SELECT CONCAT(14.3);
- > '14 .3'
对于带引号的字符串,可以通过将字符串放在彼此旁边来执行连接:
MySQL的> SELECT 'My' 'S' 'QL';
- >'MySQL'
CONCAT_WS(
separator
,str1
,str2
,...)
CONCAT_WS()
代表Concatenate With Separator,是一种特殊的形式
CONCAT()
。
第一个参数是其余参数的分隔符。
在要连接的字符串之间添加分隔符。
分隔符可以是字符串,其余参数也可以。
如果是分隔符
NULL
,结果是
NULL
。
MySQL的>SELECT CONCAT_WS(',','First name','Second name','Last Name');
- >'名字,第二个名字,姓氏' MySQL的>SELECT CONCAT_WS(',','First name',NULL,'Last Name');
- >'名字,姓氏'
CONCAT_WS()
不会跳过空字符串。
但是,它会
NULL
在分隔符参数后
跳过任何
值。
ELT()
返回
N
字符串列表
的
第th个元素:
str1
if
N
=
1
,
str2
if
N
=
2
,依此类推。
返回
NULL
if
N
小于
1
或大于参数的数量。
ELT()
是补充
FIELD()
。
MySQL的>SELECT ELT(1, 'Aa', 'Bb', 'Cc', 'Dd');
- >'Aa' MySQL的>SELECT ELT(4, 'Aa', 'Bb', 'Cc', 'Dd');
- >'Dd'
EXPORT_SET(
bits
,on
,off
[,separator
[,number_of_bits
]])
返回一个字符串,使得对于值中设置的每个位
bits
,您将获得一个
on
字符串,并且对于未在该值中设置的每个位,您将获得一个
off
字符串。
比特
bits
被从右到左(从低以高序位)检查。
字符串从左到右添加到结果中,由
separator
字符串
分隔
(默认为逗号字符
,
)。
检查的位数由
number_of_bits
下式
给出
,如果未指定,则默认值为64。
number_of_bits
如果大于64,则静默地剪切为64.它被视为无符号整数,因此值-1实际上与64相同。
MySQL的>SELECT EXPORT_SET(5,'Y','N',',',4);
- >'Y,N,Y,N' MySQL的>SELECT EXPORT_SET(6,'1','0',',',10);
- >'0,1,1,0,0,0,0,0,0,0'
返回的索引(位置)
str
中
str1
,
str2
,
str3
,
...
列表。
0
如果
str
找不到则
返回
。
如果所有参数
FIELD()
都是字符串,
则将所有参数
作为字符串进行比较。
如果所有参数都是数字,则将它们作为数字进行比较。
否则,参数将被比较为double。
如果
str
是
NULL
,返回值是
0
因为
NULL
与任何值的失败相等性比较。
FIELD()
是补充
ELT()
。
MySQL的>SELECT FIELD('Bb', 'Aa', 'Bb', 'Cc', 'Dd', 'Ff');
- > 2 MySQL的>SELECT FIELD('Gg', 'Aa', 'Bb', 'Cc', 'Dd', 'Ff');
- > 0
N
如果字符串
str
位于
strlist
由
N
子
字符串
组成
的字符串列表中
,
则
返回1到1范围内的值
。
字符串列表是由
,
字符
分隔的子字符串组成的字符串
。
如果第一个参数是常量字符串而第二个参数是类型列,
则优化
SET
该
FIND_IN_SET()
函数以使用位算术。
返回
0
if
str
不在
strlist
或if
strlist
是空字符串。
NULL
如果任一参数是,则
返回
NULL
。
如果第一个参数包含逗号,则此函数无法正常工作(
,
)性格。
MySQL的> SELECT FIND_IN_SET('b','a,b,c,d');
- > 2
将数字格式化
X
为格式
'#,###,###.##'
,舍入到
D
小数位,并将结果作为字符串返回。
如果
D
是的话
0
,则结果没有小数点或小数部分。
可选的第三个参数允许指定区域设置用于结果编号的小数点,千位分隔符和分隔符之间的分组。
允许的区域设置值与
lc_time_names
系统变量
的合法值相同
(请参见
第10.15节“MySQL服务器区域设置支持”
)。
如果未指定区域设置,则默认为
'en_US'
。
MySQL的>SELECT FORMAT(12332.123456, 4);
- > '12,332.1235' MySQL的>SELECT FORMAT(12332.1,4);
- > '12,332.1000' MySQL的>SELECT FORMAT(12332.2,0);
- > '12,332' MySQL的>SELECT FORMAT(12332.2,2,'de_DE');
- > '12 .332,20'
采用使用的base-64编码规则编码的字符串
TO_BASE64()
,并将解码结果作为二进制字符串返回。
结果是
NULL
参数是否是
NULL
有效的base-64字符串。
有关
TO_BASE64()
编码和解码规则的详细信息,
请参阅说明
。
MySQL的> SELECT TO_BASE64('abc'), FROM_BASE64(TO_BASE64('abc'));
- >'JWJj','abc'
对于字符串参数
str
,
HEX()
返回十六进制字符串表示形式,
str
其中每个字符的每个字节
str
都转换为两个十六进制数字。
(多字节字符因此变为两位以上。)此操作的反转由。执行
UNHEX()
功能
。
对于数字参数
N
,
HEX()
返回
N
被视为longlong(
BIGINT
)数字
的值的十六进制字符串表示形式
。
这相当于
。
该操作的反转由执行
。
CONV(
N
,10,16)CONV(HEX(
N
),16,10)
MySQL的>SELECT X'616263', HEX('abc'), UNHEX(HEX('abc'));
- >'abc',616263,'abc' MySQL的>SELECT HEX(255), CONV(HEX(255),16,10);
- >'FF',255
返回字符串
str
,在位置开始子
pos
和
len
长期被字符串替换的字符
newstr
。
如果
pos
不在
字符串
的长度内,
则返回原始
字符串。
pos
如果
len
不在字符串其余部分的长度内,
则从位置替换字符串
的其余部分。
NULL
如果有任何参数,则
返回
NULL
。
MySQL的>SELECT INSERT('Quadratic', 3, 4, 'What');
- >'QuWhattic' MySQL的>SELECT INSERT('Quadratic', -1, 4, 'What');
- >'Quadratic' MySQL的>SELECT INSERT('Quadratic', 3, 100, 'What');
- >'QuWhat'
此功能是多字节安全的。
返回
substr
string中
第一次出现的子
字符串的位置
str
。
LOCATE()
除了参数的顺序相反之外,这
与双参数形式
相同。
MySQL的>SELECT INSTR('foobarbar', 'bar');
- > 4 MySQL的>SELECT INSTR('xbar', 'foobar');
- > 0
此函数是多字节安全的,并且仅当至少一个参数是二进制字符串时才区分大小写。
LCASE()
在
LOWER()
存储视图的定义时,视图中
使用的内容将被重写
。
(缺陷号码#12844279)
返回
len
字符串中
最左边的
字符
str
,或者
NULL
如果有任何参数
NULL
。
MySQL的> SELECT LEFT('foobarbar', 5);
- >'fooba'
此功能是多字节安全的。
返回字符串的长度
str
,以字节为单位。
多字节字符计为多个字节。
这意味着对于包含五个2字节字符的字符串,
LENGTH()
返回
10
,而
CHAR_LENGTH()
返回
5
。
MySQL的> SELECT LENGTH('text');
- > 4
在
Length()
开放GIS空间功能被命名为
ST_Length()
MySQL中。
读取文件并以字符串形式返回文件内容。
要使用此功能,文件必须位于服务器主机上,您必须指定文件的完整路径名,并且您必须具有该
FILE
权限。
该文件必须是服务器可读的,其大小小于
max_allowed_packet
字节。
如果
secure_file_priv
系统变量设置为非空目录名,则要加载的文件必须位于该目录中。
(在MySQL 8.0.17之前,文件必须是所有人都可读的,而不仅仅是服务器可读的。)
如果由于不满足上述条件之一而导致文件不存在或无法读取,则返回该函数
NULL
。
该
character_set_filesystem
系统变量控制给定为文字字符串文件名的解释。
MySQL的>UPDATE t
SET blob_col=LOAD_FILE('/tmp/picture')
WHERE id=1;
LOCATE(
,
substr
,str
)LOCATE(
substr
,str
,pos
)
第一个语法返回
substr
string中
第一次出现的substring的位置
str
。
第二种语法返回
substr
string中
第一次出现的substring的
str
位置,从position开始
pos
。
0
如果
substr
不在,则
返回
str
。
NULL
如果有任何参数,则
返回
NULL
。
MySQL的>SELECT LOCATE('bar', 'foobarbar');
- > 4 MySQL的>SELECT LOCATE('xbar', 'foobar');
- > 0 MySQL的>SELECT LOCATE('bar', 'foobarbar', 5);
- > 7
此函数是多字节安全的,并且仅当至少一个参数是二进制字符串时才区分大小写。
返回
str
根据当前字符集映射将所有字符更改为小写
的字符串
。
默认是
utf8mb4
。
MySQL的> SELECT LOWER('QUADRATICALLY');
- >'quadratically'
LOWER()
(并且
UPPER()
当施加到二进制字符串()是无效的
BINARY
,
VARBINARY
,
BLOB
)。
要执行lettercase转换,请将字符串转换为非二进制字符串:
mysql>SET @str = BINARY 'New York';
mysql>SELECT LOWER(@str), LOWER(CONVERT(@str USING utf8mb4));
+ ------------- + ----------------------------------- - + | LOWER(@str)| LOWER(CONVERT(@str使用utf8mb4))| + ------------- + ----------------------------------- - + | 纽约| 纽约| + ------------- + ----------------------------------- - +
对于Unicode字符集
的排序规则
,
LOWER()
并
UPPER()
根据排序规则名称中的Unicode排序规则算法(UCA)版本(如果有)和UCA 4.0.0(如果未指定版本)工作。
例如,
utf8mb4_0900_ai_ci
并且
utf8_unicode_520_ci
根据分别UCA 9.0.0和5.2.0,工作,而
utf8_unicode_ci
作品根据UCA 4.0.0。
请参见
第10.10.1节“Unicode字符集”
。
此功能是多字节安全的。
LCASE()
视图中使用的内容将被重写为
LOWER()
。
返回字符串
str
,用
字符串
左边填充
padstr
为
len
字符
长度
。
如果
str
长于
len
,则返回值缩短为
len
字符。
MySQL的>SELECT LPAD('hi',4,'??');
- >'?? hi' MySQL的>SELECT LPAD('hi',1,'??');
- >'h'
返回
str
删除了前导空格字符
的字符串
。
MySQL的> SELECT LTRIM(' barbar');
- >'barbar'
此功能是多字节安全的。
返回一个设置值(包含由
,
字符
分隔的子字符串的字符串
),包含具有
bits
set中
相应位的字符串
。
str1
对应于位0,
str2
位1,依此类推。
NULL
在价值观
str1
,
str2
,
...
不附加到该结果。
MySQL的>SELECT MAKE_SET(1,'a','b','c');
- >'a' MySQL的>SELECT MAKE_SET(1 | 4,'hello','nice','world');
- >'你好,世界' MySQL的>SELECT MAKE_SET(1 | 4,'hello','nice',NULL,'world');
- >'你好' MySQL的>SELECT MAKE_SET(0,'a','b','c');
- >''
MID(
是...的同义词
。
str
,pos
,len
)SUBSTRING(
str
,pos
,len
)
返回八进制值的字符串表示形式
N
,其中
N
longlong(
BIGINT
)数字。
这相当于
。
如果
是,则
返回
CONV(
N
,10,8)NULL
N
NULL
。
MySQL的> SELECT OCT(12);
- >'14'
OCTET_LENGTH()
是...的同义词
LENGTH()
。
如果字符串的最左边的字符
str
是多字节字符,则返回该字符的代码,使用以下公式从其组成字节的数值计算:
(第1字节代码) +(第2字节代码* 256) +(第3字节代码* 256 ^ 2)...
如果最左边的字符不是多字节字符,则
ORD()
返回与...相同的值
ASCII()
函数
。
MySQL的> SELECT ORD('2');
- > 50
POSITION(
是...的同义词
。
substr
IN str
)LOCATE(
substr
,str
)
引用字符串以生成可在SQL语句中用作正确转义的数据值的结果。
返回的字符串用单引号括起来,每个反斜杠(
\
),单引号(
'
),ASCII
NUL
和Control + Z
实例都以反斜杠
开头。
如果参数是
NULL
,则返回值是单词
“
NULL
”
而不包含单引号。
MySQL的>SELECT QUOTE('Don\'t!');
- >'不要!' MySQL的>SELECT QUOTE(NULL);
- > NULL
为了比较,请参见 第9.1.1节“字符串文字” 和 第28.7.7.56节“mysql_real_escape_string_quote()”中 文字字符串的引用规则和C API中的引用规则 。
返回由字符串
str
重复
count
次数
组成的字符串
。
如果
count
小于1,则返回空字符串。
NULL
如果
str
或是,
count
则
返回
NULL
。
MySQL的> SELECT REPEAT('MySQL', 3);
- >'MySQLMySQLMySQL'
返回
str
字符串
from_str
替换
为字符串
的所有
字符串
to_str
。
REPLACE()
搜索时执行区分大小写的匹配
from_str
。
MySQL的> SELECT REPLACE('www.mysql.com', 'w', 'Ww');
- >'WwWwWw.mysql.com'
此功能是多字节安全的。
返回字符串
str
顺序颠倒
的字符串
。
MySQL的> SELECT REVERSE('abc');
- >'cba'
此功能是多字节安全的。
返回
len
字符串中
最右边的
字符
str
,或者
NULL
是否有任何参数
NULL
。
MySQL的> SELECT RIGHT('foobarbar', 4);
- >'rbar'
此功能是多字节安全的。
返回字符串
str
,右边用字符串填充
padstr
为一个
len
字符
长度
。
如果
str
长于
len
,则返回值缩短为
len
字符。
MySQL的>SELECT RPAD('hi',5,'?');
- >'你好??? MySQL的>SELECT RPAD('hi',1,'?');
- >'h'
此功能是多字节安全的。
返回
str
删除了尾随空格字符
的字符串
。
MySQL的> SELECT RTRIM('barbar ');
- >'barbar'
此功能是多字节安全的。
从中返回soundex字符串
str
。
听起来几乎相同的两个弦应具有相同的soundex弦。
标准soundex字符串长度为四个字符,但该
SOUNDEX()
函数返回一个任意长的字符串。
您可以
SUBSTRING()
在结果上
使用
以获得标准的soundex字符串。
str
忽略
所有非字母字符
。
AZ范围之外的所有国际字母字符都被视为元音。
使用时
SOUNDEX()
,您应该了解以下限制:
目前实现的此功能旨在与仅使用英语的字符串一起使用。 其他语言的字符串可能无法产生可靠的结果。
无法保证此函数能够为使用多字节字符集的字符串提供一致的结果,包括
utf-8
。
有关更多信息,请参阅Bug#22638。
MySQL的>SELECT SOUNDEX('Hello');
- >'H400' MySQL的>SELECT SOUNDEX('Quadratically');
- >'Q36324'
此函数实现了原始的Soundex算法,而不是更流行的增强版本(也由D. Knuth描述)。 区别在于原始版本首先丢弃元音并重复第二个元素,而增强版本首先丢弃重复元素,然后丢弃元音元素。
这是一样的
。
SOUNDEX(
expr1
)
= SOUNDEX(expr2
)
返回由
N
空格字符
组成的字符串
。
MySQL的> SELECT SPACE(6);
- >''
SUBSTR(
,
,
,
str
,pos
)SUBSTR(
str
FROM pos
)SUBSTR(
str
,pos
,len
)SUBSTR(
str
FROM pos
FOR
len
)
SUBSTR()
是...的同义词
SUBSTRING()
。
SUBSTRING(
,
,
,
str
,pos
)SUBSTRING(
str
FROM pos
)SUBSTRING(
str
,pos
,len
)SUBSTRING(
str
FROM pos
FOR
len
)
没有
len
参数
的表单
从
str
位置开始
返回字符串的子字符串
pos
。
带有
len
参数
的表单
len
从字符串
返回一个子字符串
字符
str
,从位置开始
pos
。
使用的表单
FROM
是标准SQL语法。
也可以使用负值
pos
。
在这种情况下,子字符串的开头是字符串
pos
末尾的字符,而不是字符串的开头。
负值可以用于
pos
该函数的任何形式。
对于所有形式
SUBSTRING()
,将从中提取子字符串的字符串中第一个字符的位置计算为
1
。
MySQL的>SELECT SUBSTRING('Quadratically',5);
- >'ratically' MySQL的>SELECT SUBSTRING('foobarbar' FROM 4);
- >'barbar' MySQL的>SELECT SUBSTRING('Quadratically',5,6);
- >'ratica' MySQL的>SELECT SUBSTRING('Sakila', -3);
- >'ila' MySQL的>SELECT SUBSTRING('Sakila', -5, 3);
- >'aki' MySQL的>SELECT SUBSTRING('Sakila' FROM -4 FOR 2);
- >'ki'
此功能是多字节安全的。
如果
len
小于1,则结果为空字符串。
SUBSTRING_INDEX(
str
,delim
,count
)
str
在
count
出现分隔符
之前
从字符串返回子字符串
delim
。
如果
count
为正,则返回最终分隔符左侧的所有内容(从左侧开始计算)。
如果
count
是否定的,则返回最终分隔符右侧的所有内容(从右侧开始计算)。
SUBSTRING_INDEX()
搜索时执行区分大小写的匹配
delim
。
MySQL的>SELECT SUBSTRING_INDEX('www.mysql.com', '.', 2);
- >'www.mysql' MySQL的>SELECT SUBSTRING_INDEX('www.mysql.com', '.', -2);
- >'mysql.com'
此功能是多字节安全的。
将字符串参数转换为base-64编码形式,并将结果作为带有连接字符集和排序规则的字符串返回。
如果参数不是字符串,则在转换发生之前将其转换为字符串。
结果是
NULL
如果参数是
NULL
。
可以使用该
FROM_BASE64()
函数对
Base-64编码的字符串进行解码
。
MySQL的> SELECT TO_BASE64('abc'), FROM_BASE64(TO_BASE64('abc'));
- >'JWJj','abc'
存在不同的base-64编码方案。
这些是由所使用的编码和解码规则
TO_BASE64()
和
FROM_BASE64()
:
字母值62的编码是
'+'
。
字母值63的编码是
'/'
。
编码输出由4个可打印字符组成。
输入数据的每3个字节使用4个字符进行编码。
如果最后一个组不完整,则用
'='
字符
填充
长度为4。
在编码输出的每76个字符之后添加换行符以将长输出分成多行。
解码识别并忽略换行符,回车符,制表符和空格。
TRIM([{BOTH | LEADING | TRAILING}
[
,
remstr
] FROM]
str
)TRIM([
remstr
FROM] str
)
返回
删除
str
了所有
remstr
前缀或后缀
的字符串
。
如果没有给出说明符
BOTH
,
LEADING
或者
TRAILING
给出
BOTH
。
remstr
是可选的,如果未指定,则删除空格。
MySQL的>SELECT TRIM(' bar ');
- >'酒吧' MySQL的>SELECT TRIM(LEADING 'x' FROM 'xxxbarxxx');
- >'barxxx' MySQL的>SELECT TRIM(BOTH 'x' FROM 'xxxbarxxx');
- >'酒吧' MySQL的>SELECT TRIM(TRAILING 'xyz' FROM 'barxxyz');
- >'barx'
此功能是多字节安全的。
UCASE()
视图中使用的内容将被重写为
UPPER()
。
对于字符串参数
str
,
将
参数中的
每对字符解释为十六进制数,并将其转换为数字表示的字节。
返回值是二进制字符串。
UNHEX(
str
)
MySQL的>SELECT UNHEX('4D7953514C');
- >'MySQL' MySQL的>SELECT X'4D7953514C';
- >'MySQL' MySQL的>SELECT UNHEX(HEX('string'));
- >'string' MySQL的>SELECT HEX(UNHEX('1267'));
- >'1267'
在参数字符串中的字符必须是合法的十六进制数字:
'0'
...
'9'
,
'A'
...
'F'
,
'a'
...
'f'
。
如果参数包含任何非十六进制数字,则结果为
NULL
:
MySQL的> SELECT UNHEX('GG');
+ ------------- +
| UNHEX('GG')|
+ ------------- +
| NULL |
+ ------------- +
阿
NULL
可发生的结果,如果该参数
UNHEX()
是一
BINARY
,列,因为值是用0x00填充字节存储时,但这些字节不剥离上检索。
例如,
'41'
存储到
CHAR(3)
列中
'41 '
并作为
'41'
(带有尾随垫空间被剥离)
检索
,因此
UNHEX()
对于列值返回
'A'
。
相比之下
'41'
,存储在一
BINARY(3)
列中
'41\0'
并检索为
'41\0'
(尾部填充
0x00
字节未被剥离)。
'\0'
这不是一个合法的十六进制数字
UNHEX()
列值返回
NULL
。
对于数字参数
N
,
不执行
倒数
。
请
改用。
请参阅说明
。
HEX(
N
)UNHEX()
CONV(HEX(
N
),16,10)HEX()
返回
str
根据当前字符集映射将所有字符更改为大写
的字符串
。
默认是
utf8mb4
。
MySQL的> SELECT UPPER('Hej');
- >'HEJ'
有关
LOWER()
同样适用的信息,
请参阅说明
UPPER()
。
这包括有关如何执行二进制串的大小写转换信息(
BINARY
,
VARBINARY
,
BLOB
),用于这些功能是无效的,以及约壳体折叠的Unicode字符集的信息。
此功能是多字节安全的。
UCASE()
视图中使用的内容将被重写为
UPPER()
。
WEIGHT_STRING(
str
[AS {CHAR|BINARY}(N
)]
[flags
])
此函数返回输入字符串的权重字符串。 返回值是二进制字符串,表示字符串的比较和排序值。 它具有以下属性:
如果
=
,那么
(
并且
被认为是相等的)
WEIGHT_STRING(
str1
)WEIGHT_STRING(
str2
)str1
=
str2
str1
str2
如果
<
,则
(
之前排序
)
WEIGHT_STRING(
str1
)WEIGHT_STRING(
str2
)str1
<
str2
str1
str2
WEIGHT_STRING()
是一个供内部使用的调试功能。
它的行为可以在MySQL版本之间发生变化,
它可用于测试和调试排序规则,尤其是在添加新排序规则时。
请参见
第10.13节“将字符集添加到字符集”
。
该列表简要总结了这些论点。 列表后面的讨论中给出了更多细节。
str
:输入字符串表达式。
AS
子句:可选;
将输入字符串转换为给定的类型和长度。
flags
: 可选的;
没用过。
输入字符串
str
是字符串表达式。
如果输入是一个非二进制(字符)串,诸如
CHAR
,
VARCHAR
或
TEXT
值,则返回值将包含该字符串核对权重。
如果输入是二进制(字节)字符串,如a
BINARY
,
VARBINARY
或
BLOB
value,则返回值与输入相同(二进制字符串中每个字节的权重是字节值)。
如果输入是
NULL
,则
WEIGHT_STRING()
返回
NULL
。
例子:
mysql>SET @s = _utf8mb4 'AB' COLLATE utf8mb4_0900_ai_ci;
mysql>SELECT @s, HEX(@s), HEX(WEIGHT_STRING(@s));
+ ------ + --------- + ------------------------ + | @s | 十六进制(@s)| HEX(WEIGHT_STRING(@s))| + ------ + --------- + ------------------------ + | AB | 4142 | 1C471C60 | + ------ + --------- + ------------------------ +
mysql>SET @s = _utf8mb4 'ab' COLLATE utf8mb4_0900_ai_ci;
mysql>SELECT @s, HEX(@s), HEX(WEIGHT_STRING(@s));
+ ------ + --------- + ------------------------ + | @s | 十六进制(@s)| HEX(WEIGHT_STRING(@s))| + ------ + --------- + ------------------------ + | ab | 6162 | 1C471C60 | + ------ + --------- + ------------------------ +
mysql>SET @s = CAST('AB' AS BINARY);
mysql>SELECT @s, HEX(@s), HEX(WEIGHT_STRING(@s));
+ ------ + --------- + ------------------------ + | @s | 十六进制(@s)| HEX(WEIGHT_STRING(@s))| + ------ + --------- + ------------------------ + | AB | 4142 | 4142 | + ------ + --------- + ------------------------ +
mysql>SET @s = CAST('ab' AS BINARY);
mysql>SELECT @s, HEX(@s), HEX(WEIGHT_STRING(@s));
+ ------ + --------- + ------------------------ + | @s | 十六进制(@s)| HEX(WEIGHT_STRING(@s))| + ------ + --------- + ------------------------ + | ab | 6162 | 6162 | + ------ + --------- + ------------------------ +
前面的示例用于
HEX()
显示
WEIGHT_STRING()
结果。
因为结果是二进制值,
HEX()
当结果包含非打印值时,特别有用,以可打印的形式显示它:
mysql>SET @s = CONVERT(X'C39F' USING utf8) COLLATE utf8_czech_ci;
mysql>SELECT HEX(WEIGHT_STRING(@s));
+ ------------------------ + | HEX(WEIGHT_STRING(@s))| + ------------------------ + | 0FEA0FEA | + ------------------------ +
对于非
NULL
返回值,值的数据类型是
VARBINARY
其长度是否在最大长度内
VARBINARY
,否则数据类型为
BLOB
。
AS
可以给出
该
子句以将输入字符串转换为非二进制或二进制字符串并将其强制为给定长度:
AS CHAR(
将字符串强制转换为非二进制字符串,并将其填充在右侧,并使用空格填充一定长度的
N
)N
字符。
N
必须至少为1.如果
N
小于输入字符串的长度,则字符串将截断为
N
字符。
截断没有警告。
AS BINARY(
类似但是将字符串转换为二进制字符串,
N
)N
以字节(而不是字符)来度量,并且填充使用
0x00
字节(而不是空格)。
mysql>SET NAMES 'latin1';
mysql>SELECT HEX(WEIGHT_STRING('ab' AS CHAR(4)));
+ ------------------------------- + | HEX(WEIGHT_STRING('ab'AS CHAR(4)))| + ------------------------------- + | 41422020 | + ------------------------------- + mysql>SET NAMES 'utf8';
mysql>SELECT HEX(WEIGHT_STRING('ab' AS CHAR(4)));
+ ------------------------------- + | HEX(WEIGHT_STRING('ab'AS CHAR(4)))| + ------------------------------- + | 0041004200200020 | + ------------------------------- +
MySQL的> SELECT HEX(WEIGHT_STRING('ab' AS BINARY(4)));
+ --------------------------------------- +
| HEX(WEIGHT_STRING('ab'AS BINARY(4)))|
+ --------------------------------------- +
| 61620000 |
+ --------------------------------------- +
该
flags
条款目前尚未使用。
如果字符串函数被赋予二进制字符串作为参数,则结果字符串也是二进制字符串。 转换为字符串的数字被视为二进制字符串。 这仅影响比较。
通常,如果字符串比较中的任何表达式区分大小写,则以区分大小写的方式执行比较。
expr
LIKE pat
[ESCAPE
'escape_char
']
使用SQL模式进行模式匹配。
返回
1
(
TRUE
)或
0
(
FALSE
)。
如果是,
expr
或者
pat
是
NULL
,结果是
NULL
。
模式不必是文字字符串。 例如,它可以指定为字符串表达式或表列。
根据SQL标准,
LIKE
在每个字符的基础上执行匹配,因此它可以产生与
=
比较运算符
不同的结果
:
MySQL的>SELECT 'ä' LIKE 'ae' COLLATE latin1_german2_ci;
+ ----------------------------------------- + | 'ä'LIKE'ae'COLLATE latin1_german2_ci | + ----------------------------------------- + | 0 | + ----------------------------------------- + MySQL的>SELECT 'ä' = 'ae' COLLATE latin1_german2_ci;
+ -------------------------------------- + | 'ä'='ae'COLLATE latin1_german2_ci | + -------------------------------------- + | 1 | + -------------------------------------- +
特别是,尾随空格很重要,但
与
运营商
进行的比较
不符合
CHAR
或
VARCHAR
比较
=
:
MySQL的> SELECT 'a' = 'a ', 'a' LIKE 'a ';
+ ------------ + --------------- +
| 'a'='a'| 'a'喜欢'a'|
+ ------------ + --------------- +
| 1 | 0 |
+ ------------ + --------------- +
1排(0.00秒)
有了
LIKE
可以使用的图案以下两个通配符:
%
匹配任意数量的字符,甚至零个字符。
_
恰好匹配一个字符。
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
转义序列应为空或一个字符长。
表达式必须在执行时计算为常量。
如果
NO_BACKSLASH_ESCAPES
启用
了
SQL模式,则序列不能为空。
以下两个语句说明字符串比较不区分大小写,除非其中一个操作数区分大小写(使用区分大小写的排序规则或是二进制字符串):
MySQL的>SELECT 'abc' LIKE 'ABC';
- > 1 MySQL的>SELECT 'abc' LIKE _utf8mb4 'ABC' COLLATE utf8mb4_0900_as_cs;
- > 0 MySQL的>SELECT 'abc' LIKE _utf8mb4 'ABC' COLLATE utf8mb4_bin;
- > 0 MySQL的>SELECT 'abc' LIKE BINARY 'ABC';
- > 0
作为标准SQL的扩展,MySQL允许
LIKE
使用数字表达式。
MySQL的> SELECT 10 LIKE '1%';
- > 1
因为MySQL在字符串中使用C转义语法(例如,
\n
表示换行符),所以必须
\
将在
LIKE
字符串中
使用的
任何
一个
加倍
。
例如,要搜索
\n
,请将其指定为
\\n
。
要搜索
\
,请将其指定为
\\\\
;
这是因为反斜杠被解析器剥离一次,并且在进行模式匹配时再次剥离,留下一个反斜杠来匹配。
例外:在模式字符串的末尾,反斜杠可以指定为
\\
。
在字符串的末尾,反斜杠代表自己,因为没有任何东西可以逃脱。
假设一个表包含以下值:
MySQL的> SELECT filename FROM t1;
+ -------------- +
| 文件名|
+ -------------- +
| C:|
| C:\ |
| C:\ Programs |
| C:\ Programs \ |
+ -------------- +
要测试以反斜杠结尾的值,可以使用以下任一模式匹配值:
MySQL的>SELECT filename, filename LIKE '%\\' FROM t1;
+ -------------- + --------------------- + | 文件名| filename LIKE'%\\'| + -------------- + --------------------- + | C:| 0 | | C:\ | 1 | | C:\ Programs | 0 | | C:\ Programs \ | 1 | + -------------- + --------------------- + MySQL的>SELECT filename, filename LIKE '%\\\\' FROM t1;
+ -------------- + ----------------------- + | 文件名| 文件名LIKE'%\\\\'| + -------------- + ----------------------- + | C:| 0 | | C:\ | 1 | | C:\ Programs | 0 | | C:\ Programs \ | 1 | + -------------- + ----------------------- +
expr
NOT LIKE pat
[ESCAPE
'escape_char
']
这是一样的
。
NOT
(
expr
LIKE
pat
[ESCAPE
'escape_char
'])
涉及
NOT
LIKE
与包含列的比较的
聚合查询
NULL
可能会产生意外结果。
例如,请考虑以下表格和数据:
CREATE TABLE foo(bar VARCHAR(10)); INSERT INTO foo VALUES(NULL),(NULL);
查询
SELECT COUNT(*) FROM foo WHERE bar LIKE
'%baz%';
返回
0
。
你可能会认为
SELECT COUNT(*) FROM foo WHERE bar
NOT LIKE '%baz%';
会返回
2
。
但是,情况并非如此:第二个查询返回
0
。
这是因为
无论价值如何,
总是返回
。
对于涉及
和使用
或的
比较的
聚合查询也是如此
。
在这种情况下,您必须明确测试
使用
(而不是
),如下所示:
NULL NOT LIKE
expr
NULL
expr
NULL
NOT
RLIKE
NOT
REGEXP
NOT NULL
OR
AND
SELECT COUNT(*)FROM foo WHERE bar NOT LIKE'%baz%'或bar is NULL;
STRCMP()
0
如果字符串相同,
-1
如果第一个参数根据当前排序顺序小于第二个参数
,
则
返回
,
1
否则返回。
MySQL的>SELECT STRCMP('text', 'text2');
- > -1 MySQL的>SELECT STRCMP('text2', 'text');
- > 1 MySQL的>SELECT STRCMP('text', 'text');
- > 0
STRCMP()
使用参数的排序规则执行比较。
mysql>SET @s1 = _utf8mb4 'x' COLLATE utf8mb4_0900_ai_ci;
mysql>SET @s2 = _utf8mb4 'X' COLLATE utf8mb4_0900_ai_ci;
mysql>SET @s3 = _utf8mb4 'x' COLLATE utf8mb4_0900_as_cs;
mysql>SET @s4 = _utf8mb4 'X' COLLATE utf8mb4_0900_as_cs;
mysql>SELECT STRCMP(@s1, @s2), STRCMP(@s3, @s4);
+ ------------------ + ------------------ + | STRCMP(@ s1,@ s2)| STRCMP(@ s3,@ s4)| + ------------------ + ------------------ + | 0 | -1 | + ------------------ + ------------------ +
如果排序规则不兼容,则必须将其中一个参数转换为与另一个相互兼容。 请参见 第10.8.4节“表达式中的校对强制性” 。
mysql> SET @ s1 = _utf8mb4'x'COLLATE utf8mb4_0900_ai_ci; mysql> SET @ s2 = _utf8mb4'X'COLLATE utf8mb4_0900_ai_ci; mysql> SET @ s3 = _utf8mb4'x'COLLATE utf8mb4_0900_as_cs; mysql> SET @ s4 = _utf8mb4'X'COLLATE utf8mb4_0900_as_cs; - > MySQL的>SELECT STRCMP(@s1, @s3);
ERROR 1267(HY000):非法混合排序(utf8mb4_0900_ai_ci,IMPLICIT) 和(utf8mb4_0900_as_cs,IMPLICIT)用于操作'strcmp' MySQL的>SELECT STRCMP(@s1, @s3 COLLATE utf8mb4_0900_ai_ci);
+ --------------------------------------------- + | STRCMP(@ s1,@ s3 COLLATE utf8mb4_0900_ai_ci)| + --------------------------------------------- + | 0 | + --------------------------------------------- +
表12.9正则表达式函数和运算符
名称 | 描述 |
---|---|
NOT REGEXP |
REGEXP的否定 |
REGEXP |
string是否匹配正则表达式 |
REGEXP_INSTR() |
匹配正则表达式的子串的起始索引 |
REGEXP_LIKE() |
string是否匹配正则表达式 |
REGEXP_REPLACE() |
替换匹配正则表达式的子字符串 |
REGEXP_SUBSTR() |
返回子串匹配正则表达式 |
RLIKE |
string是否匹配正则表达式 |
正则表达式是为复杂搜索指定模式的强大方法。 本节讨论可用于正则表达式匹配的函数和运算符,并通过示例说明可用于正则表达式运算的一些特殊字符和构造。 另请参见 第3.3.4.7节“模式匹配” 。
MySQL使用国际Unicode组件(ICU)实现正则表达式支持,ICU提供完整的Unicode支持并且是多字节安全的。 (在MySQL 8.0.4之前,MySQL使用Henry Spencer的正则表达式实现,它以字节方式运行并且不是多字节安全的。有关使用正则表达式的应用程序可能受实现更改影响的方式的信息,请参阅 正则表达式兼容性注意事项 。)
,
expr
NOT REGEXP pat
expr
NOT RLIKE pat
这是一样的
。
NOT
(
expr
REGEXP
pat
)
,
expr
REGEXP pat
expr
RLIKE pat
如果字符串
expr
与模式指定的正则表达式匹配,则
返回1,否则返回
pat
0。
如果
expr
或者
pat
是
NULL
,返回值是
NULL
。
REGEXP
并且
RLIKE
是同义词
REGEXP_LIKE()
。
有关如何进行匹配的其他信息,请参阅说明
REGEXP_LIKE()
。
MySQL的>SELECT 'Michael!' REGEXP '.*';
+ ------------------------ + | “迈克尔!” REGEXP'。*'| + ------------------------ + | 1 | + ------------------------ + MySQL的>SELECT 'new*\n*line' REGEXP 'new\\*.\\*line';
+ --------------------------------------- + | 'new * \ n * line'REGEXP'new \\ *。\\ * line'| + --------------------------------------- + | 0 | + --------------------------------------- + MySQL的>SELECT 'a' REGEXP '^[a-d]';
+ --------------------- + | 'a'REGEXP'^ [ad]'| + --------------------- + | 1 | + --------------------- + MySQL的>SELECT 'a' REGEXP 'A', 'a' REGEXP BINARY 'A';
+ ---------------- + ----------------------- + | 'a'REGEXP'A'| 'a'REGEXP BINARY'A'| + ---------------- + ----------------------- + | 1 | 0 | + ---------------- + ----------------------- +
REGEXP_INSTR(
expr
,
pat
[,
pos
[,
occurrence
[,
return_option
[,
match_type
]]]])
返回与
expr
模式指定的正则表达式匹配
的字符串子字符串的起始索引
pat
,如果没有匹配则返回0。
如果
expr
或者
pat
是
NULL
,返回值是
NULL
。
字符索引从1开始。
REGEXP_INSTR()
采用这些可选参数:
pos
:
expr
开始搜索的位置。
如果省略,则默认值为1。
occurrence
:要搜索哪个匹配项。
如果省略,则默认值为1。
return_option
:返回哪种类型的职位。
如果此值为0,则
REGEXP_INSTR()
返回匹配的子字符串的第一个字符的位置。
如果此值为1,则
REGEXP_INSTR()
返回匹配的子字符串后面的位置。
如果省略,则默认值为0。
match_type
:一个字符串,指定如何执行匹配。
含义如上所述
REGEXP_LIKE()
。
有关如何进行匹配的其他信息,请参阅说明
REGEXP_LIKE()
。
MySQL的>SELECT REGEXP_INSTR('dog cat dog', 'dog');
+ ------------------------------------ + | REGEXP_INSTR('狗猫狗','狗')| + ------------------------------------ + | 1 | + ------------------------------------ + MySQL的>SELECT REGEXP_INSTR('dog cat dog', 'dog', 2);
+ --------------------------------------- + | REGEXP_INSTR('狗猫狗','狗',2)| + --------------------------------------- + | 9 | + --------------------------------------- + MySQL的>SELECT REGEXP_INSTR('aa aaa aaaa', 'a{2}');
+ ------------------------------- + | REGEXP_INSTR('aa aaa aaaa','a {2}')| + ------------------------------- + | 1 | + ------------------------------- + MySQL的>SELECT REGEXP_INSTR('aa aaa aaaa', 'a{4}');
+ ------------------------------- + | REGEXP_INSTR('aa aaa aaaa','a {4}')| + ------------------------------- + | 8 | + ------------------------------- +
REGEXP_LIKE(
expr
,
pat
[,
match_type
])
如果字符串
expr
与模式指定的正则表达式匹配,则
返回1,否则返回
pat
0。
如果
expr
或者
pat
是
NULL
,返回值是
NULL
。
该模式可以是扩展的正则表达式,其语法在 正则表达式语法中 讨论 。 模式不必是文字字符串。 例如,它可以指定为字符串表达式或表列。
可选
match_type
参数是一个字符串,可以包含指定如何执行匹配的任何或所有以下字符:
c
:区分大小写的匹配。
i
:不区分大小写的匹配。
m
:多行模式。
识别字符串中的行终止符。
默认行为是仅在字符串表达式的开头和结尾处匹配行终止符。
n
:
.
字符匹配行终止符。
默认设置是
.
匹配以在行尾停止。
u
:仅限Unix的行结尾。
只有换行字符识别为结束一条线
.
,
^
以及
$
匹配运算符。
如果在其中指定了指定矛盾选项的字符
match_type
,则最右边的
字符
优先。
默认情况下,正则表达式操作
在决定字符类型和执行比较时
使用
expr
和
pat
参数
的字符集和排序规则
。
如果参数具有不同的字符集或排序规则,则应用强制性规则,如
第10.8.4节“表达式中的排序规范性”中所述
。
可以使用显式排序规则指定参数来更改比较行为。
MySQL的>SELECT REGEXP_LIKE('CamelCase', 'CAMELCASE');
+ --------------------------------------- + | REGEXP_LIKE('CamelCase','CAMELCASE')| + --------------------------------------- + | 1 | + --------------------------------------- + MySQL的>SELECT REGEXP_LIKE('CamelCase', 'CAMELCASE' COLLATE utf8mb4_0900_as_cs);
+ ------------------------------------------------- ----------------- + | REGEXP_LIKE('CamelCase','CAMELCASE'COLLATE utf8mb4_0900_as_cs)| + ------------------------------------------------- ----------------- + | 0 | + ------------------------------------------------- ----------------- +
match_type
可以使用
c
或
i
字符
指定
覆盖默认区分大小写。
例外:如果任一参数是二进制字符串,则参数将以区分大小写的方式处理为二进制字符串,即使
match_type
包含该
i
字符也是如此。
因为MySQL在字符串中使用C转义语法(例如,
\n
表示换行符),所以必须
\
将您在
expr
和
pat
参数中
使用的
任何
一个
加倍
。
MySQL的>SELECT REGEXP_LIKE('Michael!', '.*');
+ ------------------------------- + | REGEXP_LIKE('迈克尔!','。*')| + ------------------------------- + | 1 | + ------------------------------- + MySQL的>SELECT REGEXP_LIKE('new*\n*line', 'new\\*.\\*line');
+ ---------------------------------------------- + | REGEXP_LIKE('new * \ n * line','new \\ *。\\ * line')| + ---------------------------------------------- + | 0 | + ---------------------------------------------- + MySQL的>SELECT REGEXP_LIKE('a', '^[a-d]');
+ ---------------------------- + | REGEXP_LIKE('a','^ [ad]')| + ---------------------------- + | 1 | + ---------------------------- + MySQL的>SELECT REGEXP_LIKE('a', 'A'), REGEXP_LIKE('a', BINARY 'A');
+ ----------------------- + ------------------------- ----- + | REGEXP_LIKE('a','A')| REGEXP_LIKE('a',BINARY'A')| + ----------------------- + ------------------------- ----- + | 1 | 0 | + ----------------------- + ------------------------- ----- +
MySQL的>SELECT REGEXP_LIKE('abc', 'ABC');
+ --------------------------- + | REGEXP_LIKE('abc','ABC')| + --------------------------- + | 1 | + --------------------------- + MySQL的>SELECT REGEXP_LIKE('abc', 'ABC', 'c');
+ -------------------------------- + | REGEXP_LIKE('abc','ABC','c')| + -------------------------------- + | 0 | + -------------------------------- +
REGEXP_REPLACE(
expr
,
pat
,
repl
[,
pos
[,
occurrence
[,
match_type
]]])
将字符串
expr
中与模式指定的正则表达式匹配的匹配项
pat
替换为替换字符串
repl
,并返回结果字符串。
如果
expr
,
pat
或者
repl
就是
NULL
,返回值
NULL
。
REGEXP_REPLACE()
采用这些可选参数:
pos
:
expr
开始搜索的位置。
如果省略,则默认值为1。
occurrence
:要替换哪个匹配项。
如果省略,则默认值为0(表示
“
替换所有出现次数
”
)。
match_type
:一个字符串,指定如何执行匹配。
含义如上所述
REGEXP_LIKE()
。
在MySQL 8.0.17之前,此函数返回的结果使用了
UTF-16
字符集;
在MySQL 8.0.17及更高版本中,使用搜索匹配的表达式的字符集和排序规则。
(Bug#94203,Bug#29308212)
有关如何进行匹配的其他信息,请参阅说明
REGEXP_LIKE()
。
MySQL的>SELECT REGEXP_REPLACE('a b c', 'b', 'X');
+ ----------------------------------- + | REGEXP_REPLACE('ab c','b','X')| + ----------------------------------- + | 一个X c | + ----------------------------------- + MySQL的>SELECT REGEXP_REPLACE('abc def ghi', '[a-z]+', 'X', 1, 3);
+ ------------------------------------------------- --- + | REGEXP_REPLACE('abc def ghi','[az] +','X',1,3)| + ------------------------------------------------- --- + | abc def X | + ------------------------------------------------- --- +
REGEXP_SUBSTR(
expr
,
pat
[,
pos
[,
occurrence
[,
match_type
]]])
如果没有匹配
,
则
返回与
expr
模式指定的正则表达式匹配
的字符串的子字符串
。
如果
或者
是
,返回值是
。
pat
NULL
expr
pat
NULL
NULL
REGEXP_SUBSTR()
采用这些可选参数:
pos
:
expr
开始搜索的位置。
如果省略,则默认值为1。
occurrence
:要搜索哪个匹配项。
如果省略,则默认值为1。
match_type
:一个字符串,指定如何执行匹配。
含义如上所述
REGEXP_LIKE()
。
在MySQL 8.0.17之前,此函数返回的结果使用了
UTF-16
字符集;
在MySQL 8.0.17及更高版本中,使用搜索匹配的表达式的字符集和排序规则。
(Bug#94203,Bug#29308212)
有关如何进行匹配的其他信息,请参阅说明
REGEXP_LIKE()
。
MySQL的>SELECT REGEXP_SUBSTR('abc def ghi', '[a-z]+');
+ ---------------------------------------- + | REGEXP_SUBSTR('abc def ghi','[az] +')| + ---------------------------------------- + | abc | + ---------------------------------------- + MySQL的>SELECT REGEXP_SUBSTR('abc def ghi', '[a-z]+', 1, 3);
+ ---------------------------------------------- + | REGEXP_SUBSTR('abc def ghi','[az] +',1,3)| + ---------------------------------------------- + | ghi | + ---------------------------------------------- +
正则表达式描述了一组字符串。
最简单的正则表达式是其中没有特殊字符的表达式。
例如,正则表达式
hello
匹配
hello
,没有别的。
非平凡的正则表达式使用某些特殊结构,以便它们可以匹配多个字符串。
例如,正则表达式
hello|world
包含
|
交替运算符并匹配
hello
或
world
。
作为一个更复杂的实例中,正则表达式
B[an]*s
匹配的任何串的
Bananas
,
Baaaaas
,
Bs
,和任何其他字符串开头的
B
,与结束
s
,和含有任何数目的
a
或
n
在字符之间。
以下列表介绍了可在正则表达式中使用的一些基本特殊字符和构造。 有关用于实现正则表达式支持的ICU库支持的完整正则表达式语法的信息,请访问 International Components for Unicode网站 。
^
匹配字符串的开头。
mysql>SELECT REGEXP_LIKE('fo\nfo', '^fo$');
- > 0 mysql>SELECT REGEXP_LIKE('fofo', '^fo');
- > 1
$
匹配字符串的结尾。
mysql>SELECT REGEXP_LIKE('fo\no', '^fo\no$');
- > 1 mysql>SELECT REGEXP_LIKE('fo\no', '^fo$');
- > 0
.
匹配任何字符(包括回车符和换行符,但要在字符串中间匹配这些字符,
必须给出
m
(多行)匹配控制字符或
(?m)
模式内修饰符)。
mysql>SELECT REGEXP_LIKE('fofo', '^f.*$');
- > 1 mysql>SELECT REGEXP_LIKE('fo\r\nfo', '^f.*$');
- > 0 mysql>SELECT REGEXP_LIKE('fo\r\nfo', '^f.*$', 'm');
- > 1 mysql>SELECT REGEXP_LIKE('fo\r\nfo', '(?m)^f.*$');
- > 1
a*
匹配零个或多个
a
字符的
任何序列
。
mysql>SELECT REGEXP_LIKE('Ban', '^Ba*n');
- > 1 mysql>SELECT REGEXP_LIKE('Baaan', '^Ba*n');
- > 1 mysql>SELECT REGEXP_LIKE('Bn', '^Ba*n');
- > 1
a+
匹配一个或多个
a
字符的
任何序列
。
mysql>SELECT REGEXP_LIKE('Ban', '^Ba+n');
- > 1 mysql>SELECT REGEXP_LIKE('Bn', '^Ba+n');
- > 0
a?
匹配零个或一个
a
字符。
mysql>SELECT REGEXP_LIKE('Bn', '^Ba?n');
- > 1 mysql>SELECT REGEXP_LIKE('Ban', '^Ba?n');
- > 1 mysql>SELECT REGEXP_LIKE('Baan', '^Ba?n');
- > 0
de|abc
轮换;
匹配任一序列
de
或
abc
。
mysql>SELECT REGEXP_LIKE('pi', 'pi|apa');
- > 1 mysql>SELECT REGEXP_LIKE('axe', 'pi|apa');
- > 0 mysql>SELECT REGEXP_LIKE('apa', 'pi|apa');
- > 1 mysql>SELECT REGEXP_LIKE('apa', '^(pi|apa)$');
- > 1 mysql>SELECT REGEXP_LIKE('pi', '^(pi|apa)$');
- > 1 mysql>SELECT REGEXP_LIKE('pix', '^(pi|apa)$');
- > 0
(abc)*
匹配序列的零个或多个实例
abc
。
mysql>SELECT REGEXP_LIKE('pi', '^(pi)*$');
- > 1 mysql>SELECT REGEXP_LIKE('pip', '^(pi)*$');
- > 0 mysql>SELECT REGEXP_LIKE('pipi', '^(pi)*$');
- > 1
{1}
,
{2,3}
重复;
和
表示法提供了一种更通用的方法来编写正则表达式,这些正则表达式匹配模式的前一个原子(或
“
片段
”
)的
多次出现
。
并且
是整数。
{
n
}{
m
,n
}m
n
a*
可以写成
a{0,}
。
a+
可以写成
a{1,}
。
a?
可以写成
a{0,1}
。
更确切地说,
匹配完全匹配的
实例
。
匹配
或更多的实例
。
通过
实例
匹配
,包括在内。
如果两个
和
给出,
必须小于或等于
。
a{
n
}n
a
a{
n
,}n
a
a{
m
,n
}m
n
a
m
n
m
n
mysql>SELECT REGEXP_LIKE('abcde', 'a[bcd]{2}e');
- > 0 mysql>SELECT REGEXP_LIKE('abcde', 'a[bcd]{3}e');
- > 1 mysql>SELECT REGEXP_LIKE('abcde', 'a[bcd]{1,10}e');
- > 1
[a-dX]
,
[^a-dX]
匹配任何字符,该字符(或不是,如果
^
被使用)任一
a
,
b
,
c
,
d
或
X
。
甲
-
其它两个字符之间的字符形成一个所有字符从所述第一字符向所述第二匹配范围。
例如,
[0-9]
匹配任何十进制数字。
要包含文字
]
字符,它必须紧跟在左括号后面
[
。
要包含文字
-
字符,必须先写入或最后写入。
任何在a内没有特定含义的字符
[]
对只匹配自己。
mysql>SELECT REGEXP_LIKE('aXbc', '[a-dXYZ]');
- > 1 mysql>SELECT REGEXP_LIKE('aXbc', '^[a-dXYZ]$');
- > 0 mysql>SELECT REGEXP_LIKE('aXbc', '^[a-dXYZ]+$');
- > 1 mysql>SELECT REGEXP_LIKE('aXbc', '^[^a-dXYZ]+$');
- > 0 mysql>SELECT REGEXP_LIKE('gheis', '^[^a-dXYZ]+$');
- > 1 mysql>SELECT REGEXP_LIKE('gheisa', '^[^a-dXYZ]+$');
- > 0
[=character_class=]
在括号表达式(使用
[
和
编写
]
)中,
[=character_class=]
表示等价类。
它匹配具有相同排序值的所有字符,包括其自身。
例如,如果
o
和
(+)
是一个等价类的成员,
[[=o=]]
,
[[=(+)=]]
,和
[o(+)]
都是同义。
等价类不能用作范围的端点。
[:character_class:]
在括号表达式(使用
[
和
编写
]
)中,
[:character_class:]
表示与属于该类的所有字符匹配的字符类。
下表列出了标准类名。
这些名称代表
ctype(3)
手册页中
定义的字符类
。
特定区域设置可以提供其他类名。
字符类不能用作范围的端点。
字符类名称 | 含义 |
---|---|
alnum |
字母数字字符 |
alpha |
字母字符 |
blank |
空白字符 |
cntrl |
控制字符 |
digit |
数字字符 |
graph |
图形字符 |
lower |
小写字母字符 |
print |
图形或空格字符 |
punct |
标点字符 |
space |
空格,制表符,换行符和回车符 |
upper |
大写字母字符 |
xdigit |
十六进制数字字符 |
mysql>SELECT REGEXP_LIKE('justalnums', '[[:alnum:]]+');
- > 1 mysql>SELECT REGEXP_LIKE('!!', '[[:alnum:]]+');
- > 0
要在正则表达式中使用特殊字符的文字实例,请在其前面加上两个反斜杠(\)字符。
MySQL解析器解释其中一个反斜杠,正则表达式库解释另一个反斜杠。
例如,要匹配
1+2
包含特殊
+
字符
的字符串
,只有以下正则表达式中的最后一个是正确的:
mysql>SELECT REGEXP_LIKE('1+2', '1+2');
- > 0 mysql>SELECT REGEXP_LIKE('1+2', '1\+2');
- > 0 mysql>SELECT REGEXP_LIKE('1+2', '1\\+2');
- > 1
REGEXP_LIKE()
和类似的函数使用可以通过设置系统变量来控制的资源:
匹配引擎将内存用于其内部堆栈。
要以字节为单位控制堆栈的最大可用内存,请设置
regexp_stack_limit
系统变量。
匹配引擎分步运行。
要控制引擎执行的最大步数(以及间接执行时间),请设置
regexp_time_limit
系统变量。
由于此限制表示为步数,因此仅间接影响执行时间。
通常,它大约为毫秒。
在MySQL 8.0.4之前,MySQL使用Henry Spencer正则表达式库来支持正则表达式操作,而不是使用Unicode的国际组件(ICU)。 以下讨论描述了可能影响应用程序的Spencer和ICU库之间的差异:
使用Spencer库,
REGEXP
和
RLIKE
运算符以字节方式工作,因此它们不是多字节安全的,并且可能会产生多字节字符集的意外结果。
此外,这些运算符通过字节值比较字符,并且即使给定的排序规则将重音字符视为相等,重音字符也可能无法比较。
ICU具有完整的Unicode支持并且是多字节安全的。
它的正则表达式函数将所有字符串视为
UTF-16
。
您应该记住,位置索引基于16位块而不是代码点。
这意味着,当传递给这些函数时,使用多个块的字符可能会产生意外结果,如下所示:
MySQL的>SELECT REGEXP_INSTR('🍣🍣b', 'b');
+ -------------------------- + | REGEXP_INSTR('?? b','b')| + -------------------------- + | 5 | + -------------------------- + 1排(0.00秒) MySQL的>SELECT REGEXP_INSTR('🍣🍣bxxx', 'b', 4);
+ -------------------------------- + | REGEXP_INSTR('?? bxxx','b',4)| + -------------------------------- + | 5 | + -------------------------------- + 1排(0.00秒)
Unicode基本多语言平面中的字符(包括大多数现代语言使用的字符)在这方面是安全的:
MySQL的>SELECT REGEXP_INSTR('бжb', 'b');
+ ---------------------------- + | REGEXP_INSTR('бжb','b')| + ---------------------------- + | 3 | + ---------------------------- + 1排(0.00秒) MySQL的>SELECT REGEXP_INSTR('עבb', 'b');
+ ---------------------------- + | REGEXP_INSTR('עבb','b')| + ---------------------------- + | 3 | + ---------------------------- + 1排(0.00秒) MySQL的>SELECT REGEXP_INSTR('µå周çб', '周');
+ ------------------------------------ + | REGEXP_INSTR('μå周çб','周')| + ------------------------------------ + | 3 | + ------------------------------------ + 1排(0.00秒)
表情符号,例如
前两个例子中使用
的
“
寿司
”
字符
🍣
(U + 1F363),不包括在基本多语言平面中,而是包含在Unicode的辅助多语言平面中。
表情符号和其他4字节字符可能会出现另一个问题
REGEXP_SUBSTR()
或类似的功能开始在角色中间搜索。
以下示例中的两个语句中的每一个都从第一个参数中的第二个2字节位置开始。
第一个语句适用于仅由2字节(BMP)字符组成的字符串。
第二个语句包含4字节字符,这些字符在结果中被错误地解释,因为前两个字节被剥离,因此字符数据的其余部分未对齐。
MySQL的>SELECT REGEXP_SUBSTR('周周周周', '.*', 2);
+ ---------------------------------------- + | REGEXP_SUBSTR('周周周周','。*',2)| + ---------------------------------------- + | 周周周| + ---------------------------------------- + 1排(0.00秒) MySQL的>SELECT REGEXP_SUBSTR('🍣🍣🍣🍣', '.*', 2);
+ -------------------------------- + | REGEXP_SUBSTR('????','。*',2)| + -------------------------------- + | ?㳟揘㳟揘㳟揘| + -------------------------------- + 1排(0.00秒)
对于
.
运算符,Spencer库将字符串终止符(回车符,换行符)与字符串表达式中的任何位置匹配,包括在中间。
要匹配字符串中间的行终止符和ICU,请指定
m
匹配控制字符。
Spencer库支持单词开头和单词结束边界标记(
[[:<:]]
以及
[[:>:]]
表示法)。
ICU没有。
对于ICU,您可以使用
\b
匹配字边界;
加倍反斜杠,因为MySQL将其解释为字符串中的转义字符。
Spencer库支持整理元素括号表达式(
[.characters.]
表示法)。
ICU没有。
对于重复计数(
{n}
和
{m,n}
表示法),Spencer库最多为255.虽然可以通过设置
regexp_time_limit
系统变量
来限制匹配引擎步骤的最大数量,但ICU没有此限制
。
ICU将括号解释为元字符。
要
(
在正则表达式中
指定文字左括号
,必须对其进行转义:
MySQL的>SELECT REGEXP_LIKE('(', '(');
ERROR 3692(HY000):正则表达式中的括号不匹配。 MySQL的>SELECT REGEXP_LIKE('(', '\\(');
+ ------------------------- + | REGEXP_LIKE('(','\\(')| + ------------------------- + | 1 | + ------------------------- +
MySQL有许多返回字符串的运算符和函数。 本节回答了这样一个问题:这种字符串的字符集和整理是什么?
对于采用字符串输入并将字符串结果作为输出返回的简单函数,输出的字符集和排序规则与主输入值的字符集和排序规则相同。
例如,
返回一个字符串和排序规则相同的字符串
。
这同样适用于
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,和
。
UPPER(
X
)X
INSTR()
LCASE()
LOWER()
LTRIM()
MID()
REPEAT()
REPLACE()
REVERSE()
RIGHT()
RPAD()
RTRIM()
SOUNDEX()
SUBSTRING()
TRIM()
UCASE()
UPPER()
REPLACE()
与所有其他函数不同,
该
函数始终忽略字符串输入的排序规则并执行区分大小写的比较。
如果字符串输入或函数结果是二进制字符串,则该字符串具有
binary
字符集和排序规则。
这可以通过使用
CHARSET()
和
COLLATION()
函数
来检查
,这两个函数都返回
binary
二进制字符串参数:
MySQL的> SELECT CHARSET(BINARY 'a'), COLLATION(BINARY 'a');
+ --------------------- + ----------------------- +
| CHARSET(BINARY'a')| COLLATION(BINARY'a')|
+ --------------------- + ----------------------- +
| 二进制| 二进制|
+ --------------------- + ----------------------- +
对于组合多个字符串输入并返回单个字符串输出的操作, 标准SQL 的 “ 聚合规则 ” 适用于确定结果的排序 规则 :
如果发生显式
,请使用
。
COLLATE
Y
Y
如果显式
且
发生,则引发错误。
COLLATE
Y
COLLATE
Z
否则,如果所有归类都是
Y
,请使用
Y
。
否则,结果没有排序规则。
例如,使用
,得到的校对是
。
这同样适用于
,
,
,
,
,
,和
。
CASE ... WHEN a THEN b WHEN b THEN c
COLLATE
X
ENDX
UNION
||
CONCAT()
ELT()
GREATEST()
IF()
LEAST()
对于转换为字符数据的操作,字符集和从该操作得到的字符串核对由定义
character_set_connection
和
collation_connection
用于确定默认的连接字符集和归类的系统变量(见
第10.4节,“连接字符集和校对”
) 。
这仅适用于
BIN_TO_UUID()
,
CAST()
,
CONV()
,
FORMAT()
,
HEX()
,和
SPACE()
。
对于虚拟生成列的表达式,会出现前一个原则的例外情况。
在这样的表达式中,表的字符集被用于
BIN_TO_UUID()
,
CONV()
或
HEX()
结果,而不管连接字符集。
如果对字符串函数返回的结果的字符集或排序规则有任何疑问,请使用
CHARSET()
或
COLLATION()
函数查找:
MySQL的>SELECT USER(), CHARSET(USER()), COLLATION(USER());
+ ---------------- + ----------------- + -------------- ----- + | USER()| CHARSET(USER())| COLLATION(USER())| + ---------------- + ----------------- + -------------- ----- + | 测试@ localhost | utf8 | utf8_general_ci | + ---------------- + ----------------- + -------------- ----- + MySQL的>SELECT CHARSET(COMPRESS('abc')), COLLATION(COMPRESS('abc'));
+ -------------------------- + ---------------------- ------ + | CHARSET(COMPRESS('abc'))| COLLATION(COMPRESS('abc'))| + -------------------------- + ---------------------- ------ + | 二进制| 二进制| + -------------------------- + ---------------------- ------ +
表12.10数字函数和运算符
名称 | 描述 |
---|---|
ABS() |
返回绝对值 |
ACOS() |
返回反余弦 |
ASIN() |
返回圆弧正弦 |
ATAN() |
返回反正切 |
ATAN2()
,
ATAN()
|
返回两个参数的反正切 |
CEIL() |
返回不小于参数的最小整数值 |
CEILING() |
返回不小于参数的最小整数值 |
CONV() |
转换不同数字基数之间的数字 |
COS() |
返回余弦 |
COT() |
归还余切 |
CRC32() |
计算循环冗余校验值 |
DEGREES() |
将弧度转换为度数 |
DIV |
整数除法 |
/ |
分部运营商 |
EXP() |
提升到的力量 |
FLOOR() |
返回不大于参数的最大整数值 |
LN() |
返回参数的自然对数 |
LOG() |
返回第一个参数的自然对数 |
LOG10() |
返回参数的以10为底的对数 |
LOG2() |
返回参数的base-2对数 |
- |
减号运算符 |
MOD() |
归还剩下的 |
%
,
MOD
|
模数运算符 |
PI() |
返回pi的值 |
+ |
加法运算符 |
POW() |
将引发的参数返回到指定的幂 |
POWER() |
将引发的参数返回到指定的幂 |
RADIANS() |
返回参数转换为弧度 |
RAND() |
返回随机浮点值 |
ROUND() |
围绕论点 |
SIGN() |
返回参数的符号 |
SIN() |
返回参数的正弦值 |
SQRT() |
返回参数的平方根 |
TAN() |
返回参数的正切值 |
* |
乘法运算符 |
TRUNCATE() |
截断到指定的小数位数 |
- |
更改参数的符号 |
通常的算术运算符可用。 结果根据以下规则确定:
如果两个操作数都是整数且其中任何一个都是无符号的,则结果是无符号整数。
对于减法,如果
NO_UNSIGNED_SUBTRACTION
启用
了
SQL模式,即使任何操作数未签名,结果也会被签名。
在执行的除法中
/
,使用两个精确值操作数时的结果比例是第一个操作数的比例加上
div_precision_increment
系统变量
的值
(默认为4)。
例如,表达式的结果
5.05 / 0.014
具有六个小数位(
360.714286
)
的比例
。
这些规则适用于每个操作,因此嵌套计算意味着每个组件的精度。
因此,
(14620 / 9432456) / (24250 / 9432456)
首先解析
(0.0014) / (0.0026)
,最终结果有8个小数位(
0.60288653
)。
由于这些规则及其应用方式,应注意确保计算的组件和子组件使用适当的精度级别。 请参见 第12.10节“强制转换函数和运算符” 。
有关在数值表达式求值中处理溢出的信息,请参见 第11.2.6节“超出范围和溢出处理” 。
算术运算符适用于数字。
对于其他类型的值,可以使用替代操作。
例如,要添加日期值,请使用
DATE_ADD()
;
请参见
第12.7节“日期和时间函数”
。
加成:
MySQL的> SELECT 3+5;
- > 8
减法:
MySQL的> SELECT 3-5;
- > -2
一元减。 此运算符更改操作数的符号。
MySQL的> SELECT - 2;
- > -2
乘法:
MySQL的>SELECT 3*5;
- > 15 MySQL的>SELECT 18014398509481984*18014398509481984.0;
- > 324518553658426726783156020576256.0 MySQL的>SELECT 18014398509481984*18014398509481984;
- >超出范围的错误
最后一个表达式产生错误,因为整数乘法的结果超过了64位
BIGINT
计算
范围
。
(参见
第11.2节“数字类型”
。)
师:
MySQL的> SELECT 3/5;
- > 0.60
除以零产生
NULL
结果:
MySQL的> SELECT 102/(1-1);
- > NULL
BIGINT
仅当在其结果转换为整数的上下文中执行时,才
使用
算术
计算除法
。
整数除法。 从除法中丢弃会导致小数点右边的任何小数部分。
如果任一操作数具有非整数类型,则
在将结果转换为之前
,操作数将转换为
DECIMAL
并使用
DECIMAL
算术进行
除法
BIGINT
。
如果结果超出
BIGINT
范围,则会发生错误。
MySQL的> SELECT 5 DIV 2, -5 DIV 2, 5 DIV -2, -5 DIV -2;
- > 2,-2,-2,2
模数运算。
返回
N
除以
的余数
M
。
欲了解更多信息,请参阅说明
MOD()
功能
节12.6.2,“数学函数”
。
表12.12数学函数
名称 | 描述 |
---|---|
ABS() |
返回绝对值 |
ACOS() |
返回反余弦 |
ASIN() |
返回圆弧正弦 |
ATAN() |
返回反正切 |
ATAN2()
,
ATAN()
|
返回两个参数的反正切 |
CEIL() |
返回不小于参数的最小整数值 |
CEILING() |
返回不小于参数的最小整数值 |
CONV() |
转换不同数字基数之间的数字 |
COS() |
返回余弦 |
COT() |
归还余切 |
CRC32() |
计算循环冗余校验值 |
DEGREES() |
将弧度转换为度数 |
EXP() |
提升到的力量 |
FLOOR() |
返回不大于参数的最大整数值 |
LN() |
返回参数的自然对数 |
LOG() |
返回第一个参数的自然对数 |
LOG10() |
返回参数的以10为底的对数 |
LOG2() |
返回参数的base-2对数 |
MOD() |
归还剩下的 |
PI() |
返回pi的值 |
POW() |
将引发的参数返回到指定的幂 |
POWER() |
将引发的参数返回到指定的幂 |
RADIANS() |
返回参数转换为弧度 |
RAND() |
返回随机浮点值 |
ROUND() |
围绕论点 |
SIGN() |
返回参数的符号 |
SIN() |
返回参数的正弦值 |
SQRT() |
返回参数的平方根 |
TAN() |
返回参数的正切值 |
TRUNCATE() |
截断到指定的小数位数 |
所有数学函数
NULL
在发生错误时
返回
。
返回绝对值
X
。
MySQL的>SELECT ABS(2);
- > 2 MySQL的>SELECT ABS(-32);
- > 32
此功能可安全地与
BIGINT
值
一起使用
。
返回反余弦值
X
,即余弦值为的值
X
。
返回
NULL
如果
X
不在范围内
-1
来
1
。
MySQL的>SELECT ACOS(1);
- > 0 MySQL的>SELECT ACOS(1.0001);
- > NULL MySQL的>SELECT ACOS(0);
- > 1.5707963267949
返回正弦
X
值的正弦值,即正弦值
X
。
返回
NULL
如果
X
不在范围内
-1
来
1
。
MySQL的>SELECT ASIN(0.2);
- > 0.20135792079033 MySQL的>SELECT ASIN('foo');
+ ------------- + | ASIN('foo')| + ------------- + | 0 | + ------------- + 1排,1警告(0.00秒) MySQL的>SHOW WARNINGS;
+ --------- + ------ + -------------------------------- --------- + | 等级| 代码| 消息| + --------- + ------ + -------------------------------- --------- + | 警告| 1292 | 截断不正确的DOUBLE值:'foo'| + --------- + ------ + -------------------------------- --------- +
返回
X
其正切值的反正切值
X
。
MySQL的>SELECT ATAN(2);
- > 1.1071487177941 MySQL的>SELECT ATAN(-2);
- > -1.1071487177941
返回两个变量的反正切
X
和
Y
。
它类似于计算反正切
,除了两个参数的符号用于确定结果的象限。
Y
/
X
MySQL的>SELECT ATAN(-2,2);
- > -0.78539816339745 MySQL的>SELECT ATAN2(PI(),0);
- > 1.5707963267949
返回不小于的最小整数值
X
。
MySQL的>SELECT CEILING(1.23);
- > 2 MySQL的>SELECT CEILING(-1.23);
- > -1
对于精确值数字参数,返回值具有精确值数字类型。 对于字符串或浮点参数,返回值具有浮点类型。
转换不同数字基数之间的数字。
返回数字的字符串表示形式
N
,从base转换
from_base
为base
to_base
。
NULL
如果有任何参数,则
返回
NULL
。
该参数
N
被解释为整数,但可以指定为整数或字符串。
最小基数是
2
,最大基数是
36
。
如果
from_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'+X'0a',10,10);
- > '40'
返回余弦
X
,
X
以弧度为单位给出。
MySQL的> SELECT COS(PI());
- > -1
返回的余切
X
。
MySQL的>SELECT COT(12);
- > -1.5726734063977 MySQL的>SELECT COT(0);
- >超出范围的错误
计算循环冗余校验值并返回32位无符号值。
结果是
NULL
如果参数是
NULL
。
该参数应该是一个字符串,并且(如果可能的话)被视为一个,如果不是的话。
MySQL的>SELECT CRC32('MySQL');
- > 3259397556 MySQL的>SELECT CRC32('mysql');
- > 2501908538
返回
X
从弧度转换为度数
的参数
。
MySQL的>SELECT DEGREES(PI());
- > 180 MySQL的>SELECT DEGREES(PI() / 2);
- > 90
返回
e
的值
(自然对数的基数)提升到的幂
X
。
此函数的反函数是
LOG()
(仅使用单个参数)或
LN()
。
MySQL的>SELECT EXP(2);
- > 7.3890560989307 MySQL的>SELECT EXP(-2);
- > 0.13533528323661 MySQL的>SELECT EXP(0);
- > 1
返回不大于的最大整数值
X
。
MySQL的> SELECT FLOOR(1.23), FLOOR(-1.23);
- > 1,-2
对于精确值数字参数,返回值具有精确值数字类型。 对于字符串或浮点参数,返回值具有浮点类型。
将数字格式化
X
为格式
'#,###,###.##'
,舍入到
D
小数位,并将结果作为字符串返回。
有关详细信息,请参见
第12.5节“字符串函数”
。
此函数可用于获取十进制数或字符串的十六进制表示形式; 它的表达方式根据参数的类型而有所不同。 有关详细信息,请参见 第12.5节“字符串函数”中的 此函数的说明 。
返回自然对数
X
;
也就是碱基
ê
的对数
X
。
如果
X
小于或等于0.0E0,函数返回
NULL
和警告
“
的对数无效参数
”
报道。
MySQL的>SELECT LN(2);
- > 0.69314718055995 MySQL的>SELECT LN(-2);
- > NULL
如果使用一个参数调用,则此函数返回自然对数
X
。
如果
X
小于或等于0.0E0,函数返回
NULL
和警告
“
的对数无效参数
”
报道。
此函数的反函数(使用单个参数调用时)是
EXP()
函数。
MySQL的>SELECT LOG(2);
- > 0.69314718055995 MySQL的>SELECT LOG(-2);
- > NULL
如果使用两个参数调用,则此函数返回
X
基数
的对数
B
。
如果
X
小于或等于0,或者
B
小于或等于1,则
NULL
返回。
MySQL的>SELECT LOG(2,65536);
- > 16 MySQL的>SELECT LOG(10,100);
- > 2 MySQL的>SELECT LOG(1,100);
- > NULL
LOG(
相当于
。
B
,X
)LOG(
X
)
/
LOG(B
)
返回的基数为2的对数
。
如果
X
X
小于或等于0.0E0,函数返回
NULL
和警告
“
的对数无效参数
”
报道。
MySQL的>SELECT LOG2(65536);
- > 16 MySQL的>SELECT LOG2(-100);
- > NULL
LOG2()
有助于找出一个数字需要存储的位数。
此函数等效于表达式
。
LOG(
X
)
/
LOG(2)
返回基数为10的对数
X
。
如果
X
小于或等于0.0E0,函数返回
NULL
和警告
“
的对数无效参数
”
报道。
MySQL的>SELECT LOG10(2);
- > 0.30102999566398 MySQL的>SELECT LOG10(100);
- > 2 MySQL的>SELECT LOG10(-100);
- > NULL
模数运算。
返回
N
除以
的余数
M
。
MySQL的>SELECT MOD(234, 10);
- > 4 MySQL的>SELECT 253 % 7;
- > 1 MySQL的>SELECT MOD(29,9);
- > 2 MySQL的>SELECT 29 MOD 9;
- > 2
此功能可安全地与
BIGINT
值
一起使用
。
MOD()
也适用于具有小数部分的值,并在除法后返回精确的余数:
MySQL的> SELECT MOD(34.5,3);
- > 1.5
MOD(
回报
N
,0)NULL
。
返回π(pi)的值。 显示的默认小数位数为7,但MySQL在内部使用完整的双精度值。
MySQL的>SELECT PI();
- > 3.141593 MySQL的>SELECT PI()+0.000000000000000000;
- > 3.141592653589793116
返回
X
raise的幂值
Y
。
MySQL的>SELECT POW(2,2);
- > 4 MySQL的>SELECT POW(2,-2);
- > 0.25
这是一个同义词
POW()
。
返回参数
X
,从度数转换为弧度。
(注意π弧度等于180度。)
MySQL的> SELECT RADIANS(90);
- > 1.5707963267949
返回
<=
<
v
范围内
的随机浮点值
。
要获取
范围
<=
<
的随机整数
,请使用表达式
-
。
例如,要获取范围
<=
<
范围内的随机整数
,请使用以下语句:
0
v
1.0
R
i
R
j
FLOOR(
i
+ RAND() * (j
i
))7
R
12
SELECT FLOOR(7 +(RAND()* 5));
如果
N
指定
了整数参数
,则将其用作种子值:
使用常量初始化参数,在执行之前,在准备语句时初始化种子。
使用非常量初始值设定项参数(例如列名称),使用每次调用的值初始化种子
RAND()
。
这种行为的一个含义是,对于相等的参数值,
每次都返回相同的值,从而产生可重复的列值序列。
在下面的示例中,生成的值序列在
它出现的两个位置都是相同的。
RAND(
N
)RAND(3)
MySQL的>CREATE TABLE t (i INT);
查询OK,0行受影响(0.42秒) MySQL的>INSERT INTO t VALUES(1),(2),(3);
查询OK,3行受影响(0.00秒) 记录:3个重复:0个警告:0 MySQL的>SELECT i, RAND() FROM t;
+ ------ + ------------------ + | 我| 兰德()| + ------ + ------------------ + | 1 | 0.61914388706828 | | 2 | 0.93845168309142 | | 3 | 0.83482678498591 | + ------ + ------------------ + 3组(0.00秒) MySQL的>SELECT i, RAND(3) FROM t;
+ ------ + ------------------ + | 我| 兰德(3)| + ------ + ------------------ + | 1 | 0.90576975597606 | | 2 | 0.37307905813035 | | 3 | 0.14808605345719 | + ------ + ------------------ + 3组(0.00秒) MySQL的>SELECT i, RAND() FROM t;
+ ------ + ------------------ + | 我| 兰德()| + ------ + ------------------ + | 1 | 0.35877890638893 | | 2 | 0.28941420772058 | | 3 | 0.37073435016976 | + ------ + ------------------ + 3组(0.00秒) MySQL的>SELECT i, RAND(3) FROM t;
+ ------ + ------------------ + | 我| 兰德(3)| + ------ + ------------------ + | 1 | 0.90576975597606 | | 2 | 0.37307905813035 | | 3 | 0.14808605345719 | + ------ + ------------------ + 3行(0.01秒)
RAND()
在
WHERE
子句中计算每一行(从一个表中选择时)或行组合(从多表连接中选择时)。
因此,出于优化程序的目的,
RAND()
它不是常量值,不能用于索引优化。
有关更多信息,请参见
第8.2.1.19节“函数调用优化”
。
RAND()
在
ORDER BY
or
GROUP
BY
子句中
使用
值
具有
值
的列
可能会产生意外结果,因为对于任一子句,
RAND()
可以对同一行多次计算表达式,每次返回不同的结果。
如果目标是以随机顺序检索行,则可以使用如下语句:
SELECT * FROM tbl_name
ORDER BY RAND();
从一组行中选择一个随机样本,结合
ORDER BY RAND()
有
LIMIT
:
SELECT * FROM table1,table2 WHERE a = b AND c <d ORDER BY RAND()LIMIT 1000;
RAND()
并不意味着是一个完美的随机发生器。
这是一种快速生成按需随机数的方法,可以在同一MySQL版本的平台之间移植。
此函数对于基于语句的复制不安全。
如果在
binlog_format
设置
为时使用此功能,则会记录警告
STATEMENT
。
将参数舍入
X
到
D
小数位。
舍入算法取决于数据类型
X
。
D
如果未指定,则默认为0。
D
可以为负,导致
D
值的小数点左边的数字
X
变为零。
MySQL的>SELECT ROUND(-1.23);
- > -1 MySQL的>SELECT ROUND(-1.58);
- > -2 MySQL的>SELECT ROUND(1.58);
- > 2 MySQL的>SELECT ROUND(1.298, 1);
- > 1.3 MySQL的>SELECT ROUND(1.298, 0);
- > 1 MySQL的>SELECT ROUND(23.298, -1);
- > 20
返回值与第一个参数具有相同的类型(假设它是整数,双精度或十进制)。 这意味着对于整数参数,结果是一个整数(没有小数位):
MySQL的> SELECT ROUND(150.000,2), ROUND(150,2);
+ ------------------ + -------------- +
| ROUND(150.000,2)| ROUND(150,2)|
+ ------------------ + -------------- +
| 150.00 | 150 |
+ ------------------ + -------------- +
ROUND()
根据第一个参数的类型使用以下规则:
以下示例显示精确值和近似值的舍入方式有何不同:
MySQL的> SELECT ROUND(2.5), ROUND(25E-1);
+ ------------ + -------------- +
| ROUND(2.5)| ROUND(25E-1)|
+ ------------ + -------------- +
| 3 | 2 |
+ ------------ + -------------- +
有关更多信息,请参见 第12.25节“精确数学” 。
返回参数的符号为
-1
,
0
或者
1
,根据是否
X
是负数,零或正。
MySQL的>SELECT SIGN(-32);
- > -1 MySQL的>SELECT SIGN(0);
- > 0 MySQL的>SELECT SIGN(234);
- > 1
返回的正弦值
X
,其中
X
以弧度给出。
MySQL的>SELECT SIN(PI());
- > 1.2246063538224e-16 MySQL的>SELECT ROUND(SIN(PI()));
- > 0
返回非负数的平方根
X
。
MySQL的>SELECT SQRT(4);
- > 2 MySQL的>SELECT SQRT(20);
- > 4.4721359549996 MySQL的>SELECT SQRT(-16);
- > NULL
返回切线
X
,其中
X
以弧度为单位。
MySQL的>SELECT TAN(PI());
- > -1.2246063538224e-16 MySQL的>SELECT TAN(PI()+1);
- > 1.5574077246549
返回数字
X
,截断为
D
小数位。
如果
D
是
0
,则结果没有小数点或小数部分。
D
可以为负,导致
D
值的小数点左边的数字
X
变为零。
MySQL的>SELECT TRUNCATE(1.223,1);
- > 1.2 MySQL的>SELECT TRUNCATE(1.999,1);
- > 1.9 MySQL的>SELECT TRUNCATE(1.999,0);
- > 1 MySQL的>SELECT TRUNCATE(-1.999,1);
- > -1.9 MySQL的>SELECT TRUNCATE(122,-2);
- > 100 MySQL的>SELECT TRUNCATE(10.28*100,0);
- > 1028
所有数字都向零舍入。
本节介绍可用于处理时间值的函数。 有关 每种日期和时间类型具有的值范围以及可以指定值的有效格式的说明, 请参见 第11.3节“日期和时间类型” 。
表12。13日期和时间函数
名称 | 描述 |
---|---|
ADDDATE() |
将时间值(间隔)添加到日期值 |
ADDTIME() |
添加时间 |
CONVERT_TZ() |
从一个时区转换为另一个时区 |
CURDATE() |
返回当前日期 |
CURRENT_DATE()
,
CURRENT_DATE
|
CURDATE()的同义词 |
CURRENT_TIME()
,
CURRENT_TIME
|
CURTIME()的同义词 |
CURRENT_TIMESTAMP()
,
CURRENT_TIMESTAMP
|
同义词NOW() |
CURTIME() |
返回当前时间 |
DATE() |
提取日期或日期时间表达式的日期部分 |
DATE_ADD() |
将时间值(间隔)添加到日期值 |
DATE_FORMAT() |
格式化日期指定 |
DATE_SUB() |
从日期中减去时间值(间隔) |
DATEDIFF() |
减去两个日期 |
DAY() |
DAYOFMONTH()的同义词 |
DAYNAME() |
返回工作日的名称 |
DAYOFMONTH() |
返回月中的某一天(0-31) |
DAYOFWEEK() |
返回参数的工作日索引 |
DAYOFYEAR() |
返回一年中的某一天(1-366) |
EXTRACT() |
提取部分日期 |
FROM_DAYS() |
将日期号码转换为日期 |
FROM_UNIXTIME() |
将Unix时间戳格式化为日期 |
GET_FORMAT() |
返回日期格式字符串 |
HOUR() |
提取小时 |
LAST_DAY |
返回参数的月份的最后一天 |
LOCALTIME()
,
LOCALTIME
|
NOW()的同义词 |
LOCALTIMESTAMP
,
LOCALTIMESTAMP()
|
NOW()的同义词 |
MAKEDATE() |
创建年份和年中的日期 |
MAKETIME() |
从小时,分钟,秒创建时间 |
MICROSECOND() |
从参数返回微秒 |
MINUTE() |
从论证中返回分钟 |
MONTH() |
从过去的日期返回月份 |
MONTHNAME() |
返回月份名称 |
NOW() |
返回当前日期和时间 |
PERIOD_ADD() |
将期间添加到年 - 月 |
PERIOD_DIFF() |
返回句点之间的月数 |
QUARTER() |
从日期参数返回季度 |
SEC_TO_TIME() |
将秒转换为'hh:mm:ss'格式 |
SECOND() |
返回秒(0-59) |
STR_TO_DATE() |
将字符串转换为日期 |
SUBDATE() |
使用三个参数调用时DATE_SUB()的同义词 |
SUBTIME() |
减去时间 |
SYSDATE() |
返回函数执行的时间 |
TIME() |
提取传递的表达式的时间部分 |
TIME_FORMAT() |
格式化为时间 |
TIME_TO_SEC() |
返回转换为秒的参数 |
TIMEDIFF() |
减去时间 |
TIMESTAMP() |
使用单个参数,此函数返回日期或日期时间表达式; 有两个参数,参数的总和 |
TIMESTAMPADD() |
在datetime表达式中添加间隔 |
TIMESTAMPDIFF() |
从日期时间表达式中减去间隔 |
TO_DAYS() |
返回转换为days的日期参数 |
TO_SECONDS() |
返回自0年以来转换为秒的日期或日期时间参数 |
UNIX_TIMESTAMP() |
返回Unix时间戳 |
UTC_DATE() |
返回当前的UTC日期 |
UTC_TIME() |
返回当前的UTC时间 |
UTC_TIMESTAMP() |
返回当前的UTC日期和时间 |
WEEK() |
返回周数 |
WEEKDAY() |
返回工作日索引 |
WEEKOFYEAR() |
返回日期的日历周(1-53) |
YEAR() |
回归年份 |
YEARWEEK() |
返回年份和星期 |
这是一个使用日期函数的示例。
以下查询选择具有
date_col
最近30天内值的
所有行
:
mysql> - >SELECT
something
FROMtbl_name
WHERE DATE_SUB(CURDATE(),INTERVAL 30 DAY) <=
date_col
;
该查询还会选择日期位于将来的行。
期望日期值的函数通常接受日期时间值并忽略时间部分。 期望时间值的函数通常接受日期时间值并忽略日期部分。
返回当前日期或时间的函数在查询执行开始时每个查询仅评估一次。
这意味着对诸如
NOW()
单个查询内
的函数的多个引用
总是产生相同的结果。
(对于我们而言,单一的查询还包括对存储程序的调用(存储程序,触发器或事件)以及所有子程序由该程序调用。)这个原则也适用于
CURDATE()
,
CURTIME()
,
UTC_DATE()
,
UTC_TIME()
,
UTC_TIMESTAMP()
,和他们的任何同义词。
的
CURRENT_TIMESTAMP()
,
CURRENT_TIME()
,
CURRENT_DATE()
,和
FROM_UNIXTIME()
功能在当前会话中的时区,这可作为的会话值返回值
time_zone
系统变量。
此外,
UNIX_TIMESTAMP()
假设其参数是会话时区中的日期时间值。
请参见
第5.1.13节“MySQL服务器时区支持”
。
某些日期函数可以使用
“
零
”
日期或不完整日期,例如
'2001-11-00'
,而其他
日期函数
则不能。
提取日期部分的函数通常使用不完整的日期,因此当您可能期望非零值时可以返回0。
例如:
MySQL的> SELECT DAYOFMONTH('2001-11-00'), MONTH('2005-00-00');
- > 0,0
其他功能期望完整日期和
NULL
不完整日期的
返回
。
这些包括执行日期算术或将日期部分映射到名称的函数。
例如:
MySQL的>SELECT DATE_ADD('2006-05-00',INTERVAL 1 DAY);
- > NULL MySQL的>SELECT DAYNAME('2006-05-00');
- > NULL
当传递
DATE()
函数值作为参数
时,有几个函数更严格,
并且在零日的零部分拒绝不完整的日期。
这些功能被影响:
CONVERT_TZ()
,
DATE_ADD()
,
DATE_SUB()
,
DAYOFYEAR()
,
LAST_DAY()
(允许零天一部分), ,
TIMESTAMPDIFF()
,
TO_DAYS()
,
TO_SECONDS()
,
WEEK()
,
WEEKDAY()
,
。
WEEKOFYEAR()
YEARWEEK()
支持
,和
值的小
数秒
TIME
,
精度高达微秒。
采用时态参数的函数接受带小数秒的值。
时间函数的返回值包括适当的小数秒。
DATETIME
TIMESTAMP
ADDDATE(
,
date
,INTERVAL
expr
unit
)ADDDATE(
expr
,days
)
当使用
INTERVAL
第二个参数
的
形式
调用时
,
ADDDATE()
是同义词
DATE_ADD()
。
相关功能
SUBDATE()
是其同义词
DATE_SUB()
。
有关
INTERVAL
unit
参数的
信息
,请参阅
时间间隔
。
MySQL的>SELECT DATE_ADD('2008-01-02', INTERVAL 31 DAY);
- >'2008-02-02' MySQL的>SELECT ADDDATE('2008-01-02', INTERVAL 31 DAY);
- >'2008-02-02'
当使用
days
第二个参数
的
形式
调用时
,MySQL会将其视为要添加的整数天数
expr
。
MySQL的> SELECT ADDDATE('2008-01-02', 31);
- >'2008-02-02'
ADDTIME()
增加了
expr2
对
expr1
并返回结果。
expr1
是时间或日期时间表达式,
expr2
是时间表达式。
MySQL的>SELECT ADDTIME('2007-12-31 23:59:59.999999', '1 1:1:1.000002');
- >'2008-01-02 01:01:01.000001' MySQL的>SELECT ADDTIME('01:00:00.999999', '02:00:00.999998');
- > '03:00:01.999997'
CONVERT_TZ()
将datetime值
dt
从给定的时区
转换为
给定
from_tz
的时区,
to_tz
并返回结果值。
时区的指定如
第5.1.13节“MySQL服务器时区支持”中所述
。
NULL
如果参数无效,则
返回此函数
。
如果在
TIMESTAMP
从
from_tz
UTC
转换
为UTC
时
该值超出支持的
类型
范围,则
不会发生转换。
第11.1.2节“日期和时间类型概述”中
TIMESTAMP
介绍了
该
范围
。
MySQL的>SELECT CONVERT_TZ('2004-01-01 12:00:00','GMT','MET');
- >'2004-01-01 13:00:00' MySQL的>SELECT CONVERT_TZ('2004-01-01 12:00:00','+00:00','+10:00');
- >'2004-01-01 22:00:00'
要使用诸如
'MET'
或的
命名时区
'Europe/Amsterdam'
,必须正确设置时区表。
有关说明,请参见
第5.1.13节“MySQL服务器时区支持”
。
以值
'YYYY-MM-DD'
或
YYYYMMDD
格式
返回当前日期
,具体取决于函数是在字符串还是数字上下文中使用。
MySQL的>SELECT CURDATE();
- >'2008-06-13' MySQL的>SELECT CURDATE() + 0;
- > 20080613
CURRENT_DATE
并且
CURRENT_DATE()
是同义词
CURDATE()
。
CURRENT_TIME
,
CURRENT_TIME([
fsp
])
CURRENT_TIME
并且
CURRENT_TIME()
是同义词
CURTIME()
。
CURRENT_TIMESTAMP
,
CURRENT_TIMESTAMP([
fsp
])
CURRENT_TIMESTAMP
并且
CURRENT_TIMESTAMP()
是同义词
NOW()
。
以值
'hh:mm:ss'
或
hhmmss
格式
返回当前时间
,具体取决于函数是在字符串还是数值上下文中使用。
该值以会话时区表示。
如果
fsp
给出参数以指定从0到6的小数秒精度,则返回值包括该多个数字的小数秒部分。
MySQL的>SELECT CURTIME();
- > '23:50:26' MySQL的>SELECT CURTIME() + 0;
- > 235026.000000
提取日期或日期时间表达式的日期部分
expr
。
MySQL的> SELECT DATE('2003-12-31 01:02:03');
- >'2003-12-31'
DATEDIFF()
返回
expr1
-
expr2
表示为从一个日期到另一个日期的天数值。
expr1
并且
expr2
是日期或日期和时间表达式。
在计算中仅使用值的日期部分。
MySQL的>SELECT DATEDIFF('2007-12-31 23:59:59','2007-12-30');
- > 1 MySQL的>SELECT DATEDIFF('2010-11-30 23:59:59','2010-12-31');
- > -31
DATE_ADD(
,
date
,INTERVAL
expr
unit
)DATE_SUB(
date
,INTERVAL
expr
unit
)
这些函数执行日期算术。
该
date
参数指定起始日期或日期时间值。
expr
是一个表达式,用于指定要从开始日期添加或减去的区间值。
expr
被评估为一个字符串;
它可能
-
以负间隔开始。
unit
是一个关键字,指示应该解释表达式的单位。
有关时间间隔语法的更多信息,包括完整的
unit
说明符
列表,
expr
每个
unit
值
的
参数
的预期形式
,以及时间算术中操作数解释的规则,请参阅
时间间隔
。
返回值取决于参数:
为确保结果
DATETIME
,您可以使用
CAST()
将第一个参数转换为
DATETIME
。
MySQL的>SELECT DATE_ADD('2018-05-01',INTERVAL 1 DAY);
- >'2018-05-02' MySQL的>SELECT DATE_SUB('2018-05-01',INTERVAL 1 YEAR);
- >'2017-05-01' mysql>SELECT DATE_ADD('2020-12-31 23:59:59',
- >INTERVAL 1 SECOND);
- > '2021-01-01 00:00:00' mysql>SELECT DATE_ADD('2018-12-31 23:59:59',
- >INTERVAL 1 DAY);
- >'2019-01-01 23:59:59' mysql>SELECT DATE_ADD('2100-12-31 23:59:59',
- >INTERVAL '1:1' MINUTE_SECOND);
- >'2101-01-01 00:01:00' mysql>SELECT DATE_SUB('2025-01-01 00:00:00',
- >INTERVAL '1 1:1:1' DAY_SECOND);
- >'2024-12-30 22:58:59' mysql>SELECT DATE_ADD('1900-01-01 00:00:00',
- >INTERVAL '-1 10' DAY_HOUR);
- >'1899-12-30 14:00:00' MySQL的>SELECT DATE_SUB('1998-01-02', INTERVAL 31 DAY);
- >'1997-12-02' mysql>SELECT DATE_ADD('1992-12-31 23:59:59.000002',
- >INTERVAL '1.999999' SECOND_MICROSECOND);
- >'1993-01-01 00:00:01.000001'
date
根据
format
字符串
格式化
值
。
下表中显示的说明符可以在
format
字符串中使用。
%
格式说明符字符前需要
该
字符。
该说明符适用于其它功能:
STR_TO_DATE()
,
TIME_FORMAT()
,
UNIX_TIMESTAMP()
。
符 | 描述 |
---|---|
%a |
工作日缩写名称(
Sun
..
Sat
)
|
%b |
缩写的月份名称(
Jan
..
Dec
)
|
%c |
月,数字(
0
..
12
)
|
%D |
这个月的一天,英语后缀(
0th
,
1st
,
2nd
,
3rd
,...)
|
%d |
每月的某一天,数字(
00
..
31
)
|
%e |
每月的某一天,数字(
0
..
31
)
|
%f |
微秒(
000000
...
999999
)
|
%H |
小时(
00
..
23
)
|
%h |
小时(
01
..
12
)
|
%I |
小时(
01
..
12
)
|
%i |
分钟,数字(
00
..
59
)
|
%j |
一年中的一天(
001
..
366
)
|
%k |
小时(
0
..
23
)
|
%l |
小时(
1
..
12
)
|
%M |
月份名称(
January
..
December
)
|
%m |
月,数字(
00
..
12
)
|
%p |
AM
要么
PM
|
%r |
时间,12小时(
hh:mm:ss
其次是
AM
或
PM
)
|
%S |
秒(
00
...
59
)
|
%s |
秒(
00
...
59
)
|
%T |
时间,24小时(
hh:mm:ss
)
|
%U |
周(
00
..
53
),周日是一周的第一天;
WEEK()
模式0
|
%u |
周(
00
..
53
),周一是一周的第一天;
WEEK()
模式1
|
%V |
周(
01
..
53
),周日是一周的第一天;
WEEK()
模式2;
用于
%X
|
%v |
周(
01
..
53
),周一是一周的第一天;
WEEK()
模式3;
用于
%x
|
%W |
工作日名称(
Sunday
..
Saturday
)
|
%w |
星期几(
0
=星期日..
6
=星期六)
|
%X |
星期日是星期的第一天的星期,数字,四位数;
用于
%V
|
%x |
一周的年份,星期一是一周的第一天,数字,四位数;
用于
%v
|
%Y |
年份,数字,四位数 |
%y |
年份,数字(两位数) |
%% |
文字
%
字符
|
% |
x
,对于
上面未列出的
任何
“
x
”
|
由于MySQL允许存储不完整的日期,例如,因此月份和日期说明符的范围从零开始
'2014-00-00'
。
用于日期和月份名称和缩写的语言由
lc_time_names
系统变量
的值控制
(
第10.15节“MySQL服务器区域设置支持”
)。
对于
%U
,
%u
,
%V
,和
%v
说明符,看到的描述
WEEK()
有关模式值的信息的功能。
该模式会影响周编号的发生方式。
DATE_FORMAT()
返回由给定的字符集和校对规则的字符串
character_set_connection
,并
collation_connection
使其可以返回一个包含非ASCII字符月和星期名。
MySQL的>SELECT DATE_FORMAT('2009-10-04 22:23:00', '%W %M %Y');
- >'2009年10月10日' MySQL的>SELECT DATE_FORMAT('2007-10-04 22:23:00', '%H:%i:%s');
- > '22:23:00' mysql>SELECT DATE_FORMAT('1900-10-04 22:23:00',
- >'%D %y %a %d %m %b %j');
- >'4th 00 Thu 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' MySQL的>SELECT DATE_FORMAT('1999-01-01', '%X %V');
- >'1998 52' MySQL的>SELECT DATE_FORMAT('2006-06-00', '%d');
- > '00'
DATE_SUB(
date
,INTERVAL
expr
unit
)
请参阅说明
DATE_ADD()
。
DAY()
是...的同义词
DAYOFMONTH()
。
返回工作日的名称
date
。
用于名称的语言由
lc_time_names
系统变量
的值控制
(
第10.15节“MySQL服务器区域设置支持”
)。
MySQL的> SELECT DAYNAME('2007-02-03');
- >'星期六'
返回月份的
日期
date
,范围
1
为
31
,或者
0
日期,例如
'0000-00-00'
或
'2008-00-00'
具有零日部分的日期。
MySQL的> SELECT DAYOFMONTH('2007-02-03');
- > 3
返回
date
(
1
= Sunday,
2
= Monday,...,
7
= Saturday)
的工作日索引
。
这些索引值对应于ODBC标准。
MySQL的> SELECT DAYOFWEEK('2007-02-03');
- > 7
返回一年中的某一天,
date
范围
1
为
366
。
MySQL的> SELECT DAYOFYEAR('2007-02-03');
- > 34
该
EXTRACT()
函数使用与
or
相同类型的
unit
说明符
,但从日期中提取部分而不是执行日期算术。
有关
参数的
信息
,请参阅
时间间隔
。
DATE_ADD()
DATE_SUB()
unit
MySQL的>SELECT EXTRACT(YEAR FROM '2019-07-02');
- > 2019年 MySQL的>SELECT EXTRACT(YEAR_MONTH FROM '2019-07-02 01:02:03');
- > 201907 MySQL的>SELECT EXTRACT(DAY_MINUTE FROM '2019-07-02 01:02:03');
- > 20102 mysql>SELECT EXTRACT(MICROSECOND
- >FROM '2003-01-02 10:30:00.000123');
- > 123
给定一个天数
N
,返回一个
DATE
值。
MySQL的> SELECT FROM_DAYS(730669);
- >'2000-07-03'
FROM_DAYS()
在旧约会上谨慎
使用
。
它不适用于格里高利历(1582年)出现之前的值。
请参见
第12.8节“MySQL使用什么日历?”
。
FROM_UNIXTIME(
unix_timestamp
[,format
])
返回
unix_timestamp
参数
的表示形式,
作为值
'YYYY-MM-DD hh:mm:ss'
或
YYYYMMDDhhmmss.uuuuuu
格式,具体取决于函数是在字符串还是数字上下文中使用。
unix_timestamp
是一个内部时间戳值,表示自
'1970-01-01 00:00:00'
UTC
以来的秒数
,例如由
UNIX_TIMESTAMP()
函数
生成的
值。
返回值以会话时区表示。
(客户端可以按照
第5.1.13节“MySQL服务器时区支持”中
所述设置会话时区
。)
format
字符串(如果给定)用于格式化结果,方法与
DATE_FORMAT()
函数
条目中描述的方式相同
。
MySQL的>SELECT FROM_UNIXTIME(1447430881);
- >'2015-11-13 10:08:01' MySQL的>SELECT FROM_UNIXTIME(1447430881) + 0;
- > 20151113100801 mysql>SELECT FROM_UNIXTIME(1447430881,
- >'%Y %D %M %h:%i:%s %x');
- >'2015年11月13日10:08:01 2015'
如果您使用
UNIX_TIMESTAMP()
和
FROM_UNIXTIME()
转换非UTC时区中的值和Unix时间戳值,则转换是有损的,因为映射在两个方向上都不是一对一的。
有关详细信息,请参阅该
UNIX_TIMESTAMP()
功能
的说明
。
GET_FORMAT({DATE|TIME|DATETIME},
{'EUR'|'USA'|'JIS'|'ISO'|'INTERNAL'})
返回格式字符串。
此功能与
功能
DATE_FORMAT()
和
STR_TO_DATE()
功能
结合使用非常有用
。
第一个和第二个参数的可能值导致几个可能的格式字符串(对于使用的
DATE_FORMAT()
说明符
,请参阅
函数说明中
的表
)。
ISO格式是指ISO 9075,而不是ISO 8601。
功能调用 | 结果 |
---|---|
GET_FORMAT(DATE,'USA') |
'%m.%d.%Y' |
GET_FORMAT(DATE,'JIS') |
'%Y-%m-%d' |
GET_FORMAT(DATE,'ISO') |
'%Y-%m-%d' |
GET_FORMAT(DATE,'EUR') |
'%d.%m.%Y' |
GET_FORMAT(DATE,'INTERNAL') |
'%Y%m%d' |
GET_FORMAT(DATETIME,'USA') |
'%Y-%m-%d %H.%i.%s' |
GET_FORMAT(DATETIME,'JIS') |
'%Y-%m-%d %H:%i:%s' |
GET_FORMAT(DATETIME,'ISO') |
'%Y-%m-%d %H:%i:%s' |
GET_FORMAT(DATETIME,'EUR') |
'%Y-%m-%d %H.%i.%s' |
GET_FORMAT(DATETIME,'INTERNAL') |
'%Y%m%d%H%i%s' |
GET_FORMAT(TIME,'USA') |
'%h:%i:%s %p' |
GET_FORMAT(TIME,'JIS') |
'%H:%i:%s' |
GET_FORMAT(TIME,'ISO') |
'%H:%i:%s' |
GET_FORMAT(TIME,'EUR') |
'%H.%i.%s' |
GET_FORMAT(TIME,'INTERNAL') |
'%H%i%s' |
TIMESTAMP
也可以用作第一个参数
GET_FORMAT()
,在这种情况下,函数返回
与之
相同的值
DATETIME
。
MySQL的>SELECT DATE_FORMAT('2003-10-03',GET_FORMAT(DATE,'EUR'));
- > '03 .10.2003' MySQL的>SELECT STR_TO_DATE('10.31.2003',GET_FORMAT(DATE,'USA'));
- >'2003-10-31'
返回小时
time
。
返回值的范围是
0
要
23
时间的日值。
但是,
TIME
值
的范围
实际上要大得多,因此
HOUR
可以返回大于的值
23
。
MySQL的>SELECT HOUR('10:05:03');
- > 10 MySQL的>SELECT HOUR('272:59:59');
- > 272
采用日期或日期时间值并返回该月最后一天的相应值。
NULL
如果参数无效,则
返回
。
MySQL的>SELECT LAST_DAY('2003-02-05');
- >'2003-02-28' MySQL的>SELECT LAST_DAY('2004-02-05');
- >'2004-02-29' MySQL的>SELECT LAST_DAY('2004-01-01 01:01:01');
- >'2004-01-31' MySQL的>SELECT LAST_DAY('2003-03-32');
- > NULL
LOCALTIME
并且
LOCALTIME()
是同义词
NOW()
。
LOCALTIMESTAMP
,
LOCALTIMESTAMP([
fsp
])
LOCALTIMESTAMP
并且
LOCALTIMESTAMP()
是同义词
NOW()
。
返回给定年份和年份值的日期。
dayofyear
必须大于0或结果是
NULL
。
MySQL的>SELECT MAKEDATE(2011,31), MAKEDATE(2011,32);
- >'2011-01-31','2011-02-01' MySQL的>SELECT MAKEDATE(2011,365), MAKEDATE(2014,365);
- >'2011-12-31','2014-12-31' MySQL的>SELECT MAKEDATE(2011,0);
- > NULL
返回从计算出的时间值
hour
,
minute
和
second
参数。
该
second
参数可以有小数部分。
MySQL的> SELECT MAKETIME(12,15,30);
- > '12:15:30'
返回时间或日期时间表达式中的微秒,
expr
作为从
0
到
的范围内的数字
999999
。
MySQL的>SELECT MICROSECOND('12:00:00.123456');
- > 123456 MySQL的>SELECT MICROSECOND('2019-12-31 23:59:59.000010');
- > 10
返回分钟
time
,范围
0
到
59
。
MySQL的> SELECT MINUTE('2008-02-03 10:05:03');
- > 5
返回一个月
date
,在范围内
1
,以
12
供1- 12月,或
0
为日期,如
'0000-00-00'
或
'2008-00-00'
有一个零一个月的一部分。
MySQL的> SELECT MONTH('2008-02-03');
- > 2
返回月份的全名
date
。
用于名称的语言由
lc_time_names
系统变量
的值控制
(
第10.15节“MySQL服务器区域设置支持”
)。
MySQL的> SELECT MONTHNAME('2008-02-03');
- >'二月'
以值
'YYYY-MM-DD hh:mm:ss'
或
YYYYMMDDhhmmss
格式
返回当前日期和时间
,具体取决于函数是在字符串还是数字上下文中使用。
该值以会话时区表示。
如果
fsp
给出参数以指定从0到6的小数秒精度,则返回值包括该多个数字的小数秒部分。
MySQL的>SELECT NOW();
- >'2007-12-15 23:50:26' MySQL的>SELECT NOW() + 0;
- > 20071215235026.000000
NOW()
返回一个常量时间,指示语句开始执行的时间。
(在存储的函数或触发器中,
NOW()
返回函数或触发语句开始执行的时间。)这与行为不同
SYSDATE()
,后者返回执行它的确切时间。
MySQL的>SELECT NOW(), SLEEP(2), NOW();
+ --------------------- + ---------- + ---------------- ----- + | 现在()| SLEEP(2)| 现在()| + --------------------- + ---------- + ---------------- ----- + | 2006-04-12 13:47:36 | 0 | 2006-04-12 13:47:36 | + --------------------- + ---------- + ---------------- ----- + MySQL的>SELECT SYSDATE(), SLEEP(2), SYSDATE();
+ --------------------- + ---------- + ---------------- ----- + | SYSDATE()| SLEEP(2)| SYSDATE()| + --------------------- + ---------- + ---------------- ----- + | 2006-04-12 13:47:44 | 0 | 2006-04-12 13:47:46 | + --------------------- + ---------- + ---------------- ----- +
此外,该
SET TIMESTAMP
语句会影响返回的值,
NOW()
但不会
影响
SYSDATE()
。
这意味着二进制日志中的时间戳设置对调用没有影响
SYSDATE()
。
将时间戳设置为非零值会导致每次后续调用都
NOW()
返回该值。
将时间戳设置为零会取消此效果,以便
NOW()
再次返回当前日期和时间。
有关这
SYSDATE()
两个功能之间差异的其他信息,
请参阅说明
。
添加
N
月份到期间
P
(格式
YYMM
或
YYYYMM
)。
返回格式的值
YYYYMM
。
该时期的说法
P
是
没有
日期值。
MySQL的> SELECT PERIOD_ADD(200801,2);
- > 200803
返回句点
P1
和
之间的月数
P2
。
P1
并且
P2
应该采用格式
YYMM
或
YYYYMM
。
注意周期参数
P1
和
P2
是
不是
日期值。
MySQL的> SELECT PERIOD_DIFF(200802,200703);
- > 11
返回一年的季度
date
,范围
1
到
4
。
MySQL的> SELECT QUARTER('2008-04-01');
- > 2
返回
time
范围
0
为
的第二个
59
。
MySQL的> SELECT SECOND('10:05:03');
- > 3
返回
seconds
参数,转换为小时,分钟和秒,作为
TIME
值。
结果的范围限制为
TIME
数据类型的范围。
如果参数对应于该范围之外的值,则会发出警告。
MySQL的>SELECT SEC_TO_TIME(2378);
- > '00:39:38' MySQL的>SELECT SEC_TO_TIME(2378) + 0;
- > 3938
这是
DATE_FORMAT()
函数
的反
函数。
它需要一个字符串
str
和一个格式字符串
format
。
如果格式字符串包含日期和时间部分,则
STR_TO_DATE()
返回
DATETIME
值;如果字符串仅包含日期或时间部分,则
返回
值
DATE
或
TIME
值。
如果从中提取的日期,时间或日期时间值
str
是非法的,则
STR_TO_DATE()
返回
NULL
并生成警告。
服务器扫描
str
尝试匹配
format
它。
格式字符串可以包含以字母开头的文字字符和格式说明符
%
。
文字字符
format
必须符合字面意思
str
。
格式说明符
format
必须与日期或时间部分匹配
str
。
有关可以使用
format
的
DATE_FORMAT()
说明符
,请参阅
函数说明。
MySQL的>SELECT STR_TO_DATE('01,5,2013','%d,%m,%Y');
- >'2013-05-01' MySQL的>SELECT STR_TO_DATE('May 1, 2013','%M %d,%Y');
- >'2013-05-01'
扫描在开始时开始,
str
如果
format
发现不匹配则
失败
。
末尾的额外字符将
str
被忽略。
MySQL的>SELECT STR_TO_DATE('a09:30:17','a%h:%i:%s');
- > '09:30:17' MySQL的>SELECT STR_TO_DATE('a09:30:17','%h:%i:%s');
- > NULL MySQL的>SELECT STR_TO_DATE('09:30:17a','%h:%i:%s');
- > '09:30:17'
未指定的日期或时间部分的值为0,因此未完全指定的值会
str
产生一些或所有部分设置为0的结果:
MySQL的>SELECT STR_TO_DATE('abc','abc');
- >'0000-00-00' MySQL的>SELECT STR_TO_DATE('9','%m');
- >'0000-09-00' MySQL的>SELECT STR_TO_DATE('9','%s');
- > '00:00:09'
对日期值部分的范围检查如 第11.3.1节“DATE,DATETIME和TIMESTAMP类型”中所述 。 这意味着,例如, 除非将SQL模式设置为禁止此类值,否则允许部分值为0的 “ 零 ” 日期或日期。
MySQL的>SELECT STR_TO_DATE('00/00/0000', '%m/%d/%Y');
- >'0000-00-00' MySQL的>SELECT STR_TO_DATE('04/31/2004', '%m/%d/%Y');
- >'2004-04-31'
如果
启用
了
SQL
NO_ZERO_DATE
或
NO_ZERO_IN_DATE
SQL模式,则不允许零日期或部分日期。
在这种情况下,
STR_TO_DATE()
返回
NULL
并生成警告:
mysql>SET sql_mode = '';
mysql>SELECT STR_TO_DATE('15:35:00', '%H:%i:%s');
+ ------------------------------- + | STR_TO_DATE('15:35:00','%H:%i:%s')| + ------------------------------- + | 15:35:00 | + ------------------------------- + mysql>SET sql_mode = 'NO_ZERO_IN_DATE';
mysql>SELECT STR_TO_DATE('15:35:00', '%h:%i:%s');
+ ------------------------------- + | STR_TO_DATE('15:35:00','%h:%i:%s')| + ------------------------------- + | NULL | + ------------------------------- + MySQL的>SHOW WARNINGS\G
*************************** 1。排******************** ******* 等级:警告 代码:1411 消息:日期时间值不正确:'15:35:00'表示函数str_to_date
您不能使用格式
"%X%V"
将年周字符串转换为日期,因为如果周超过月边界,则年和周的组合不能唯一标识年和月。
要将年周转换为日期,您还应指定工作日:
MySQL的> SELECT STR_TO_DATE('200442 Monday', '%X%V %W');
- >'2004-10-18'
SUBDATE(
,
date
,INTERVAL
expr
unit
)SUBDATE(
expr
,days
)
当使用
INTERVAL
第二个参数
的
形式
调用时
,
SUBDATE()
是同义词
DATE_SUB()
。
有关
INTERVAL
unit
参数的
信息
,请参阅讨论
DATE_ADD()
。
MySQL的>SELECT DATE_SUB('2008-01-02', INTERVAL 31 DAY);
- >'2007-12-02' MySQL的>SELECT SUBDATE('2008-01-02', INTERVAL 31 DAY);
- >'2007-12-02'
第二种形式允许使用整数值
days
。
在这种情况下,它被解释为从日期或日期时间表达式中减去的天数
expr
。
MySQL的> SELECT SUBDATE('2008-01-02 12:00:00', 31);
- >'2007-12-02 12:00:00'
SUBTIME()
返回
expr1
-
expr2
表示为与格式相同的值
expr1
。
expr1
是时间或日期时间表达式,
expr2
是时间表达式。
MySQL的>SELECT SUBTIME('2007-12-31 23:59:59.999999','1 1:1:1.000002');
- >'2007-12-30 22:58:58.999997' MySQL的>SELECT SUBTIME('01:00:00.999999', '02:00:00.999998');
- >' - 00:59:59.999999'
以值
'YYYY-MM-DD hh:mm:ss'
或
YYYYMMDDhhmmss
格式
返回当前日期和时间
,具体取决于函数是在字符串还是数字上下文中使用。
如果
fsp
给出参数以指定从0到6的小数秒精度,则返回值包括该多个数字的小数秒部分。
SYSDATE()
返回它执行的时间。
这与行为不同
NOW()
,后者返回一个表示语句开始执行的时间的常量时间。
(在存储的函数或触发器中,
NOW()
返回函数或触发语句开始执行的时间。)
MySQL的>SELECT NOW(), SLEEP(2), NOW();
+ --------------------- + ---------- + ---------------- ----- + | 现在()| SLEEP(2)| 现在()| + --------------------- + ---------- + ---------------- ----- + | 2006-04-12 13:47:36 | 0 | 2006-04-12 13:47:36 | + --------------------- + ---------- + ---------------- ----- + MySQL的>SELECT SYSDATE(), SLEEP(2), SYSDATE();
+ --------------------- + ---------- + ---------------- ----- + | SYSDATE()| SLEEP(2)| SYSDATE()| + --------------------- + ---------- + ---------------- ----- + | 2006-04-12 13:47:44 | 0 | 2006-04-12 13:47:46 | + --------------------- + ---------- + ---------------- ----- +
此外,该
SET TIMESTAMP
语句会影响返回的值,
NOW()
但不会
影响
SYSDATE()
。
这意味着二进制日志中的时间戳设置对调用没有影响
SYSDATE()
。
因为
SYSDATE()
即使在同一语句中也可以返回不同的值,并且不受其影响
SET TIMESTAMP
,因此如果使用基于语句的二进制日志记录,则它是不确定的,因此对于复制是不安全的。
如果这是一个问题,您可以使用基于行的日志记录。
或者,您可以使用该
--sysdate-is-now
选项使其
SYSDATE()
成为别名
NOW()
。
如果在主服务器和从服务器上都使用该选项,则此方法有效。
非确定性
SYSDATE()
也意味着索引不能用于评估引用它的表达式。
提取时间或日期时间表达式的时间部分
expr
并将其作为字符串返回。
此函数对于基于语句的复制不安全。
如果在
binlog_format
设置
为时使用此功能,则会记录警告
STATEMENT
。
MySQL的>SELECT TIME('2003-12-31 01:02:03');
- > '01:02:03' MySQL的>SELECT TIME('2003-12-31 01:02:03.000123');
- > '01:02:03.000123'
TIMEDIFF()
返回
expr1
-
expr2
表示为时间值。
expr1
并且
expr2
是时间或日期和时间表达式,但两者必须是相同的类型。
返回的结果
TIMEDIFF()
仅限于
TIME
值
允许的范围
。
另外,您也可以使用的功能
TIMESTAMPDIFF()
和
UNIX_TIMESTAMP()
,两者返回整数。
mysql>SELECT TIMEDIFF('2000:01:01 00:00:00',
- >'2000:01:01 00:00:00.000001');
- >'-00:00:00.000001' mysql>SELECT TIMEDIFF('2008-12-31 23:59:59.000001',
- >'2008-12-30 01:01:01.000002');
- > '46:58:57.999999'
TIMESTAMP(
,
expr
)TIMESTAMP(
expr1
,expr2
)
使用单个参数,此函数将日期或日期时间表达式
expr
作为日期时间值返回。
使用两个参数,它将时间表达式添加
expr2
到日期或日期时间表达式
expr1
,并将结果作为日期时间值返回。
MySQL的>SELECT TIMESTAMP('2003-12-31');
- >'2003-12-31 00:00:00' MySQL的>SELECT TIMESTAMP('2003-12-31 12:00:00','12:00:00');
- >'2004-01-01 00:00:00'
TIMESTAMPADD(
unit
,interval
,datetime_expr
)
将整数表达式添加
interval
到日期或日期时间表达式
datetime_expr
。
为单元
interval
将被给定
unit
参数,它应为以下值中的一个:
MICROSECOND
(微秒), ,
SECOND
,
MINUTE
,
HOUR
,
DAY
,
WEEK
,
MONTH
,
QUARTER
或
YEAR
。
unit
可以使用所示的关键字之一或前缀为,来指定
该
值
SQL_TSI_
。
例如,
DAY
并且
SQL_TSI_DAY
都是合法的。
MySQL的>SELECT TIMESTAMPADD(MINUTE,1,'2003-01-02');
- >'2003-01-02 00:01:00' MySQL的>SELECT TIMESTAMPADD(WEEK,1,'2003-01-02');
- >'2003-01-09'
TIMESTAMPDIFF(
unit
,datetime_expr1
,datetime_expr2
)
返回
datetime_expr2
-
datetime_expr1
,where
datetime_expr1
和
datetime_expr2
date或datetime表达式。
一个表达式可以是日期,另一个表达式可以是日期时间;
日期值被视为具有
'00:00:00'
必要
时间部分的日期时间
。
结果的单位(整数)由
unit
参数
给出
。
合法值
unit
与
TIMESTAMPADD()
函数
说明中列出的
值
相同
。
MySQL的>SELECT TIMESTAMPDIFF(MONTH,'2003-02-01','2003-05-01');
- > 3 MySQL的>SELECT TIMESTAMPDIFF(YEAR,'2002-05-01','2001-01-01');
- > -1 MySQL的>SELECT TIMESTAMPDIFF(MINUTE,'2003-02-01','2003-05-01 12:05:55');
- > 128885
此函数的date或datetime参数的顺序
TIMESTAMP()
与使用2个参数调用时与函数
使用的顺序相反
。
这与
DATE_FORMAT()
函数
类似
,但
format
字符串可能只包含小时,分钟,秒和微秒的格式说明符。
其他说明符产生一个
NULL
值或
0
。
如果该
time
值中包含一个小时的部分是大于
23
,则
%H
和
%k
小时的格式说明产生比通常范围大的值
0..23
。
其他小时格式说明符生成模数为12的小时值。
MySQL的> SELECT TIME_FORMAT('100:00:00', '%H %k %h %I %l');
- > '100 100 04 04 4'
返回
time
参数,转换为秒。
MySQL的>SELECT TIME_TO_SEC('22:23:00');
- > 80580 MySQL的>SELECT TIME_TO_SEC('00:39:38');
- > 2378
给定日期
date
,返回日期编号(自0年以来的天数)。
MySQL的>SELECT TO_DAYS(950501);
- > 728779 MySQL的>SELECT TO_DAYS('2007-10-07');
- > 733321
TO_DAYS()
不适用于格里高利历(1582年)出现之前的值,因为它不考虑日历更改时丢失的日期。
对于1582年之前的日期(可能是其他语言环境中的后一年),此函数的结果不可靠。
有关详细信息
,
请参见
第12.8节“MySQL使用什么日历?”
。
请记住,MySQL使用
第11.3节“日期和时间类型”中
的规则将日期中的两位数年份值转换为四位数形式
。
例如,
'2008-10-07'
并且
'08-10-07'
被看作是相同的日期:
MySQL的> SELECT TO_DAYS('2008-10-07'), TO_DAYS('08-10-07');
- > 733687,733687
在MySQL中,零日期被定义为
'0000-00-00'
,即使此日期本身被视为无效。
这意味着,for
'0000-00-00'
和
'0000-01-01'
,
TO_DAYS()
返回此处显示的值:
MySQL的>SELECT TO_DAYS('0000-00-00');
+ ----------------------- + | to_days('0000-00-00')| + ----------------------- + | NULL | + ----------------------- + 1排,1警告(0.00秒) MySQL的>SHOW WARNINGS;
+ --------- + ------ + -------------------------------- -------- + | 等级| 代码| 消息| + --------- + ------ + -------------------------------- -------- + | 警告| 1292 | 日期时间值不正确:'0000-00-00'| + --------- + ------ + -------------------------------- -------- + 1排(0.00秒) MySQL的>SELECT TO_DAYS('0000-01-01');
+ ----------------------- + | to_days('0000-01-01')| + ----------------------- + | 1 | + ----------------------- + 1排(0.00秒)
无论是否
ALLOW_INVALID_DATES
启用SQL服务器模式,都是如此。
给定日期或日期时间
expr
,返回自年份0以来的秒数。如果
expr
不是有效的日期或日期时间值,则返回
NULL
。
MySQL的>SELECT TO_SECONDS(950501);
- > 62966505600 MySQL的>SELECT TO_SECONDS('2009-11-29');
- > 63426672000 MySQL的>SELECT TO_SECONDS('2009-11-29 13:43:32');
- > 63426721412 MySQL的>SELECT TO_SECONDS( NOW() );
- > 63426721458
例如
TO_DAYS()
,
TO_SECONDS()
不适用于格里高利历(1582年)出现之前的值,因为它没有考虑日历更改时丢失的日期。
对于1582年之前的日期(可能是其他语言环境中的后一年),此函数的结果不可靠。
有关详细信息
,
请参见
第12.8节“MySQL使用什么日历?”
。
例如
TO_DAYS()
,
TO_SECONDS()
使用
第11.3节“日期和时间类型”中
的规则将日期中的两位数年份值转换为四位数形式
。
在MySQL中,零日期被定义为
'0000-00-00'
,即使此日期本身被视为无效。
这意味着,for
'0000-00-00'
和
'0000-01-01'
,
TO_SECONDS()
返回此处显示的值:
MySQL的>SELECT TO_SECONDS('0000-00-00');
+ -------------------------- + | TO_SECONDS('0000-00-00')| + -------------------------- + | NULL | + -------------------------- + 1排,1警告(0.00秒) MySQL的>SHOW WARNINGS;
+ --------- + ------ + -------------------------------- -------- + | 等级| 代码| 消息| + --------- + ------ + -------------------------------- -------- + | 警告| 1292 | 日期时间值不正确:'0000-00-00'| + --------- + ------ + -------------------------------- -------- + 1排(0.00秒) MySQL的>SELECT TO_SECONDS('0000-01-01');
+ -------------------------- + | TO_SECONDS('0000-01-01')| + -------------------------- + | 86400 | + -------------------------- + 1排(0.00秒)
无论是否
ALLOW_INVALID_DATES
启用SQL服务器模式,都是如此。
如果
UNIX_TIMESTAMP()
没有
date
参数调用,则返回表示自
'1970-01-01
00:00:00'
UTC
以来秒数的Unix时间戳
。
如果
UNIX_TIMESTAMP()
使用
date
参数调用,则它将参数的值返回为
'1970-01-01 00:00:00'
UTC后的
秒数
。
服务器将其解释
date
为会话时区中的值,并将其转换为UTC的内部Unix时间戳值。
(客户端可以设置会话时区中描述
第5.1.13,“MySQL服务器时区支持”
。)该
date
参数可以是一个
DATE
,
DATETIME
或
TIMESTAMP
串,或在多个
YYMMDD
,
YYMMDDhhmmss
,
YYYYMMDD
,或者
YYYYMMDDhhmmss
格式。
如果参数包括时间部分,则它可以可选地包括小数秒部分。
如果没有给出参数或者参数不包含小数秒部分,或者
DECIMAL
如果给出包含小数秒部分的参数,则
返回值是整数
。
当
date
参数是
TIMESTAMP
列时,
UNIX_TIMESTAMP()
直接返回内部时间戳值,没有隐式的
“
字符串到Unix时间戳
”
转换。
参数值的有效范围与
TIMESTAMP
数据类型
相同
:
'1970-01-01 00:00:01.000000'
UTC到
'2038-01-19 03:14:07.999999'
UTC。
如果您将超出范围的日期传递给
UNIX_TIMESTAMP()
,则返回
0
。
MySQL的>SELECT UNIX_TIMESTAMP();
- > 1447431666 MySQL的>SELECT UNIX_TIMESTAMP('2015-11-13 10:20:19');
- > 1447431619 MySQL的>SELECT UNIX_TIMESTAMP('2015-11-13 10:20:19.012');
- > 1447431619.012
如果您使用
UNIX_TIMESTAMP()
和
FROM_UNIXTIME()
转换非UTC时区中的值和Unix时间戳值,则转换是有损的,因为映射在两个方向上都不是一对一的。
例如,由于夏令时(DST)等本地时区更改的约定,可以
UNIX_TIMESTAMP()
将两个在非UTC时区中不同的值映射到相同的Unix时间戳值。
FROM_UNIXTIME()
将该值映射回原始值中的一个。
下面是一个示例,使用
MET
时区
中不同的值
:
mysql>SET time_zone = 'MET';
mysql>SELECT UNIX_TIMESTAMP('2005-03-27 03:00:00');
+ --------------------------------------- + | UNIX_TIMESTAMP('2005-03-27 03:00:00')| + --------------------------------------- + | 1111885200 | + --------------------------------------- + MySQL的>SELECT UNIX_TIMESTAMP('2005-03-27 02:00:00');
+ --------------------------------------- + | UNIX_TIMESTAMP('2005-03-27 02:00:00')| + --------------------------------------- + | 1111885200 | + --------------------------------------- + MySQL的>SELECT FROM_UNIXTIME(1111885200);
+ --------------------------- + | FROM_UNIXTIME(1111885200)| + --------------------------- + | 2005-03-27 03:00:00 | + --------------------------- +
要使用诸如
'MET'
或的
命名时区
'Europe/Amsterdam'
,必须正确设置时区表。
有关说明,请参见
第5.1.13节“MySQL服务器时区支持”
。
如果要减去
UNIX_TIMESTAMP()
列,可能需要将它们转换为有符号整数。
请参见
第12.10节“强制转换函数和运算符”
。
以值
'YYYY-MM-DD'
或
YYYYMMDD
格式
返回当前UTC日期
,具体取决于函数是在字符串还是数字上下文中使用。
MySQL的> SELECT UTC_DATE(), UTC_DATE() + 0;
- >'2003-08-14',20030814
以值
'hh:mm:ss'
或
hhmmss
格式
返回当前UTC时间
,具体取决于函数是在字符串还是数字上下文中使用。
如果
fsp
给出参数以指定从0到6的小数秒精度,则返回值包括该多个数字的小数秒部分。
MySQL的> SELECT UTC_TIME(), UTC_TIME() + 0;
- > '18:07:53',180753.000000
UTC_TIMESTAMP
,
UTC_TIMESTAMP([
fsp
])
以值
'YYYY-MM-DD hh:mm:ss'
或
YYYYMMDDhhmmss
格式
返回当前UTC日期和时间
,具体取决于函数是在字符串还是数字上下文中使用。
如果
fsp
给出参数以指定从0到6的小数秒精度,则返回值包括该多个数字的小数秒部分。
MySQL的> SELECT UTC_TIMESTAMP(), UTC_TIMESTAMP() + 0;
- >'2003-08-14 18:08:04',20030814180804.000000
此函数返回的周数
date
。
的双参数形式
WEEK()
允许你指定星期是否在周日或周一,以及是否返回值应在范围从启动
0
到
53
或者从
1
到
53
。
如果
mode
省略
该
参数,
default_week_format
则使用系统变量
的值
。
请参见
第5.1.8节“服务器系统变量”
。
下表描述了
mode
参数的工作原理。
模式 | 一周的第一天 | 范围 | 第1周是第一周...... |
---|---|---|---|
0 | 星期日 | 0-53 | 在今年的一个星期天 |
1 | 星期一 | 0-53 | 今年有4天或更多天 |
2 | 星期日 | 1-53 | 在今年的一个星期天 |
3 | 星期一 | 1-53 | 今年有4天或更多天 |
4 | 星期日 | 0-53 | 今年有4天或更多天 |
五 | 星期一 | 0-53 | 在今年的星期一 |
6 | 星期日 | 1-53 | 今年有4天或更多天 |
7 | 星期一 | 1-53 | 在今年的星期一 |
对于
mode
具有的意义价值
“
有4个或更多天,今年
, ”
1988年:周根据ISO 8601编号:
如果包含1月1日的一周在新的一年中有4天或更多天,则为第1周。
否则,它是上一年的最后一周,下一周是第1周。
MySQL的>SELECT WEEK('2008-02-20');
- > 7 MySQL的>SELECT WEEK('2008-02-20',0);
- > 7 MySQL的>SELECT WEEK('2008-02-20',1);
- > 8 MySQL的>SELECT WEEK('2008-12-31',1);
- > 53
如果日期落入在上周的前一年,MySQL的返回
0
,如果你不使用
2
,
3
,
6
,或
7
作为可选的
mode
参数:
MySQL的> SELECT YEAR('2000-01-01'), WEEK('2000-01-01',0);
- > 2000,0
可能有人会说
WEEK()
应该返回
52
,因为给定的日期实际上是在1999年的第52周时
WEEK()
的回报
0
,而不是使返回值是
“
给定年份的周数。
“
WEEK()
当与从日期中提取日期部分的其他功能结合
使用时,这使得该
功能可靠。
如果你喜欢就包含了一周的指定日期的第一天计算一年的结果,使用
0
,
2
,
5
,或
7
作为可选
mode
参数。
MySQL的> SELECT WEEK('2000-01-01',2);
- > 52
或者,使用以下
YEARWEEK()
功能:
MySQL的>SELECT YEARWEEK('2000-01-01');
- > 199952 MySQL的>SELECT MID(YEARWEEK('2000-01-01'),5,2);
- > '52'
返回
date
(
0
= Monday,
1
= Tuesday,...
6
= Sunday)
的工作日索引
。
MySQL的>SELECT WEEKDAY('2008-02-03 22:23:00');
- > 6 MySQL的>SELECT WEEKDAY('2007-11-06');
- > 1
返回日期从范围内的数字日历星期
1
来
53
。
WEEKOFYEAR()
是一个相当于的兼容性函数
。
WEEK(
date
,3)
MySQL的> SELECT WEEKOFYEAR('2008-02-20');
- > 8
返回年
date
,范围
1000
至
9999
,或
0
为
“
零
”
日期。
MySQL的> SELECT YEAR('1987-01-01');
- > 1987年
YEARWEEK(
,
date
)YEARWEEK(
date
,mode
)
返回日期的年份和星期。 结果中的年份可能与一年中第一周和最后一周的日期参数中的年份不同。
该
mode
论证的作用与
mode
参数
完全相同
WEEK()
。
对于单参数语法,使用
mode
值0。
不同
WEEK()
,价值
default_week_format
不会影响
YEARWEEK()
。
MySQL的> SELECT YEARWEEK('1987-01-01');
- > 198652
周数是从什么不同的
WEEK()
函数将返回(
0
)的可选参数
0
或
1
作为
WEEK()
然后返回周中的给定年份的情况下。
MySQL使用所谓的 公历格里高利历 。
每个从朱利安日历到格里高利历的国家都不得不在转换期间丢弃至少十天。 要了解其工作原理,请考虑1582年10月,即第一个Julian-to-Gregorian切换发生的月份。
星期一 | 星期二 | 星期三 | 星期四 | 星期五 | 星期六 | 星期日 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 三十 | 31 |
10月4日至10月15日之间没有日期。这种不连续性称为 转换 。 切换前的任何日期都是朱利安,切换后的任何日期都是格里高利。 切换期间的日期不存在。
应用于未实际使用的日期的日历称为
预感
。
因此,如果我们假设从来没有切换和格里高利规则总是统治,我们有一个预感格里高利历。
这是MySQL使用的,正如标准SQL所要求的那样。
出于这个原因,切换之前的日期存储为MySQL
DATE
或
DATETIME
必须调整值以补偿差异。
重要的是要意识到切换并非在所有国家同时发生,而且发生的时间越晚,丢失的天数就越多。
例如,在英国,它发生在1752年,当时9月2日星期三之后是9月14日星期四。俄罗斯一直保持朱利安历法直到1918年,在此过程中损失了13天,并且通常被称为
“
十月”
根据格里高利历法,
革命
“
发生在11月。
MATCH
(
col1
,col2
,...)
AGAINST (expr
[search_modifier
])
search_modifier:
{
在自然语言模式
| 具有查询扩展的自然语言模式
| 在布尔模式
| 随着扩展
}
MySQL支持全文索引和搜索:
MySQL中的全文索引是类型的索引
FULLTEXT
。
全文索引只能使用
InnoDB
或
MyISAM
表格,并且只能用于创建
CHAR
,
VARCHAR
或
TEXT
列。
MySQL
提供了一个内置的全文ngram解析器,支持中文,日文和韩文(CJK),以及一个可安装的日文版MeCab全文解析器插件。
解析差异在
第12.9.8节“ngram全文分析器”
和
第12.9.9节“MeCab全文分析器插件”
中概述
。
甲
FULLTEXT
索引定义可以在被给予
CREATE
TABLE
的语句中创建表时,或者稍后使用添加
ALTER
TABLE
或
CREATE
INDEX
。
对于大型数据集,将数据加载到没有
FULLTEXT
索引
的表中,
然后在此之后创建索引
要快得多
,而不是将数据加载到具有现有
FULLTEXT
索引
的表中
。
使用
MATCH() ... AGAINST
语法
执行全文搜索
。
MATCH()
采用逗号分隔的列表来命名要搜索的列。
AGAINST
获取要搜索的字符串,以及指示要执行的搜索类型的可选修饰符。
搜索字符串必须是在查询评估期间保持不变的字符串值。
例如,这排除了表列,因为每行可能不同。
有三种类型的全文搜索:
自然语言搜索将搜索字符串解释为自然人类语言(自由文本中的短语)中的短语。 没有特殊运算符,但双引号(“)字符除外。 禁用 词列表适用。有关 禁用 词列表的更多信息,请参见 第12.9.4节”全文 停用词 “ 。
如果
IN NATURAL LANGUAGE MODE
给出修饰符或者没有给出修饰符,则
全文搜索是自然语言搜索
。
有关更多信息,请参见
第12.9.1节“自然语言全文搜索”
。
布尔搜索使用特殊查询语言的规则来解释搜索字符串。
该字符串包含要搜索的单词。
它还可以包含指定要求的运算符,以便在匹配的行中必须存在或不存在单词,或者它应该比通常更高或更低的权重。
搜索索引中省略了某些常用词(停用词),如果搜索字符串中存在,则不匹配。
该
IN BOOLEAN MODE
修饰符指定一个布尔搜索。
有关更多信息,请参见
第12.9.2节“布尔全文搜索”
。
查询扩展搜索是自然语言搜索的修改。
搜索字符串用于执行自然语言搜索。
然后将搜索返回的最相关行中的单词添加到搜索字符串中,然后再次进行搜索。
查询返回第二次搜索中的行。
该
IN NATURAL LANGUAGE MODE WITH
QUERY EXPANSION
或
WITH QUERY
EXPANSION
修改指定查询扩展搜索。
有关更多信息,请参见
第12.9.3节“使用查询扩展的全文搜索”
。
有关
FULLTEXT
查询性能的
信息
,请参见
第8.3.5节“列索引”
。
有关
InnoDB
FULLTEXT
索引的
更多信息
,请参见
第15.6.2.4节“InnoDB FULLTEXT索引”
。
第12.9.5节“全文限制” 中列出了对全文搜索的 约束 。
该
myisam_ftdump
工具转储的内容
MyISAM
全文索引。
这可能有助于调试全文查询。
请参见
第4.6.3节“
myisam_ftdump
- 显示全文索引信息”
。
默认情况下或使用
IN NATURAL LANGUAGE
MODE
修饰符,
MATCH()
函数会针对
文本集合
执行字符串的自然语言搜索
。
集合是
FULLTEXT
索引中
包含的一个或多个列的集合
。
搜索字符串作为参数给出
AGAINST()
。
对于表中的每一行,
MATCH()
返回相关值;
也就是说,搜索字符串与
MATCH()
列表中
指定的列中该行中的文本之间的相似性度量
。
MySQL的>CREATE TABLE articles (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200),
body TEXT,
FULLTEXT (title,body)
) ENGINE=InnoDB;
查询正常,0行受影响(0.08秒) MySQL的>INSERT INTO articles (title,body) VALUES
('MySQL Tutorial','DBMS stands for DataBase ...'),
('How To Use MySQL Well','After you went through a ...'),
('Optimizing MySQL','In this tutorial we will show ...'),
('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'),
('MySQL vs. YourSQL','In the following database comparison ...'),
('MySQL Security','When configured properly, MySQL ...');
查询OK,6行受影响(0.01秒) 记录:6个重复:0个警告:0 MySQL的>SELECT * FROM articles
WHERE MATCH (title,body)
AGAINST ('database' IN NATURAL LANGUAGE MODE);
+ ---- + ------------------- + ------------------------ ------------------ + | id | 标题| 身体| + ---- + ------------------- + ------------------------ ------------------ + | 1 | MySQL教程| DBMS代表DataBase ... | | 5 | MySQL与YourSQL | 在以下数据库比较中...... | + ---- + ------------------- + ------------------------ ------------------ + 2行(0.00秒)
默认情况下,搜索以不区分大小写的方式执行。
要执行区分大小写的全文搜索,请对索引列使用区分大小写或二进制排序规则。
例如,
utf8mb4
可以为
使用
字符集的
列
分配整数
utf8mb4_0900_as_cs
或
utf8mb4_bin
使其对全文搜索区分大小写。
当
MATCH()
在
WHERE
子句中
使用时
,如前面所示的示例中所示,返回的行将首先自动排序,具有最高相关性。
相关性值是非负浮点数。
零相关意味着没有相似性。
相关性是根据行(文档)中的单词数,行中唯一单词的数量,集合中的单词总数以及包含特定单词的行数计算的。
术语 “ 文档 ” 可以与术语 “ 行 ” 互换使用 ,并且两个术语都指行的索引部分。 术语 “ 集合 ” 指的是索引列并包含所有行。
要简单地计算匹配,您可以使用如下查询:
MySQL的>SELECT COUNT(*) FROM articles
WHERE MATCH (title,body)
AGAINST ('database' IN NATURAL LANGUAGE MODE);
+ ---------- + | COUNT(*)| + ---------- + | 2 | + ---------- + 1排(0.00秒)
您可能会发现重写查询的速度更快,如下所示:
MySQL的>SELECT
COUNT(IF(MATCH (title,body) AGAINST ('database' IN NATURAL LANGUAGE MODE), 1, NULL))
AS count
FROM articles;
+ ------- + | 计数| + ------- + | 2 | + ------- + 1排(0.03秒)
第一个查询执行一些额外的工作(按相关性对结果进行排序),但也可以使用基于该
WHERE
子句
的索引查找
。
如果搜索匹配几行,索引查找可能会使第一个查询更快。
第二个查询执行全表扫描,如果搜索词存在于大多数行中,则可能比索引查找更快。
对于自然语言全文搜索,
MATCH()
函数中
指定的列
必须与表中某些
FULLTEXT
索引中
包含的列相同
。
对于前面的查询,请注意
MATCH()
函数(
title
和
body
)中指定的列与
article
表
FULLTEXT
索引
定义中指定
的列
相同
。
要
单独
搜索
title
或
body
单独
搜索
,可以
FULLTEXT
为每列
创建单独的
索引。
您还可以执行布尔搜索或使用查询扩展进行搜索。 第12.9.2节“布尔全文搜索” 和 第12.9.3节“使用查询扩展 的全文搜索” 中介绍了这些搜索类型 。
使用索引的全文搜索只能从
MATCH()
子句中
的单个表中命名列,
因为索引不能跨越多个表。
对于
MyISAM
表,可以在没有索引的情况下进行布尔搜索(尽管速度较慢),在这种情况下,可以从多个表中命名列。
上面的示例是一个基本插图,显示了如何使用按
MATCH()
相关性降低的顺序返回行
的
函数。
下一个示例显示了如何显式检索相关性值。
返回的行不是有序的,因为该
SELECT
语句既不包含
WHERE
也不
包含
ORDER BY
子句:
MySQL的>SELECT id, MATCH (title,body)
AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE) AS score
FROM articles;
+ ---- + --------------------- + | id | 得分| + ---- + --------------------- + | 1 | 0.22764469683170319 | | 2 | 0 | | 3 | 0.22764469683170319 | | 4 | 0 | | 5 | 0 | | 6 | 0 | + ---- + --------------------- + 6行(0.00秒)
以下示例更复杂。
查询返回相关性值,它还按相关性递减的顺序对行进行排序。
要实现此结果,请指定
MATCH()
两次:一次在
SELECT
列表中,一次在
WHERE
子句中。
这不会产生额外的开销,因为MySQL优化器注意到这两个
MATCH()
调用是相同的,只调用一次全文搜索代码。
MySQL的>SELECT id, body, MATCH (title,body) AGAINST
('Security implications of running MySQL as root'
IN NATURAL LANGUAGE MODE) AS score
FROM articles WHERE MATCH (title,body) AGAINST
('Security implications of running MySQL as root'
IN NATURAL LANGUAGE MODE);
+ ---- + ------------------------------- + ------ ----------- + | id | 身体| 得分| + ---- + ------------------------------- + ------ ----------- + | 4 | 1.永远不要以root身份运行mysqld。2. ... | 1.5219271183014 | | 6 | 正确配置后,MySQL ... | 1.3114095926285 | + ---- + ------------------------------- + ------ ----------- + 2行(0.00秒)
双引号(
"
)字符中包含的短语仅匹配
字面上
包含短语的行
,因为它是键入的
。
全文引擎将短语拆分为单词,并
FULLTEXT
在单词
的
索引中
执行搜索
。
非单词字符不需要完全匹配:短语搜索只需要匹配包含与短语完全相同的单词并且顺序相同。
例如,
"test
phrase"
匹配
"test, phrase"
。
如果短语不包含索引中的单词,则结果为空。
例如,如果所有单词都是停用词或短于索引单词的最小长度,则结果为空。
MySQL
FULLTEXT
实现将任何真实单词字符序列(字母,数字和下划线)视为单词。
该序列也可能包含撇号(
'
),但不能超过一行。
这意味着它
aaa'bbb
被视为一个词,但
aaa''bbb
被视为两个词。
FULLTEXT
解析器
剥离一个单词开头或结尾的撇号
;
'aaa'bbb'
将被解析为
aaa'bbb
。
内置
FULLTEXT
解析器通过查找某些分隔符来确定单词的开始和结束位置;
例如,
(空格),
,
(逗号)和
.
(句点)。
如果单词没有用分隔符分隔(例如,中文),则内置
FULLTEXT
解析器无法确定单词的开始或结束位置。
为了能够将这些语言中的单词或其他索引术语添加到
FULLTEXT
使用内置
FULLTEXT
解析器
的
索引
,您必须对它们进行预处理,以便它们由某个任意分隔符分隔。
或者,您可以创建
FULLTEXT
使用ngram解析器插件(中文,日文或韩文)或MeCab解析器插件(日文)的索引。
可以编写一个替换内置全文解析器的插件。
有关详细信息,请参见
第29.2节“MySQL插件API”
。
例如解析器插件源代码,请参阅
plugin/fulltext
MySQL源代码分发
的
目录。
在全文搜索中会忽略某些单词:
任何太短的单词都会被忽略。
通过全文搜索找到的默认最小单词长度是
InnoDB
搜索索引的
三个字符
,或者四个字符
MyISAM
。
:您可以通过创建索引之前设置一个配置选项来控制截止
innodb_ft_min_token_size
的配置选项
InnoDB
搜索索引,或
ft_min_word_len
为
MyISAM
。
此行为不适用于
FULLTEXT
使用ngram解析器的索引。
对于ngram解析器,令牌长度由
ngram_token_size
选项
定义
。
禁用词列表中的单词将被忽略。
禁用词是诸如
“
the
”
或
“
some
”之
类的词
,它是如此常见以至于它被认为具有零语义值。
有一个内置的禁用词列表,但它可以被用户定义的列表覆盖。
对于
InnoDB
搜索索引和
MyISAM
一些
,停用词列表和相关配置选项是不同
的。
停用词处理由配置选项来控制
innodb_ft_enable_stopword
,
innodb_ft_server_stopword_table
和
innodb_ft_user_stopword_table
用于
InnoDB
搜索的索引,并且
ft_stopword_file
对于
MyISAM
那些。
请参见 第12.9.4节“全文 停用词 ” 以查看默认的停用词列表以及如何更改它们。 可以按 第12.9.6节“微调MySQL全文搜索”中 所述更改默认的最小字长 。
集合和查询中的每个正确单词都根据其在集合或查询中的重要性进行加权。 因此,许多文档中存在的单词具有较低的权重,因为它在该特定集合中具有较低的语义值。 相反,如果这个词很少见,它会获得更高的权重。 组合单词的权重以计算行的相关性。 这种技术最适合大型集合。
对于非常小的表,单词分布不能充分反映其语义值,并且此模型有时可能会对
MyISAM
表
上的搜索索引产生奇怪的结果
。
例如,尽管
前面显示
的
表格的
每一行都有
“
MySQL
”
articles
一词,但
MyISAM
搜索索引中
的单词
搜索不会产生任何结果:
MySQL的>SELECT * FROM articles
WHERE MATCH (title,body)
AGAINST ('MySQL' IN NATURAL LANGUAGE MODE);
空集(0.00秒)
搜索结果为空,因为 “ MySQL ” 一词出现在至少50%的行中,因此被有效地视为一个停用词。 这种过滤技术更适用于大型数据集,您可能不希望结果集从1GB表中返回每隔一行,而不是小型数据集,因为它可能会导致流行术语的结果不佳。
当您第一次尝试全文搜索以查看其工作方式时,50%的阈值会让您感到惊讶,并使
InnoDB
表格更适合全文搜索的实验。
如果您创建一个
MyISAM
表并仅在其中插入一行或两行文本,则文本中的每个单词都会出现在至少50%的行中。
因此,在表包含更多行之前,搜索不会返回任何结果。
需要绕过50%限制的用户可以在
InnoDB
表
上构建搜索索引
,或使用
第12.9.2节“布尔全文搜索”中
介绍的布尔搜索模式
。
MySQL可以使用
IN BOOLEAN MODE
修饰符
执行布尔全文搜索
。
使用此修饰符,某些字符在搜索字符串中的单词的开头或结尾处具有特殊含义。
在以下查询中,
+
和
-
运算符分别表示必须存在或不存在单词才能进行匹配。
因此,查询检索包含单词
“
MySQL
”
但
不
包含单词
“
YourSQL
”的所有行
:
MySQL的>SELECT * FROM articles WHERE MATCH (title,body)
AGAINST ('+MySQL -YourSQL' IN BOOLEAN MODE);
+ ---- + ----------------------- + -------------------- ----------------- + | id | 标题| 身体| + ---- + ----------------------- + -------------------- ----------------- + | 1 | MySQL教程| DBMS代表DataBase ... | | 2 | 如何使用MySQL井 经过一段时间...... | | 3 | 优化MySQL | 在本教程中,我们将展示... | | 4 | 1001 MySQL技巧| 1.永远不要以root身份运行mysqld。2. ... | | 6 | MySQL安全| 正确配置后,MySQL ... | + ---- + ----------------------- + -------------------- ----------------- +
在实现此功能时,MySQL使用有时被称为 隐含布尔逻辑 的内容
+
代表
AND
-
代表
NOT
[
无操作员
]暗示
OR
布尔全文搜索具有以下特征:
它们不会按相关性降低的顺序自动对行进行排序。
InnoDB
表需要
表达式的
FULLTEXT
所有列上的索引
MATCH()
来执行布尔查询。
MyISAM
即使没有
FULLTEXT
索引,
对
搜索索引的
布尔查询
也可以工作
,尽管以这种方式执行的搜索会非常慢。
最小和最大字长全文参数适用于
FULLTEXT
使用内置
FULLTEXT
解析器和MeCab解析器插件
创建的索引
。
innodb_ft_min_token_size
并
innodb_ft_max_token_size
用于
InnoDB
搜索索引。
ft_min_word_len
并
ft_max_word_len
用于
MyISAM
搜索索引。
最小和最大字长全文参数不适用于
FULLTEXT
使用ngram解析器创建的索引。
ngram标记大小由
ngram_token_size
选项
定义
。
停止字适用,通过控制
innodb_ft_enable_stopword
,
innodb_ft_server_stopword_table
以及
innodb_ft_user_stopword_table
对
InnoDB
搜索索引,并
ft_stopword_file
为
MyISAM
那些。
InnoDB
全文搜索不支持在单个搜索词上使用多个运算符,如下例所示:
'++apple'
。
在单个搜索词上使用多个运算符会将语法错误返回到标准输出。
MyISAM全文搜索将成功处理相同的搜索,忽略除紧邻搜索词的运算符之外的所有运算符。
InnoDB
全文搜索仅支持前导加号或减号。
例如,
InnoDB
支持
'+apple'
但不支持
'apple+'
。
指定尾随加号或减号会导致
InnoDB
报告语法错误。
InnoDB
全文搜索不支持使用带有通配符(
'+*'
),加号和减号组合(
'+-'
)或带正号和减号组合(
'+-apple'
)的
前导加号
。
这些无效查询返回语法错误。
InnoDB
全文搜索不支持
@
在布尔
全文搜索中使用该
符号。
该
@
符号保留供
@distance
邻近搜索运算符使用。
它们不使用适用于
MyISAM
搜索索引
的50%阈值
。
布尔全文搜索功能支持以下运算符:
+
前导或尾随加号表示该单词
必须
出现在返回的每一行中。
InnoDB
只支持领先加号。
-
前导或尾随减号表示该单词
不得
出现在任何返回的行中。
InnoDB
只支持领先的减号。
注意:
-
运算符仅用于排除其他搜索项以其他方式匹配的行。
因此,仅包含前面的术语的布尔模式搜索
-
返回空结果。
它不会返回
“
除包含任何排除条款的行之外的所有行。
”
(没有运营商)
默认情况下(当既未
指定
也
+
未
-
指定时),该单词是可选的,但包含它的行的等级更高。
这模仿了
MATCH() ...
AGAINST()
没有
IN BOOLEAN
MODE
修饰符
的行为
。
@
distance
此运算符
InnoDB
仅
适用于
表。
它测试两个或多个单词是否都在相互指定的距离内开始,用单词测量。
例如,
在
运算符
之前的双引号字符串中指定搜索词
@
distance
MATCH(col1) AGAINST('"word1
word2 word3" @8' IN BOOLEAN MODE)
> <
这两个运算符用于更改单词对分配给行的相关性值的贡献。
该
>
运营商的贡献增加以及
<
运营商降低它。
请参阅此列表后面的示例。
( )
括号将单词组合成子表达式。 括号内的组可以嵌套。
~
前导波浪号充当否定运算符,导致该词对该行相关性的贡献为负。
这对标记
“
噪音
”
字
很有用
。
包含这样一个单词的行的评级低于其他行,但不会像
-
操作员
那样完全排除
。
*
星号用作截断(或通配符)运算符。
与其他运算符不同,它
附加
到要受影响的单词。
如果单词以
*
操作符
前面的单词开头,则单词匹配
。
如果使用截断运算符指定了一个单词,则它不会从布尔查询中删除,即使它太短或是一个停用词。
无论一个字太短从确定
innodb_ft_min_token_size
设置为
InnoDB
表,或
ft_min_word_len
对
MyISAM
表。
这些选项不适用于
FULLTEXT
使用ngram解析器的索引。
通配字被视为必须出现在一个或多个单词的开头的前缀。
如果最小字长为4,则搜索
可以返回比搜索更少的行
,因为第二个查询忽略了太短的搜索项
。
'+
word
+the*''+
word
+the'the
"
双引号(
"
)字符中包含的短语仅匹配
字面上
包含短语的行
,因为它是键入的
。
全文引擎将短语拆分为单词,并
FULLTEXT
在单词
的
索引中
执行搜索
。
非单词字符不需要完全匹配:短语搜索只需要匹配包含与短语完全相同的单词并且顺序相同。
例如,
"test phrase"
匹配
"test,
phrase"
。
如果短语不包含索引中的单词,则结果为空。 由于多种因素的组合,单词可能不在索引中:如果它们在文本中不存在,则是停用词,或者短于索引单词的最小长度。
以下示例演示了一些使用布尔全文运算符的搜索字符串:
'apple banana'
查找包含两个单词中至少一个的行。
'+apple +juice'
查找包含两个单词的行。
'+apple macintosh'
查找包含单词 “ apple ”的 行,但如果它们也包含 “ macintosh ”, 则将行排名更高 。
'+apple -macintosh'
查找包含单词 “ apple ” 但不 包含 “ macintosh ”的行 。
'+apple ~macintosh'
查找包含单词
“
apple
”
的行,但如果该行还包含单词
“
macintosh
”
,则将其
评级
为低于不行的行。
这
比搜索
“
更柔和
”
'+apple
-macintosh'
,
“
macintosh
”
的存在
导致行根本不返回。
'+apple +(>turnover <strudel)'
查找包含单词 “ apple ” 和 “ turnover ” ,或 “ apple ” 和 “ strudel ” (按任意顺序)的行,但排名 “ apple turnover ” 高于 “ apple strudel ” 。
'apple*'
查找包含诸如 “ apple ” , “ apples ” , “ applesauce ” 或 “ applet ” 等字词的行 。
'"some words"'
查找包含具体字词行
“
有些字
”
(例如,包含的行
“
的一些智慧的话
”
而不是
“
一些干扰词
”
)。
请注意,
"
包含该短语的字符是分隔该短语的运算符字符。
它们不是包含搜索字符串本身的引号。
InnoDB
全文搜索以
Sphinx
全文搜索引擎
为模型,所
使用的算法基于
BM25
和
TF-IDF
排名算法。
由于这些原因,
InnoDB
布尔全文搜索的
MyISAM
相关性排名
可能与
相关性排名
不同
。
InnoDB
使用
“
术语频率 - 逆文档频率
”
(
TF-IDF
)加权系统的变体来对给定全文搜索查询的文档的相关性进行排名。
该
TF-IDF
权重是基于一个字如何频繁地出现在文档中,通过字如何频繁地出现在集合中的所有文件偏移。
换句话说,单词出现在文档中的频率越高,单词出现在文档集合中的频率越低,文档排名越高。
术语frequency(
TF
)值是单词在文档中出现的次数。
IDF
使用以下公式计算单词
的逆文档频率(
)值,其中
total_records
是集合中
matching_records
的记录数,以及搜索项出现的记录数。
$ {IDF} = log10($ {total_records} / $ {matching_records})
当文档多次包含单词时,IDF值乘以TF值:
$ {TF} * $ {IDF}
使用
TF
和
IDF
值,使用以下公式计算文档的相关性排名:
$ {rank} = $ {TF} * $ {IDF} * $ {IDF}
该配方在以下实施例中说明。
此示例演示单字搜索的相关性排名计算。
mysql> CREATE TABLE文章( id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, title VARCHAR(200), 主体, FULLTEXT(标题,正文) )ENGINE = InnoDB; 查询OK,0行受影响(1.04秒) mysql> INSERT INTO文章(标题,正文)VALUES ('MySQL Tutorial','这个数据库教程......'), (“如何使用MySQL”,“在你经历了......”之后), ('优化数据库','在此数据库教程中......'), ('MySQL vs. YourSQL','比较数据库......'), ('MySQL Security','配置正确,MySQL ......'), ('数据库,数据库,数据库','数据库数据库'), ('1001 MySQL Tricks','1。永远不要以root身份运行mysqld.2。......'), ('MySQL全文索引','MySQL全文索引使用..'); 查询OK,8行受影响(0.06秒) 记录:8个重复:0个警告:0 mysql> SELECT id,title,body,MATCH(title,body)AGAINST('database'IN BOOLEAN MODE) AS评分来自文章ORDER BY得分DESC; + ---- + ------------------------------ + ------------- ------------------------ + --------------------- + | id | 标题| 身体| 得分| + ---- + ------------------------------ + ------------- ------------------------ + --------------------- + | 6 | 数据库,数据库,数据库| 数据库数据库| 1.0886961221694946 | | 3 | 优化您的数据库| 在这个数据库教程中...... | 0.36289870738983154 | | 1 | MySQL教程| 这个数据库教程...... | 0.18144935369491577 | | 2 | 如何使用MySQL | 经过一段时间...... | 0 | | 4 | MySQL与YourSQL | 比较数据库时... | 0 | | 5 | MySQL安全| 正确配置后,MySQL ... | 0 | | 7 | 1001 MySQL技巧| 1.永远不要以root身份运行mysqld。2. ... | 0 | | 8 | MySQL全文索引| MySQL全文索引使用.. | 0 | + ---- + ------------------------------ + ------------- ------------------------ + --------------------- + 8行(0.00秒)
总共有8条记录,其中3条与
“
数据库
”
搜索词
匹配
。
第一个记录(
id 6
)包含搜索词6次,相关性排名为
1.0886961221694946
。
该等级值使用
TF
值6(
“
数据库
”
搜索词在记录中出现6次
id 6
)和
IDF
值0.42596873216370745计算,其计算如下(其中8是记录总数,3是记录数)搜索词出现在:):
$ {IDF} = log10(8/3)= 0.42596873216370745
然后
将
TF
和
IDF
值输入到排名公式中:
$ {rank} = $ {TF} * $ {IDF} * $ {IDF}
在MySQL命令行客户端中执行计算会返回排名值1.088696164686938。
mysql> SELECT 6 * log10(8/3)* log10(8/3); + ------------------------- + | 6 * log10(8/3)* log10(8/3)| + ------------------------- + | 1.088696164686938 | + ------------------------- + 1排(0.00秒)
您可能会注意到在返回的排名值略有差异
SELECT ... MATCH ...
AGAINST
语句和MySQL命令行客户端(
1.0886961221694946
对
1.088696164686938
)。
不同之处在于整数和浮点数/双精度之间的转换是如何在内部执行的
InnoDB
(以及相关的精度和舍入决策),以及它们如何在其他地方执行,例如在MySQL命令行客户端或其他类型的计算器中。
此示例演示了基于
articles
前一示例中使用
的
表和数据
的多字全文搜索的相关性排名计算
。
如果您搜索多个单词,则相关性排名值是每个单词的相关性排名值的总和,如下面的公式所示:
$ {rank} = $ {TF} * $ {IDF} * $ {IDF} + $ {TF} * $ {IDF} * $ {IDF}
对两个术语执行搜索('mysql tutorial')会返回以下结果:
mysql> SELECT id,title,body,MATCH(title,body)AGAINST('mysql tutorial'IN BOOLEAN MODE) AS评分来自文章ORDER BY得分DESC; + ---- + ------------------------------ + ------------- ------------------------ + ---------------------- + | id | 标题| 身体| 得分| + ---- + ------------------------------ + ------------- ------------------------ + ---------------------- + | 1 | MySQL教程| 这个数据库教程...... | 0.7405621409416199 | | 3 | 优化您的数据库| 在这个数据库教程中...... | 0.3624762296676636 | | 5 | MySQL安全| 正确配置后,MySQL ... | 0.031219376251101494 | | 8 | MySQL全文索引| MySQL全文索引使用.. | 0.031219376251101494 | | 2 | 如何使用MySQL | 经过一段时间...... | 0.015609688125550747 | | 4 | MySQL与YourSQL | 比较数据库时... | 0.015609688125550747 | | 7 | 1001 MySQL技巧| 1.永远不要以root身份运行mysqld。2. ... | 0.015609688125550747 | | 6 | 数据库,数据库,数据库| 数据库数据库| 0 | + ---- + ------------------------------ + ------------- ------------------------ + ---------------------- + 8行(0.00秒)
在第一个记录(
id 8
)中,'mysql'出现一次,'tutorial'出现两次。
'mysql'有六个匹配记录,'tutorial'有两个匹配记录。
当将这些值插入到多字搜索的排名公式中时,MySQL命令行客户端返回预期的排名值:
mysql> SELECT(1 * log10(8/6)* log10(8/6))+(2 * log10(8/2)* log10(8/2)); + ------------------------------------------------- ------ + | (1 * log10(8/6)* log10(8/6))+(2 * log10(8/2)* log10(8/2))| + ------------------------------------------------- ------ + | 0.7405621541938003 | + ------------------------------------------------- ------ + 1排(0.00秒)
SELECT ... MATCH ... AGAINST
在前面的示例中解释
了
语句和MySQL命令行客户端
返回的排名值的细微差别
。
全文搜索支持查询扩展(特别是其变体 “ 盲查询扩展 ” )。 当搜索短语太短时,这通常很有用,这通常意味着用户依赖于全文搜索引擎所缺乏的隐含知识。 例如,搜索 “ 数据库 ” 的用户 可能实际上意味着 “ MySQL ” , “ Oracle ” , “ DB2 ” 和 “ RDBMS ” 都是应该匹配 “ 数据库 ”的 短语 也应该归还。 这是隐含的知识。
通过添加
WITH QUERY
EXPANSION
或
IN NATURAL LANGUAGE MODE WITH
QUERY EXPANSION
跟随搜索短语
来启用盲查询扩展(也称为自动相关性反馈)
。
它通过执行两次搜索来工作,其中第二次搜索的搜索短语是与来自第一次搜索的几个最高度相关的文档连接的原始搜索短语。
因此,如果其中一个文档包含单词
“
databases
”
和单词
“
MySQL
”
,则第二个搜索查找包含单词
“
MySQL
”
的文档,
即使它们不包含单词
“
database
”
。
以下示例显示了这种差异:
MySQL的>SELECT * FROM articles
WHERE MATCH (title,body)
AGAINST ('database' IN NATURAL LANGUAGE MODE);
+ ---- + ------------------- + ------------------------ ------------------ + | id | 标题| 身体| + ---- + ------------------- + ------------------------ ------------------ + | 1 | MySQL教程| DBMS代表DataBase ... | | 5 | MySQL与YourSQL | 在以下数据库比较中...... | + ---- + ------------------- + ------------------------ ------------------ + 2行(0.00秒) MySQL的>SELECT * FROM articles
WHERE MATCH (title,body)
AGAINST ('database' WITH QUERY EXPANSION);
+ ---- + ----------------------- + -------------------- ---------------------- + | id | 标题| 身体| + ---- + ----------------------- + -------------------- ---------------------- + | 5 | MySQL与YourSQL | 在以下数据库比较中...... | | 1 | MySQL教程| DBMS代表DataBase ... | | 3 | 优化MySQL | 在本教程中,我们将展示... | | 6 | MySQL安全| 正确配置后,MySQL ... | | 2 | 如何使用MySQL井 经过一段时间...... | | 4 | 1001 MySQL技巧| 1.永远不要以root身份运行mysqld。2. ... | + ---- + ----------------------- + -------------------- ---------------------- + 6行(0.00秒)
另一个例子是Georges Simenon关于Maigret的书,当用户不确定如何拼写 “ Maigret ”时 。 搜索 “ Megre和不情愿的证人 ” 只发现 “ Maigret和不情愿的见证人 ” 而没有查询扩展。 使用查询扩展进行搜索会 在第二遍中 找到所有带有 “ Maigret ” 字样的书籍 。
由于盲查询扩展往往会通过返回非相关文档而显着增加噪声,因此仅在搜索短语较短时才使用它。
停止字被加载并使用服务器字符集和校对规则(该值搜索全文查询
character_set_server
和
collation_server
系统变量)。
假命中或遗漏如果停止字的文件或使用全文索引或搜索列有一个字符集或整理从不同的可能发生的禁用词查找
character_set_server
或
collation_server
。
禁用词查找的区分大小写取决于服务器排序规则。
例如,如果排序规则
utf8mb4_0900_ai_ci
,则查找
不区分大小写
,而如果排序规则为
utf8mb4_0900_as_cs
或
,则查找区分大小写
utf8mb4_bin
。
InnoDB
有一个相对较短的默认停用词列表,因为来自技术,文学和其他来源的文档通常使用短词作为关键词或重要短语。
例如,您可能会搜索
“
成为或不成为
”
并期望获得合理的结果,而不是忽略所有这些单词。
要查看默认的
InnoDB
停用词列表,请查询该
INFORMATION_SCHEMA.INNODB_FT_DEFAULT_STOPWORD
表。
mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_DEFAULT_STOPWORD; + ------- + | 价值| + ------- + | a | | 关于| | 一个| | 是| | 作为| | 在| | 是| | 通过| | com | | 德| | en | | 为| | 来自| | 如何| | 我| | 在| | 是| | 它| | la | | 的 | 在| | 或者 | 那个| | | | 这个| | 到| | 是| | 什么| | 当| | 哪里| | 谁| | 将| | 与| | und | | | | www | + ------- + 36行(0.00秒)
要为所有
InnoDB
表
定义自己的停用词列表
,请定义一个与表结构相同的
INNODB_FT_DEFAULT_STOPWORD
表,使用停用词填充它,并
在创建全文索引之前
将
innodb_ft_server_stopword_table
选项的值设置为表单中的值
。
停用词表必须有一个
名为的列
。
以下示例演示如何为其创建和配置新的全局停用词表
。
db_name
/table_name
VARCHAR
value
InnoDB
- 创建一个新的停用词表 mysql> CREATE TABLE my_stopwords(value VARCHAR(30))ENGINE = INNODB; 查询OK,0行受影响(0.01秒) - 插入停用词(为简单起见,在此示例中使用单个停用词) mysql> INSERT INTO my_stopwords(value)VALUES('Ishmael'); 查询正常,1行受影响(0.00秒) - 创建表格 mysql> CREATE TABLE opening_lines( id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, opening_line TEXT(500), 作者VARCHAR(200), title VARCHAR(200) )ENGINE = InnoDB; 查询OK,0行受影响(0.01秒) - 将数据插入表中 mysql> INSERT INTO opening_lines(opening_line,author,title)VALUES ('叫我以实玛利。','赫尔曼梅尔维尔','白鲸'), ('尖叫声来到天空。','托马斯品钦','重力彩虹', ('我是一个看不见的人。','拉尔夫埃利森','看不见的男人'), ('现在在哪里?谁现在?现在?','Samuel Beckett','The Unnamable'), ('一见钟情。','约瑟夫海勒','Catch-22'), ('所有这一切都发生了,或多或少。','Kurt Vonnegut','屠宰场五'), ('达洛卫太太说她会自己买花。','弗吉尼亚伍尔夫','达洛卫夫人', ('很高兴燃烧。','雷布拉德伯里','华氏451'); 查询OK,8行受影响(0.00秒) 记录:8个重复:0个警告:0 - 将innodb_ft_server_stopword_table选项设置为新的停用词表 mysql> SET GLOBAL innodb_ft_server_stopword_table ='test / my_stopwords'; 查询正常,0行受影响(0.00秒) - 创建全文索引(如果未定义FTS_DOC_ID列,则重建表) mysql> CREATE FULLTEXT INDEX idx ON opening_lines(opening_line); 查询正常,0行受影响,1警告(1.17秒) 记录:0重复:0警告:1
通过查询中的单词,验证指定的停用词('Ishmael')是否未出现
INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE
。
默认情况下,长度小于3个字符或长度大于84个字符的单词不会出现在
InnoDB
全文搜索索引中。
可以使用
innodb_ft_max_token_size
和
innodb_ft_min_token_size
变量
配置最大和最小字长值
。
此默认行为不适用于ngram解析器插件。
ngram标记大小由
ngram_token_size
选项
定义
。
mysql> SET GLOBAL innodb_ft_aux_table ='test / opening_lines'; 查询正常,0行受影响(0.00秒) mysql> SELECT word FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE LIMIT 15; + ----------- + | 字| + ----------- + | 跨越| | 所有| | 烧伤| | 买| | 打电话 | 来了| | dalloway | | 第一个| | 鲜花| | 发生了| | 她自己 | 看不见的 | 少了 | 爱| | 男人| + ----------- + 15行(0.00秒)
要逐个表创建停用词列表,请创建其他停用词表,并使用该
innodb_ft_user_stopword_table
选项指定在创建全文索引之前要使用的停用词表。
停止字文件被加载并使用搜索
latin1
,如果
character_set_server
是
ucs2
,
utf16
,
utf16le
,或
utf32
。
要覆盖MyISAM表的默认禁用词列表,请设置
ft_stopword_file
系统变量。
(请参见
第5.1.8节“服务器系统变量”
。)变量值应该是包含禁用词列表的文件的路径名,或者是用于禁用禁用词过滤的空字符串。
除非给出绝对路径名以指定其他目录,否则服务器将在数据目录中查找该文件。
更改此变量的值或停用词文件的内容后,重新启动服务器并重建
FULLTEXT
索引。
禁用词列表是自由格式的,将停用词与任何非字母数字字符(如换行符,空格或逗号)分隔开来。
例外是下划线字符(
_
)和单个撇号(
'
),它们被视为单词的一部分。
禁用词列表的字符集是服务器的默认字符集;
请参见
第10.3.2节“服务器字符集和排序规则”
。
以下列表显示了
MyISAM
搜索索引
的默认停用词
。
在MySQL源代码分发中,您可以在
storage/myisam/ft_static.c
文件中
找到此列表
。
一个能够达到以上的能力 之后事后实际上相应 再次反对并非全部允许 几乎已经允许了 虽然总是在其中 在一个和另一个中 无论如何任何人都有 无论如何,在任 适当的是不在身边 旁边问一下相关的问题 很可能成为了 因为变得变得过去了 之前在相信之前 除了最好的以外旁边 两者之间的短暂而且 通过c'mon c来了可以 不能不能导致原因 某些肯定会明显改变co 因此,com来了 考虑考虑包含含有 相应的可能当前不能 绝对描述尽管没有 不同的做不做 不要在期间完成 每个教育,例如八个 其他地方尤其如此 等等甚至每一个 每个人每个人到处都是 确切的例子,除了很少 第五个前五个跟随 以前是前者 进一步得到四个 得到给予放弃 走了就走了 问候几乎没有发生 已经没有了 因此,他是你的帮助 她此后来到这里 在这里,她自己嗨 希望他自己也好好相待 但是我怎么会这样 如果我被忽略了,我就是这样 确实很快就会出现这种情况 表明内部表示内部 相反,进入内心则不是 它就是它的全部 本身只是保持不变 知道最近才知道 后来后者至少少了 以免让我们喜欢 可能看起来很小看 有限公司可能很多 我的意思同时只是可能 更重要的是,大部分都是 我必须说出自己的名字 接近几乎必要的需要 不需要从来没有新的 接下来的九个没有人没有 没有人,通常也没有 现在没有什么新奇的了 经常哦好的 一次就好了 仅限于或其他 其他人应该是我们的 我们在外面整体而言 特别是每个人都有 大概请加上可能 可能提供que相当qv 相当合情合理 无论如何相对分别 右说同样的说法 说第二个说第二 看起来似乎看似似乎 看到自我明智的发送 认真严肃的七个应该 她应该不应该六岁 所以有些人不知何故有人 有时某种程度上某些地方 很抱歉指定指定 仍然是这样的肯定 采取倾向 感谢谢谢 这就是他们的 他们自己然后从那里开始 从那以后就有了 其中就有这些他们 他们是他们,他们是他们认为的 第三,彻底彻底那些 虽然三穿过整个过程 因此也在一起 朝向真正尝试的尝试 尝试两次尝试两次 不幸的是,除非不可能 在我们身上使用 通常使用有用的用途 价值各种非常通过即 vs想要的不是 我们的方式我们就是这样 我们很受欢迎 不是什么时候什么都没有 无论何时何地何地何地 而其中,无论何处何地 无论是谁,谁 谁是谁谁谁谁 为什么愿意和 在没有不会怀疑的情况下 不会是你还是你 你是你,你是你的 你自己零
分区表不支持全文搜索。 请参见 第23.6节“分区的限制和限制” 。
全文搜索可以与大多数多字节字符集一起使用。
例外情况是,对于Unicode,
utf8
可以使用字符集,但不能使用
ucs2
字符集。
虽然
无法使用列上的
FULLTEXT
索引
ucs2
,但您可以
IN BOOLEAN MODE
对
ucs2
没有此类索引
的
列
执行
搜索
。
该言论
utf8
也适用于
utf8mb4
,并为言论
ucs2
也适用于
utf16
,
utf16le
和
utf32
。
中文和日文等表意语言没有单词分隔符。 因此,内置全文本解析器 无法确定单词在这些语言和其他此类语言中的开始和结束位置 。
支持中文,日文和韩文(CJK)的基于字符的ngram全文解析器,以及支持日语的基于单词的MeCab解析器插件,用于
InnoDB
和
MyISAM
表
一起使用
。
虽然支持在单个表中使用多个字符集,但
FULLTEXT
索引中的
所有列都
必须使用相同的字符集和排序规则。
该
MATCH()
列列表必须完全在一些列的列表匹配
FULLTEXT
的表索引的定义,除非这
MATCH()
是
IN BOOLEAN MODE
一个
MyISAM
表。
对于
MyISAM
表,布尔模式搜索可以在非索引列上完成,尽管它们可能很慢。
参数
AGAINST()
必须是在查询评估期间保持不变的字符串值。
例如,这排除了表列,因为每行可能不同。
索引提示对于
FULLTEXT
搜索而言比对非
FULLTEXT
搜索
更有限
。
请参见
第8.9.4节“索引提示”
。
对于
InnoDB
所有DML操作(
INSERT
,
UPDATE
,
DELETE
)与全文索引以事务处理涉及列提交时间。
例如,对于
INSERT
操作,插入的字符串被标记化并分解成单个单词。
然后,在提交事务时,将单个单词添加到全文索引表中。
因此,全文搜索仅返回已提交的数据。
'%'字符不是全文搜索支持的通配符。
MySQL的全文搜索功能几乎没有用户可调参数。 如果您有MySQL源代码分发,则可以对全文搜索行为施加更多控制,因为某些更改需要修改源代码。 请参见 第2.9节“从源安装MySQL” 。
仔细调整全文搜索的有效性。 在大多数情况下修改默认行为实际上会降低有效性。 除非您知道自己在做什么,否则不要更改MySQL源代码 。
必须在服务器启动时设置本节中描述的大多数全文变量。 需要重新启动服务器才能更改它们; 它们在服务器运行时无法修改。
某些变量更改要求您重建
FULLTEXT
表中
的
索引。
有关这样做的说明将在本节后面给出。
要索引词的最小和最大长度由被定义
innodb_ft_min_token_size
和
innodb_ft_max_token_size
用于
InnoDB
搜索索引,以及
ft_min_word_len
与
ft_max_word_len
用于
MyISAM
人。
最小和最大字长全文参数不适用于
FULLTEXT
使用ngram解析器创建的索引。
ngram标记大小由
ngram_token_size
选项
定义
。
更改任何这些选项后,重建
FULLTEXT
索引以使更改生效。
例如,要使两个字符的单词可搜索,您可以将以下行放在选项文件中:
的[mysqld] innodb_ft_min_token_size = 2 的ft_min_word_len = 2
然后重新启动服务器并重建
FULLTEXT
索引。
对于
MyISAM
表格,请注意有关
重建
全文索引
的说明中
有关
myisamchk的
注释
MyISAM
。
对于
MyISAM
搜索索引,自然语言搜索的50%阈值由所选的特定加权方案确定。
要禁用它,请在以下位置查找以下行
storage/myisam/ftdefs.h
:
#define GWS_IN_USE GWS_PROB
将该行更改为:
#define GWS_IN_USE GWS_FREQ
然后重新编译MySQL。 在这种情况下,无需重建索引。
通过进行此更改,会
严重
降低MySQL为
MATCH()
函数
提供足够相关值的能力
。
如果你真的需要搜索这样的常用词,那么最好使用
IN
BOOLEAN MODE
相反的
搜索
,而不是观察50%的阈值。
要更改用于对
MyISAM
表
进行布尔全文搜索的运算符
,请设置
ft_boolean_syntax
系统变量。
(
InnoDB
没有等效设置。)可以在服务器运行时更改此变量,但必须具有足以设置全局系统变量的权限(请参见
第5.1.9.1节“系统变量权限”
)。
在这种情况下,不需要重建索引。
对于内置的全文本解析器,您可以通过多种方式更改被视为单词字符的字符集,如以下列表中所述。
进行修改后,重建包含任何
FULLTEXT
索引的
每个表的
索引。
假设您要将连字符(' - ')视为单词字符。
使用以下方法之一:
修改MySQL源:在
storage/innobase/handler/ha_innodb.cc
(for
InnoDB
)或in
storage/myisam/ftdefs.h
(for
MyISAM
)中,查看
true_word_char()
和
misc_word_char()
宏。
添加
'-'
到其中一个宏并重新编译MySQL。
修改字符集文件:这不需要重新编译。
的
true_word_char()
宏使用
“
字符类型
”
表来从其他字符区分字母和数字。
。
您可以
<ctype><map>
在其中一个字符集XML文件中
编辑
数组
的内容,
以指定它
'-'
是一个
“
字母”。
“
然后使用给定的
FULLTEXT
索引
字符集
。
有关
<ctype><map>
数组格式的信息,请参见
第10.12.1节“字符定义数组”
。
为索引列使用的字符集添加新的排序规则,并更改列以使用该排序规则。 有关添加排序 规则的 一般信息,请参见 第10.13节“将排序规则添加到字符集” 。 有关特定于全文索引的示例,请参见 第12.9.7节“为全文索引添加归类” 。
为使更改生效,
FULLTEXT
索引必须修改以下任何全文索引变量后重建:
innodb_ft_min_token_size
;
innodb_ft_max_token_size
;
innodb_ft_server_stopword_table
;
innodb_ft_user_stopword_table
;
innodb_ft_enable_stopword
;
ngram_token_size
。
修改
innodb_ft_min_token_size
,
innodb_ft_max_token_size
或
ngram_token_size
需要重新启动服务器。
要重建
FULLTEXT
索引的
InnoDB
表,使用
ALTER
TABLE
与
DROP INDEX
和
ADD INDEX
选项删除并重新创建每个索引。
OPTIMIZE TABLE
在具有全文索引的表上
运行会
重建全文索引,删除已删除的文档ID并在可能的情况下合并同一个单词的多个条目。
要优化全文索引,请启用
innodb_optimize_fulltext_only
并运行
OPTIMIZE TABLE
。
mysql> set GLOBAL innodb_optimize_fulltext_only = ON; 查询OK,0行受影响(0.01秒) mysql> OPTIMIZE TABLE opening_lines; + -------------------- + ---------- + ---------- + ------ ---- + | 表| Op | Msg_type | Msg_text | + -------------------- + ---------- + ---------- + ------ ---- + | test.opening_lines | 优化| 状态| 好的 + -------------------- + ---------- + ---------- + ------ ---- + 1排(0.01秒)
要避免大型表上的全文索引的冗长重建时间,可以使用该
innodb_ft_num_word_optimize
选项分阶段执行优化。
该
innodb_ft_num_word_optimize
选项定义每次
OPTIMIZE TABLE
运行时
优化的单词数
。
默认设置为2000,这意味着每次
OPTIMIZE
TABLE
运行
时
都会
优化2000个字
。
后续
OPTIMIZE TABLE
操作从前一
OPTIMIZE TABLE
操作结束的
地方继续
。
如果修改影响索引(
ft_min_word_len
,
ft_max_word_len
或
ft_stopword_file
)
的全文变量
,或者更改了停用词文件本身,则必须
FULLTEXT
在进行更改并重新启动服务器后
重建
索引。
要重建
表
的
FULLTEXT
索引,只需
MyISAM
执行
QUICK
修复操作即可:
MySQL的> REPAIR TABLE tbl_name
QUICK;
或者,如上所述使用
ALTER
TABLE
。
在某些情况下,这可能比修复操作更快。
FULLTEXT
必须修复
包含任何
索引的
每个表,
如刚才所示。
否则,对表的查询可能会产生不正确的结果,对表的修改将导致服务器将表视为损坏并需要修复。
如果使用
myisamchk
执行修改
MyISAM
表索引
的操作
(例如修复或分析),则
FULLTEXT
使用
默认
的全文参数值(最小字长,最大字长和停用词文件
)
重建索引
,除非您另行指定。
这可能导致查询失败。
出现此问题的原因是这些参数仅由服务器知道。
它们不存储在
MyISAM
索引文件中。
为了避免这个问题,如果你已经修改服务器所使用的最小或最大字长或停止字文件值,指定相同的
ft_min_word_len
,
ft_max_word_len
以及
ft_stopword_file
对价值观
myisamchk的
,你使用
的mysqld
。
例如,如果您将最小字长设置为3,则可以使用
myisamchk
修复表,
如下所示:
myisamchk --recover --ft_min_word_len = 3 tbl_name
.MYI
为了确保
myisamchk的
和服务器使用相同的值进行全文参数,将每一项都在
[mysqld]
和
[myisamchk]
选项文件的部分:
的[mysqld] 的ft_min_word_len = 3 [myisamchk的] 的ft_min_word_len = 3
到使用替代
myisamchk的
用于
MyISAM
表索引修改是使用
REPAIR
TABLE
,
ANALYZE TABLE
,
OPTIMIZE TABLE
,或
ALTER
TABLE
语句。
这些语句由服务器执行,服务器知道要使用的正确的全文参数值。
本节介绍如何使用内置全文本解析器为全文搜索添加新的排序规则。
样本排序规则类似,
latin1_swedish_ci
但将
'-'
字符视为字母而不是标点符号,以便将其编入索引为单词字符。
有关添加排序
规则的
一般信息,请参见
第10.13节“向字符集添加排序规则”
;
假设您已阅读并熟悉所涉及的文件。
要为全文索引添加排序规则,请使用以下过程。 此处的说明为简单字符集 添加了排序规则 ,如 第10.13节“向字符集添加排序规则”中所述 ,可以使用描述字符集属性的配置文件创建。 对于Unicode等复杂字符集,使用描述字符集属性的C源文件创建排序规则。
为
Index.xml
文件
添加排序规则
。
归类ID必须未使用,因此如果已在系统上使用该ID,请选择不同于1000的值。
<charset name =“latin1”> ... <collation name =“latin1_fulltext_ci”id =“1000”/> </字符集>
声明文件中排序规则的排序顺序
latin1.xml
。
在这种情况下,订单可以从
latin1_swedish_ci
以下位置
复制
:
<collation name =“latin1_fulltext_ci”> <地图> 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F 60 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56 57 58 59 5A 7B 7C 7D 7E 7F 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF 41 41 41 41 5C 5B 5C 43 45 45 45 45 49 49 49 49 44 4E 4F 4F 4F 4F 5D D7 D8 55 55 55 59 59 DE DF 41 41 41 41 5C 5B 5C 43 45 45 45 45 49 49 49 49 44 4E 4F 4F 4F 4F 5D F7 D8 55 55 55 59 59 DE FF </地图> </核对>
修改
ctype
数组
latin1.xml
。
将对应于0x2D(这是
'-'
字符
的代码
)的值从10(标点符号)更改为01(大写字母)。
在下面的数组中,这是第四行中的元素,第三行中的元素。
<CTYPE>
<地图>
00
20 20 20 20 20 20 20 20 20 28 28 28 28 28 20 20
20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
48 10 10 10 10 10 10 10 10 10 10 10 10 01
10 10
84 84 84 84 84 84 84 84 84 84 10 10 10 10 10 10
10 81 81 81 81 81 81 01 01 01 01 01 01 01 01 01 01
01 01 01 01 01 01 01 01 01 01 01 10 10 10 10 10
10 82 82 82 82 82 82 02 02 02 02 02 02 02 02 02
02 02 02 02 02 02 02 02 02 02 02 10 10 10 10 20
10 00 10 02 10 10 10 10 10 10 01 10 01 00 01 00
00 10 10 10 10 10 10 10 10 10 02 10 02 00 02 01
48 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01
01 01 01 01 01 01 01 10 01 01 01 01 01 01 01 02
02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02
02 02 02 02 02 02 02 10 02 02 02 02 02 02 02 02
</地图>
</ CTYPE>
重启服务器。
要使用新的排序规则,请将其包含在要使用它的列的定义中:
MySQL的>DROP TABLE IF EXISTS t1;
查询OK,0行受影响(0.13秒) MySQL的>CREATE TABLE t1 (
a TEXT CHARACTER SET latin1 COLLATE latin1_fulltext_ci,
FULLTEXT INDEX(a)
) ENGINE=InnoDB;
查询正常,0行受影响(0.47秒)
测试排序规则以验证连字符是否被视为单词字符:
MySQL的>INSERT INTO t1 VALUEs ('----'),('....'),('abcd');
查询OK,3行受影响(0.22秒) 记录:3个重复:0个警告:0 MySQL的>SELECT * FROM t1 WHERE MATCH a AGAINST ('----' IN BOOLEAN MODE);
+ ------ + | a | + ------ + | ---- | + ------ + 1排(0.00秒)
内置的MySQL全文解析器使用单词之间的空格作为分隔符来确定单词的开始和结束位置,这在使用不使用单词分隔符的表意语言时是一个限制。
为了解决这个限制,MySQL提供了一个支持中文,日文和韩文(CJK)的ngram全文解析器。
ngram全文解析器支持与
InnoDB
和
一起使用
MyISAM
。
MySQL还为日语提供了一个MeCab全文解析器插件,它将文档标记为有意义的单词。 有关更多信息,请参见 第12.9.9节“MeCab全文分析器插件” 。
ngram是
n
来自给定文本序列的
连续
字符序列。
ngram解析器将一系列文本标记为连续的
n
字符
序列
。
例如,您可以
使用ngram全文解析器将
“
abcd
”
标记
为不同的值
n
。
n = 1:'a','b','c','d' n = 2:'ab','bc','cd' n = 3:'abc','bcd' n = 4:'abcd'
ngram全文解析器是一个内置的服务器插件。 与其他内置服务器插件一样,它在服务器启动时自动加载。
第12.9节“全文搜索功能”中
描述的全文搜索语法
适用于ngram解析器插件。
本节将介绍解析行为的差异。
全文相关的配置选项,除了最小和最大字长选项(
innodb_ft_min_token_size
,
innodb_ft_max_token_size
,
ft_min_word_len
,
ft_max_word_len
)也适用。
ngram解析器的默认ngram标记大小为2(bigram)。 例如,如果令牌大小为2,则ngram解析器将字符串 “ abc def ” 解析 为四个令牌: “ ab ” , “ bc ” , “ de ” 和 “ ef ” 。
ngram标记大小可使用
ngram_token_size
配置选项
进行
配置,该选项的最小值为1,最大值为10。
通常,
ngram_token_size
设置为要搜索的最大标记的大小。
如果您只打算搜索单个字符,请设置
ngram_token_size
为1.较小的令牌大小会产生较小的全文搜索索引和较快的搜索。
如果您需要搜索由多个字符组成的单词,请相应地进行设置
ngram_token_size
。
例如
, “
生日快乐
”
是
“
生日快乐
”
简体中国,在
“
生日
”
是
“
生日
”
和
“
快乐
”
翻译为
“
快乐
”
。
要搜索这些双字符单词,请设置
ngram_token_size
为2或更高的值。
作为只读变量,
ngram_token_size
只能设置为启动字符串或配置文件的一部分:
启动字符串:
mysqld --ngram_token_size = 2
配置文件:
的[mysqld] ngram_token_size = 2
下面的最小和最大字长配置选项被忽略的
FULLTEXT
是使用NGRAM解析器指标:
innodb_ft_min_token_size
,
innodb_ft_max_token_size
,
ft_min_word_len
,和
ft_max_word_len
。
要创建
FULLTEXT
一个使用NGRAM解析器指数,指定
WITH PARSER ngram
用
CREATE
TABLE
,
ALTER
TABLE
或
CREATE
INDEX
。
以下示例演示如何使用
ngram
FULLTEXT
索引
创建表
,插入示例数据(简体中文文本)以及在
INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE
表中
查看标记化数据
。
mysql> USE测试; mysql> CREATE TABLE文章( id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, title VARCHAR(200), 主体, FULLTEXT(标题,正文)与PARSER ngram )ENGINE = InnoDB CHARACTER SET utf8mb4; mysql> SET NAMES utf8mb4; INSERT INTO文章(标题,正文)价值观 ( '数据库管理', '在本教程中我将向你展示如何管理数据库'), ( '数据库应用开发', '学习开发数据库应用程序'); mysql> SET GLOBAL innodb_ft_aux_table =“test / articles”; mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE ORDER BY doc_id,position;
要向
FULLTEXT
现有表
添加
索引,可以使用
ALTER
TABLE
或
CREATE
INDEX
。
例如:
CREATE TABLE文章( id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, title VARCHAR(200), 主体 )ENGINE = InnoDB CHARACTER SET utf8; ALTER TABLE文章ADD FULLTEXT INDEX ft_index(title,body)WITH PARSER ngram; # 要么: CREATE FULLTEXT INDEX ft_index ON PARSER ngram上的文章(标题,正文);
ngram解析器在解析时消除了空格。 例如:
“ ab cd ” 被解析为 “ ab ” , “ cd ”
“ a bc ” 被解析为 “ bc ”
内置的MySQL全文解析器将单词与禁用词列表中的条目进行比较。
如果单词等于禁用词列表中的条目,则该单词将从索引中排除。
对于ngram解析器,以不同方式执行停用词处理。
ngram解析器排除
包含
停用词的
令牌,而不是排除等同于禁用词列表中的条目的令牌
。
例如,假设
ngram_token_size=2
包含
“
a,b
”
的文档
被解析为
“
a
”
和
“
,b
”
。
如果逗号(
“
,
”
)被定义为停用词,则两者都是
“
a
”
和
“
,b
”
从索引中排除,因为它们包含逗号。
默认情况下,ngram解析器使用默认的停用词列表,其中包含英语停用词列表。 对于适用于中文,日文或韩文的禁用词列表,您必须创建自己的。 有关创建 禁用 词列表的信息,请参见 第12.9.4节“全文 停用词 ” 。
长度大于
ngram_token_size
被忽略的
停用词
。
对于
自然语言模式
搜索,搜索项将转换为ngram项的并集。
例如,字符串
“
abc
”
(假设
ngram_token_size=2
)被转换为
“
ab bc
”
。
给定两个文档,一个包含
“
ab
”
而另一个包含
“
abc
”
,搜索词
“
ab bc
”
匹配两个文档。
对于
布尔模式搜索
,搜索项将转换为ngram短语搜索。
例如,字符串'abc'(假设
ngram_token_size=2
)将转换为'
“
ab bc
”
'。
给定两个文档,一个包含'ab'而另一个包含'abc',搜索短语'
“
ab bc
”
'仅匹配包含'abc'的文档。
由于
FULLTEXT
ngram索引仅包含
ngrams
,并且不包含有关术语开头的信息,因此通配符搜索可能会返回意外结果。
以下行为适用于使用ngram
FULLTEXT
搜索索引的
通配符搜索
:
如果通配符搜索的前缀术语短于ngram令牌大小,则查询将返回包含以前缀术语开头的ngram令牌的所有索引行。
例如,假设
ngram_token_size=2
搜索
“
a *
”
将返回以
“
a
”
开头的所有行
。
如果通配符搜索的前缀术语长于ngram令牌大小,则前缀术语将转换为ngram短语,并忽略通配符运算符。
例如,假定
ngram_token_size=2
,一个
“
ABC
* ”
通配符搜索被转换为
“
AB BC
”
。
短语搜索转换为ngram短语搜索。 例如,搜索短语 “ abc ” 被转换为 “ ab bc ” ,其返回包含 “ abc ” 和 “ ab bc ”的 文档 。
搜索短语 “ abc def ” 被转换为 “ ab bc de ef ” ,其返回包含 “ abc def ” 和 “ ab bc de ef ”的 文档 。 不返回 包含 “ abcdef ”的 文档 。
内置的MySQL全文解析器使用单词之间的空格作为分隔符来确定单词的开始和结束位置,这在使用不使用单词分隔符的表意语言时是一个限制。
为了解决日语的这种限制,MySQL提供了一个MeCab全文解析器插件。
MeCab全文解析器插件支持与
InnoDB
和
一起使用
MyISAM
。
MySQL还提供了一个支持日语的ngram全文解析器插件。 有关更多信息,请参见 第12.9.8节“ngram全文分析器” 。
MeCab全文解析器插件是日语的全文解析器插件,可将一系列文本标记为有意义的单词。
例如,MeCab将
“
データベース管理
”
(
“
数据库管理
”
)
标记
为
“
データベース
”
(
“
数据库
”
)和
“
管理
”
(
“
管理
”
)。
相比之下,
ngram
全文解析器将文本标记为连续的
n
字符
序列
,其中
n
表示1到10之间的数字。
除了将文本标记为有意义的单词之外,MeCab索引通常小于ngram索引,并且MeCab全文搜索通常更快。 一个缺点是,与ngram全文解析器相比,MeCab全文本解析器可能需要更长的时间来标记文档。
第12.9节“全文搜索功能”中 描述的全文搜索语法 适用于MeCab解析器插件。 本节将介绍解析行为的差异。 全文相关的配置选项也适用。
有关MeCab解析器的其他信息,请参阅 Github上 的 MeCab:Yet Another Speech-of-Speech和Morphological Analyzer 项目。
MeCab解析器插件需要
mecab
和
mecab-ipadic
。
在受支持的Fedora,Debian和Ubuntu平台上(系统
mecab
版本太旧的
Ubuntu 12.04除外
),
mecab
如果安装到默认位置
,MySQL会动态链接到系统
安装。
在其他受支持的类Unix平台上,
libmecab.so
静态链接
libpluginmecab.so
,位于MySQL插件目录中。
mecab-ipadic
包含在MySQL二进制文件中,位于
。
MYSQL_HOME
\lib\mecab
您可以安装
mecab
和
mecab-ipadic
使用本机包管理实用程序(在Fedora,Debian和Ubuntu上),也可以
从源代码
构建
mecab
和
mecab-ipadic
使用。
有关安装
mecab
和
mecab-ipadic
使用本机程序包管理实用程序的信息,请参阅
从二进制分发安装MeCab(可选)
。
如果要构建
mecab
和
mecab-ipadic
从源
构建
,请参阅从源
构建MeCab(可选)
。
在Windows上,
libmecab.dll
可以在MySQL
bin
目录中
找到
。
mecab-ipadic
位于
。
MYSQL_HOME
/lib/mecab
要安装和配置MeCab解析器插件,请执行以下步骤:
在MySQL配置文件中,将
mecab_rc_file
配置选项
设置为配置文件
的位置,该
mecabrc
文件是MeCab的配置文件。
如果您使用的是随MySQL分发的MeCab软件包,则该
mecabrc
文件位于
MYSQL_HOME/lib/mecab/etc/
。
的[mysqld] 松mecabrc文件= MYSQL_HOME / LIB /仲裁处的/ etc / mecabrc
该
loose
前缀是一个
选项修改
。
在
mecab_rc_file
安装MeCaB解析器插件之前,MySQL无法识别
该
选项,但必须在尝试安装MeCaB解析器插件之前设置该选项。
该
loose
前缀允许你重启MySQL没有遇到错误的,由于无法识别的变量。
如果您使用自己的MeCab安装,或者从源构建MeCab,则
mecabrc
配置文件
的位置
可能会有所不同。
有关MySQL配置文件及其位置的信息,请参见 第4.2.2.2节“使用选项文件” 。
同样在MySQL配置文件中,将最小令牌大小设置为1或2,这是建议与MeCab解析器一起使用的值。
对于
InnoDB
表,最小令牌大小由
innodb_ft_min_token_size
配置选项
定义
,其默认值为3.对于
MyISAM
表,最小令牌大小由定义
ft_min_word_len
,其默认值为4。
的[mysqld] innodb_ft_min_token_size = 1
修改
mecabrc
配置文件以指定要使用的字典。
在
mecab-ipadic
与MySQL二进制分布包包括三个字典(
ipadic_euc-jp
,
ipadic_sjis
,和
ipadic_utf-8
)。
mecabrc
与MySQL一起打包
的
配置文件包含和输入类似于以下内容:
dicdir = / path / to / mysql / lib / mecab / lib / mecab / dic / ipadic_euc-jp
ipadic_utf-8
例如,
要使用
字典,请按如下所示修改条目:
dicdir = MYSQL_HOME
/ lib / mecab / dic / ipadic_utf-8
如果您使用自己的MeCab安装或从源代码构建了MeCab
dicdir
,则
mecabrc
文件中
的默认
条目
将不同,字典及其位置也将不同。
安装MeCab解析器插件后,您可以使用
mecab_charset
状态变量来查看与MeCab一起使用的字符集。
MySQL二进制文件提供的三个MeCab词典支持以下字符集。
该
ipadic_euc-jp
词典支持
ujis
和
eucjpms
字符集。
该
ipadic_sjis
词典支持
sjis
和
cp932
字符集。
该
ipadic_utf-8
词典支持
utf8
和
utf8mb4
字符集。
mecab_charset
仅报告第一个支持的字符集。
例如,
ipadic_utf-8
字典支持
utf8
和
utf8mb4
。
mecab_charset
始终报告
utf8
何时使用此词典。
重启MySQL。
安装MeCab解析器插件:
MeCab解析器插件使用
INSTALL PLUGIN
语法
安装
。
插件名称是
mecab
,共享库名称是
libpluginmecab.so
。
有关安装插件的其他信息,请参见
第5.6.1节“安装和卸载插件”
。
INSTALL PLUGIN mecab SONAME'libpluginmecab.so';
安装完成后,MeCab解析器插件会在每次正常的MySQL重启时加载。
验证是否使用该
SHOW PLUGINS
语句
加载了MeCab解析器插件
。
mysql> SHOW PLUGINS;
一个
mecab
插件应该出现在插件列表。
要创建
FULLTEXT
一个使用仲裁处解析器指数,指定
WITH PARSER ngram
用
CREATE
TABLE
,
ALTER
TABLE
或
CREATE
INDEX
。
此示例演示如何创建带有
mecab
FULLTEXT
索引
的表
,插入示例数据以及在
INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE
表中
查看标记化数据
:
mysql> USE测试; mysql> CREATE TABLE文章( id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, title VARCHAR(200), 主体, FULLTEXT(标题,正文)与PARSER mecab )ENGINE = InnoDB CHARACTER SET utf8; mysql> SET NAMES utf8; mysql> INSERT INTO文章(标题,正文)VALUES ( 'データベース管理', 'このチュートリアルでは,私はどのようにデータベースを管理する方法を绍介します'), ( 'データベースアプリケーション开発', 'データベースアプリケーションを开発することを学ぶ'); mysql> SET GLOBAL innodb_ft_aux_table =“test / articles”; mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE ORDER BY doc_id,position;
要向
FULLTEXT
现有表
添加
索引,可以使用
ALTER
TABLE
或
CREATE
INDEX
。
例如:
CREATE TABLE文章( id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, title VARCHAR(200), 主体 )ENGINE = InnoDB CHARACTER SET utf8; ALTER TABLE文章ADD FULLTEXT INDEX ft_index(标题,正文)WITH PARSER mecab; # 要么: CREATE FULLTEXT INDEX ft_index ON PARSER mecab上的文章(标题,正文);
MeCab解析器在查询字符串中使用空格作为分隔符。 例如,MeCab解析器将 データベース管理 标记 为 データベース 和 管理 。
默认情况下,MeCab解析器使用默认的停用词列表,其中包含一个简短的英语停用词列表。 对于适用于日语的禁用词列表,您必须创建自己的。 有关创建 禁用 词列表的信息,请参见 第12.9.4节“全文 停用词 ” 。
对于自然语言模式搜索,搜索项将转换为标记的并集。 例如, データベース管理 被转换为 データベース管理 。
SELECT COUNT(*)FROM articles WHERE MATCH(title,body)AGAINST('データベース管理'IN NATURAL LANGUAGE MODE);
对于布尔模式搜索,搜索词将转换为搜索词组。 例如, データベース管理 被转换为 データベース管理 。
SELECT COUNT(*)FROM articles WHERE MATCH(title,body)AGAINST('データベース管理'在BOOLEAN MODE中);
通配符搜索词不是标记化的。 搜索 データベース管理* 是在前缀 データベース管理上进行的 。
SELECT COUNT(*)FROM articles WHERE MATCH(title,body)AGAINST('データベース*'在BOOLEAN MODE中);
短语被标记化。 例如, データベース管理 被标记为 データベース管理 。
SELECT COUNT(*)FROM articles WHERE MATCH(title,body)AGAINST('データベース管理''在BOOLEAN MODE中);
本节介绍如何
使用本机程序包管理实用程序
安装
mecab
和
mecab-ipadic
使用二进制分发。
例如,在Fedora上,您可以使用Yum来执行安装:
yum mecab-devel
在Debian或Ubuntu上,您可以执行APT安装:
apt-get install mecab apt-get install mecab-ipadic
如果你想建立
mecab
和
mecab-ipadic
从源代码,下面提供了基本安装步骤。
有关其他信息,请参阅MeCab文档。
下载的tar.gz包
mecab
,并
mecab-ipadic
从
http://taku910.github.io/mecab/#download
。
截至2016年2月,最新的套餐是
mecab-0.996.tar.gz
和
mecab-ipadic-2.7.0-20070801.tar.gz
。
安装
mecab
:
tar zxfv mecab-0.996.tar cd mecab-0.996 。/配置 使 做检查 苏 make install
安装
mecab-ipadic
:
tar zxfv mecab-ipadic-2.7.0-20070801.tar cd mecab-ipadic-2.7.0-20070801 。/配置 使 苏 make install
使用
WITH_MECAB
CMake选项
编译MySQL
。
如果已安装
,
则将
WITH_MECAB
选项
设置为
默认位置。
system
mecab
mecab-ipadic
-DWITH_MECAB =系统
如果定义了自定义安装目录,请设置
WITH_MECAB
为自定义目录。
例如:
-DWITH_MECAB = /路径/到/仲裁处
转换函数和运算符可以将值从一种数据类型转换为另一种数据类型。
CONVERT()
with
USING
子句提供了一种在不同字符集之间转换数据的方法:
转换(expr
使用transcoding_name
)
在MySQL中,转码名称与相应的字符集名称相同。
例子:
SELECT CONVERT(_latin1'Müller'使用utf8); INSERT INTO utf8_table(utf8_column) SELECT CONVERT(latin1_column USING utf8)FROM latin1_table;
您也可以
CONVERT()
不
使用
USING
或
CAST()
在不同字符集之间转换字符串:
CONVERT(string
,CHAR [(N
)] CHARACTER SETcharset_name
) CAST(string
AS CHAR [(N
)] CHARACTER SETcharset_name
)
例子:
SELECT CONVERT('test',CHAR CHARACTER SET utf8); SELECT CAST('test'AS CHAR CHARACTER SET utf8);
如果指定
刚刚显示,则生成的字符集和排序规则是
默认排序规则
。
如果省略
,结果字符集和校对规则由定义
和
决定默认的连接字符集和校对系统变量(参见
第10.4节,“连接字符集和校对”
)。
CHARACTER SET
charset_name
charset_name
charset_name
CHARACTER SET
charset_name
character_set_connection
collation_connection
COLLATE
a
CONVERT()
或
CAST()
call中
不允许
使用
子句
,但可以将其应用于函数结果。
例如,这是合法的:
SELECT CAST('test'AS CHAR CHARACTER SET utf8)COLLATE utf8_bin;
但这是非法的:
SELECT CAST('test'AS CHAR CHARACTER SET utf8 COLLATE utf8_bin);
通常,您不能以不
BLOB
区分大小写的方式
比较
值或其他二进制字符串,因为二进制字符串使用的
binary
字符集
与
字母集的概念没有排序。
要执行不区分大小写的比较,请使用
CONVERT()
或
CAST()
函数将值转换为非二进制字符串。
比较结果字符串使用其排序规则。
例如,如果转换结果字符集具有不区分大小写的排序规则,则
LIKE
操作不区分大小写:
SELECT'A' LIKE CONVERT(blob_col
使用latin1) 来自tbl_name
;
要使用其他字符集,请
latin1
在前面的语句中
替换其名称
。
要为转换后的字符串指定特定排序规则,请
COLLATE
在
CONVERT()
调用后
使用
子句
:
选择'A'LIKE CONVERT(blob_col
使用latin1)COLLATE latin1_german1_ci 来自tbl_name
;
CONVERT()
并且
CAST()
可以更普遍地用于比较以不同字符集表示的字符串。
例如,这些字符串的比较会导致错误,因为它们具有不同的字符集:
mysql>SET @s1 = _latin1 'abc', @s2 = _latin2 'abc';
mysql>SELECT @s1 = @s2;
ERROR 1267(HY000):非法混合排序(latin1_swedish_ci,IMPLICIT) 和(latin2_general_ci,IMPLICIT)用于操作'='
将其中一个字符串转换为与另一个字符集兼容的字符集可以使比较无错误地发生:
MySQL的> SELECT @s1 = CONVERT(@s2 USING latin1);
+ --------------------------------- +
| @ s1 = CONVERT(@ s2使用latin1)|
+ --------------------------------- +
| 1 |
+ --------------------------------- +
为字符串常量,另一种方式来指定字符集是使用字符集导引器(
_latin1
和
_latin2
前面的例子中是导引器的实例)。
与转换函数(例如
CAST()
,或
CONVERT()
将字符串从一个字符集转换为另一个字符集)不同,介绍人将字符串文字指定为具有特定字符集,不涉及转换。
有关更多信息,请参见
第10.3.8节“字符集介绍”
。
字符集转换在二进制字符串的字母转换之前也很有用。
LOWER()
而
UPPER()
当直接应用到二进制字符串,因为大小写的概念不适是无效的。
要执行二进制字符串的字母转换,首先将其转换为非二进制字符串:
mysql>SET @str = BINARY 'New York';
mysql>SELECT LOWER(@str), LOWER(CONVERT(@str USING utf8mb4));
+ ------------- + ----------------------------------- - + | LOWER(@str)| LOWER(CONVERT(@str使用utf8mb4))| + ------------- + ----------------------------------- - + | 纽约| 纽约| + ------------- + ----------------------------------- - +
如果使用
BINARY
,
CAST()
或
转换索引列
CONVERT()
,则MySQL可能无法有效地使用索引。
转换函数对于在
CREATE
TABLE ...
SELECT
语句中
创建具有特定类型的列非常有用
:
mysql>CREATE TABLE new_table SELECT CAST('2000-01-01' AS DATE) AS c1;
mysql>SHOW CREATE TABLE new_table\G
*************************** 1。排******************** ******* 表:new_table 创建表:CREATE TABLE`new_table`( `c1`日期DEFAULT NULL )ENGINE = InnoDB DEFAULT CHARSET = utf8mb4
强制转换函数可用于按
ENUM
词汇顺序
对
列
进行排序
。
通常,
ENUM
使用内部数值
对
列进行
排序
。
将值转换
CHAR
为词汇排序的结果:
选择enum_col
来自tbl_name
CAST的订单(enum_col
作为CHAR);
CAST()
如果您将其用作更复杂表达式的一部分,也会更改结果,例如
CONCAT('Date: ',CAST(NOW() AS
DATE))
。
对于时间值,几乎不需要使用
CAST()
以不同格式提取数据。
相反,使用功能,例如
EXTRACT()
,
DATE_FORMAT()
或
TIME_FORMAT()
。
请参见
第12.7节“日期和时间函数”
。
要将字符串转换为数字,除了在数字上下文中使用字符串值之外,通常只需要执行任何操作:
MySQL的> SELECT 1+'1';
- > 2
对于十六进制和位文字也是如此,默认情况下是二进制字符串:
MySQL的>SELECT X'41', X'41'+0;
- >'A',65 MySQL的>SELECT b'1100001', b'1100001'+0;
- >'a',97
算术运算中使用的字符串在表达式求值期间转换为浮点数。
字符串上下文中使用的数字将转换为字符串:
MySQL的> SELECT CONCAT('hello you ',2);
- >'你好2'
有关将数字隐式转换为字符串的信息,请参见 第12.2节“表达式 求值中的 类型转换” 。
MySQL支持带有符号和无符号64位值的算术。
对于
其中一个操作数是无符号整数的
数字运算符(例如
+
或
-
),默认情况下结果是无符号的(参见
第12.6.1节“算术运算符”
)。
要覆盖它,请使用
SIGNED
or
UNSIGNED
cast运算符分别将值转换为有符号或无符号的64位整数。
MySQL的>SELECT 1 - 2;
- > -1 MySQL的>SELECT CAST(1 - 2 AS UNSIGNED);
- > 18446744073709551615 MySQL的>SELECT CAST(CAST(1 - 2 AS UNSIGNED) AS SIGNED);
- > -1
如果任一操作数是浮点值,则结果为浮点值,并且不受前述规则的影响。
(在此上下文中,
DECIMAL
列值被视为浮点值。)
MySQL的> SELECT CAST(1 AS UNSIGNED) - 2.0;
- > -1.0
SQL模式会影响转换操作的结果(请参见 第5.1.11节“服务器SQL模式” )。 例子:
用于将
“
零
”
日期字符串转换为日期,
CONVERT()
并
在
启用SQL模式
时
CAST()
返回
NULL
并生成警告
NO_ZERO_DATE
。
对于整数减法,如果
NO_UNSIGNED_SUBTRACTION
启用
了
SQL模式,即使任何操作数未签名,也会对减法结果进行签名。
以下列表描述了可用的强制转换函数和运算符:
BINARY
expr
的
BINARY
操作者将所表达为二进制字符串。
一种常见的用法
BINARY
是强制字符串比较逐字节而不是逐字符地完成,实际上变为区分大小写。
该
BINARY
运营商还导致比较尾随空格是显著。
MySQL的>SELECT 'a' = 'A';
- > 1 MySQL的>SELECT BINARY 'a' = 'A';
- > 0 MySQL的>SELECT 'a' = 'a ';
- > 1 MySQL的>SELECT BINARY 'a' = 'a ';
- > 0
相比之下,
BINARY
影响整个操作;
它可以在任一操作数之前给出,但结果相同。
为了将字符串表达式转换为二进制字符串,这些结构是等效的:
二元expr
铸造(expr
作为二进制) CONVERT(expr
使用二进制)
如果值是字符串文字,则可以将其指定为二进制字符串,而不使用
_binary
字符集介绍器
执行任何转换
:
MySQL的>SELECT 'a' = 'A';
- > 1 MySQL的>SELECT _binary 'a' = 'A';
- > 0
有关介绍人的信息,请参见 第10.3.8节“字符集介绍人” 。
BINARY
表达式中
的
运算符与
BINARY
字符列定义中
的
属性的
效果不同
。
使用该
BINARY
属性
定义的字符列将
分配表默认字符集和该字符集的binary(
_bin
)排序规则。
每个非二进制字符集都有一个
_bin
排序规则。
例如,
utf8
字符集
的二进制排序规则
是
utf8_bin
,因此如果表默认字符集是
utf8
,则这两个列定义是等效的:
CHAR(10)二进制 CHAR(10)CHARACTER SET utf8 COLLATE utf8_bin
使用
CHARACTER SET binary
中的定义
CHAR
,
VARCHAR
或
TEXT
柱导致列与相应的二进制字符串的数据类型进行处理。
例如,以下两对定义是等效的:
CHAR(10)CHARACTER SET二进制 BINARY(10) VARCHAR(10)CHARACTER SET二进制 VARBINARY(10) TEXT CHARACTER SET二进制 BLOB
该
CAST()
函数接受任何类型的表达式并生成指定类型的结果值,类似于
CONVERT()
。
有关更多信息,请参阅的说明
CONVERT()
。
CAST()
是标准的SQL语法。
CONVERT(
,
expr
,type
)CONVERT(
expr
USING transcoding_name
)
该
CONVERT()
函数采用任何类型的表达式并生成指定类型的结果值。
这里
对
语法的
讨论
也适用于
,这是等价的。
CONVERT(
expr
,
type
)CAST(
expr
AS
type
)
CONVERT(... USING ...)
是标准的SQL语法。
ODBC
USING
形式的
非
形式
CONVERT()
。
CONVERT()
用
USING
不同的字符集之间转换数据。
在MySQL中,转码名称与相应的字符集名称相同。
例如,此语句将
'abc'
默认字符集中
的字符串转换为
字符集中的相应字符串
utf8
:
SELECT CONVERT('abc'使用utf8);
CONVERT()
不带
USING
并
CAST()
使用表达式和
type
指定结果类型
的
值。
type
允许
这些
值:
BINARY[(
N
)]
生成具有
BINARY
数据类型
的字符串
。
有关
如何影响比较的说明,
请参见
第11.4.2节“BINARY和VARBINARY类型”
。
如果
N
给出
了可选长度
,则
会使强制转换使用不超过
参数的字节。
短于
字节的
值
用
字节
填充
到长度为
。
BINARY(
N
)N
N
0x00
N
CHAR[(
N
)]
[charset_info
]
生成具有
CHAR
数据类型
的字符串
。
如果
N
给出
了可选长度
,则
会使强制转换使用不超过
参数的字符。
对于短于
字符的
值,不会出现填充
。
CHAR(
N
)N
N
如果没有
charset_info
子句,则
CHAR
生成具有默认字符集的字符串。
要明确指定字符集,
charset_info
允许使用
以下
值:
CHARACTER SET
:生成具有给定字符集的字符串。
charset_name
ASCII
:简写
CHARACTER SET latin1
。
UNICODE
:简写
CHARACTER SET ucs2
。
在所有情况下,字符串都具有字符集的默认排序规则。
DATE
产生
DATE
价值。
DATETIME
产生
DATETIME
价值。
DECIMAL[(
M
[,D
])]
产生
DECIMAL
价值。
如果给出了可选
值
M
和
D
值,则它们指定最大位数(精度)和小数点后面的位数(刻度)。
DOUBLE
产生
DOUBLE
结果。
在MySQL 8.0.17中添加。
FLOAT [(
P
)]
如果
P
未指定
precision
,则生成类型的结果
FLOAT
。
如果
P
提供并且0 <= <<
P
= 24,则结果为类型
FLOAT
。
如果25 <=
P
<= 53,则结果为类型
REAL
。
如果
P
<0或
P
> 53,则返回错误。
在MySQL 8.0.17中添加。
JSON
产生
JSON
价值。
有关在
JSON
其他类型
之间转换值的规则的详细信息
,请参阅
JSON值的比较和排序
。
NCHAR[(
N
)]
喜欢
CHAR
,但会产生一个带有国家字符集的字符串。
请参见
第10.3.7节“国家字符集”
。
与之
不同
CHAR
,
NCHAR
不允许指定尾随字符集信息。
REAL
生成类型的结果
REAL
。
这实际上是
FLOAT
,如果
REAL_AS_FLOAT
启用了SQL模式;
否则结果是类型
DOUBLE
。
SIGNED [INTEGER]
生成有符号整数值。
TIME
产生
TIME
价值。
UNSIGNED [INTEGER]
生成无符号整数值。
本节讨论MySQL中的XML和相关功能。
通过使用该
选项
调用它们,
可以
在
mysql
和
mysqldump
客户端中
从MySQL获取XML格式的输出
--xml
。
请参见
第4.5.1节“
mysql
- MySQL命令行客户端”
和
第4.5.4节“
mysqldump
- 数据库备份程序”
。
提供了两个提供基本XPath 1.0(XML路径语言,版本1.0)功能的函数。 本节稍后将提供有关XPath语法和用法的一些基本信息; 但是,对这些主题的深入讨论超出了本手册的范围,您应该参考 XML Path Language(XPath)1.0标准 来获取确切的信息。 对于那些 刚接触XPath 或希望了解基础知识的人来说,一个有用的资源是 Zvon.org XPath教程 ,它有多种语言版本。
这些功能仍处于开发阶段。 我们将继续改进MySQL 8.0及更高版本中XML和XPath功能的这些和其他方面。 您可以在 MySQL XML用户论坛中 讨论这些内容,询问有关它们的问题,并从中获得其他用户的帮助 。
与这些函数一起使用的XPath表达式支持用户变量和本地存储的程序变量。 用户变量检查不足; 强烈检查存储程序本地的变量(另见Bug#26518):
用户变量(弱检查)。
不检查
使用语法的变量
(即用户变量)。
如果变量类型错误或之前未分配值,则服务器不会发出警告或错误。
这也意味着用户对任何印刷错误负全部责任,因为如果(例如)
在
预期的
地方使用,
则
不会发出警告
。
$@
variable_name
$@myvariable
$@myvariable
例:
MySQL的>SET @xml = '<a><b>X</b><b>Y</b></a>';
查询正常,0行受影响(0.00秒) MySQL的>SET @i =1, @j = 2;
查询正常,0行受影响(0.00秒) MySQL的>SELECT @i, ExtractValue(@xml, '//b[$@i]');
+ ------ + -------------------------------- + | @i | ExtractValue(@xml,'// b [$ @ i]')| + ------ + -------------------------------- + | 1 | X | + ------ + -------------------------------- + 1排(0.00秒) MySQL的>SELECT @j, ExtractValue(@xml, '//b[$@j]');
+ ------ + -------------------------------- + | @j | ExtractValue(@xml,'// b [$ @ j]')| + ------ + -------------------------------- + | 2 | Y | + ------ + -------------------------------- + 1排(0.00秒) MySQL的>SELECT @k, ExtractValue(@xml, '//b[$@k]');
+ ------ + -------------------------------- + | @k | ExtractValue(@xml,'// b [$ @ k]')| + ------ + -------------------------------- + | NULL | | + ------ + -------------------------------- + 1排(0.00秒)
存储程序中的变量(强检查)。
使用语法的变量
可以在存储程序中调用时声明并与这些函数一起使用。
这些变量对于定义它们的存储程序是本地的,并且强烈检查类型和值。
$
variable_name
例:
MySQL的>DELIMITER |
mysql>CREATE PROCEDURE myproc ()
- >BEGIN
- >DECLARE i INT DEFAULT 1;
- >DECLARE xml VARCHAR(25) DEFAULT '<a>X</a><a>Y</a><a>Z</a>';
- > - >WHILE i < 4 DO
- >SELECT xml, i, ExtractValue(xml, '//a[$i]');
- >SET i = i+1;
- >END WHILE;
- >END |
查询OK,0行受影响(0.01秒) MySQL的>DELIMITER ;
MySQL的>CALL myproc();
+ -------------------------- + --- + ------------------ ------------ + | xml | 我| ExtractValue(xml,'// a [$ i]')| + -------------------------- + --- + ------------------ ------------ + | <a> X </a> <a> Y </a> <a> Z </a> | 1 | X | + -------------------------- + --- + ------------------ ------------ + 1排(0.00秒) + -------------------------- + --- + ------------------ ------------ + | xml | 我| ExtractValue(xml,'// a [$ i]')| + -------------------------- + --- + ------------------ ------------ + | <a> X </a> <a> Y </a> <a> Z </a> | 2 | Y | + -------------------------- + --- + ------------------ ------------ + 1排(0.01秒) + -------------------------- + --- + ------------------ ------------ + | xml | 我| ExtractValue(xml,'// a [$ i]')| + -------------------------- + --- + ------------------ ------------ + | <a> X </a> <a> Y </a> <a> Z </a> | 3 | Z | + -------------------------- + --- + ------------------ ------------ + 1排(0.01秒)
参数。 在作为参数传入的存储例程中的XPath表达式中使用的变量也需要进行强检查。
包含用户变量或存储程序本地变量的表达式必须另外(符号除外)符合包含XPath 1.0规范中给出的变量的XPath表达式的规则。
用于存储XPath表达式的用户变量被视为空字符串。 因此,无法将XPath表达式存储为用户变量。 (Bug#32911)
ExtractValue(
xml_frag
,
xpath_expr
)
ExtractValue()
接受两个字符串参数,一个XML标记片段
xml_frag
和一个XPath表达式
xpath_expr
(也称为
定位器
);
它返回
CDATA
第一个文本节点
的text(
),该节点是XPath表达式匹配的元素的子元素。
使用此功能相当于使用
xpath_expr
后添加
执行匹配
/text()
。
换句话说,
ExtractValue('<a><b>Sakila</b></a>',
'/a/b')
并
ExtractValue('<a><b>Sakila</b></a>',
'/a/b/text()')
产生相同的结果。
如果找到多个匹配,则返回每个匹配元素的第一个子文本节点的内容(按照匹配的顺序)作为单个空格分隔的字符串。
如果没有为表达式找到匹配的文本节点(包括隐式
/text()
) - 无论
出于
何种原因,只要
xpath_expr
有效,并且
xml_frag
由正确嵌套和关闭的元素组成 - 返回空字符串。
没有区分空元素的匹配和根本没有匹配。
这是设计的。
如果您需要确定是否未找到匹配元素
xml_frag
或
找到
此类元素但未包含子文本节点,则应测试使用XPath
count()
函数
的表达式的结果
。
例如,这两个语句都返回一个空字符串,如下所示:
MySQL的>SELECT ExtractValue('<a><b/></a>', '/a/b');
+ ------------------------------- + | ExtractValue('<a> <b /> </a>','/ a / b')| + ------------------------------- + | | + ------------------------------- + 1排(0.00秒) MySQL的>SELECT ExtractValue('<a><c/></a>', '/a/b');
+ ------------------------------- + | ExtractValue('<a> <c /> </a>','/ a / b')| + ------------------------------- + | | + ------------------------------- + 1排(0.00秒)
但是,您可以使用以下内容确定是否确实存在匹配元素:
MySQL的>SELECT ExtractValue('<a><b/></a>', 'count(/a/b)');
+ ------------------------------- + | ExtractValue('<a> <b /> </a>','count(/ a / b)')| + ------------------------------- + | 1 | + ------------------------------- + 1排(0.00秒) MySQL的>SELECT ExtractValue('<a><c/></a>', 'count(/a/b)');
+ ------------------------------- + | ExtractValue('<a> <c /> </a>','count(/ a / b)')| + ------------------------------- + | 0 | + ------------------------------- + 1排(0.01秒)
ExtractValue()
仅返回
CDATA
,并且不返回可能包含在匹配标记内的任何标记,也不返回任何内容(请参阅
val1
以下示例中
返回的结果
)。
mysql>SELECT
- >ExtractValue('<a>ccc<b>ddd</b></a>', '/a') AS val1,
- >ExtractValue('<a>ccc<b>ddd</b></a>', '/a/b') AS val2,
- >ExtractValue('<a>ccc<b>ddd</b></a>', '//b') AS val3,
- >ExtractValue('<a>ccc<b>ddd</b></a>', '/b') AS val4,
- >ExtractValue('<a>ccc<b>ddd</b><b>eee</b></a>', '//b') AS val5;
+ ------ + ------ + ------ + ------ + --------- + | val1 | val2 | val3 | val4 | val5 | + ------ + ------ + ------ + ------ + --------- + | ccc | ddd | ddd | | ddd eee | + ------ + ------ + ------ + ------ + --------- +
此函数使用当前的SQL排序规则进行比较
contains()
,执行与其他字符串函数(例如
CONCAT()
)
相同的排序规则聚合
,同时考虑其参数的排序规则的强制性;
有关此行为的规则的说明,
请参见
第10.8.4节“表达式中的校对强制性”
。
(以前,二进制 - 即始终使用区分大小写的比较。)
NULL
如果
xml_frag
包含未正确嵌套或关闭的元素,则会
返回
,并生成警告,如下例所示:
MySQL的>SELECT ExtractValue('<a>c</a><b', '//a');
+ ----------------------------------- + | ExtractValue('<a> c </a> <b','// a')| + ----------------------------------- + | NULL | + ----------------------------------- + 1排,1警告(0.00秒) MySQL的>SHOW WARNINGS\G
*************************** 1。排******************** ******* 等级:警告 代码:1525 消息:XML值不正确:'第1行pos 11处的解析错误: END-OF-INPUT意外('>'想要'' 1排(0.00秒) MySQL的>SELECT ExtractValue('<a>c</a><b/>', '//a');
+ ------------------------------- + | ExtractValue('<a> c </a> <b />','// a')| + ------------------------------- + | c | + ------------------------------- + 1排(0.00秒)
UpdateXML(
xml_target
,
xpath_expr
,
new_xml
)
此函数将XML标记的给定片段的单个部分替换为
xml_target
新的XML片段
new_xml
,然后返回更改的XML。
xml_target
替换
的部分
与
xpath_expr
用户提供
的XPath表达式匹配
。
如果未
xpath_expr
找到
表达式匹配
,或者找到多个匹配项,则该函数返回原始
xml_target
XML片段。
所有三个参数都应该是字符串。
mysql>SELECT
- >UpdateXML('<a><b>ccc</b><d></d></a>', '/a', '<e>fff</e>') AS val1,
- >UpdateXML('<a><b>ccc</b><d></d></a>', '/b', '<e>fff</e>') AS val2,
- >UpdateXML('<a><b>ccc</b><d></d></a>', '//b', '<e>fff</e>') AS val3,
- >UpdateXML('<a><b>ccc</b><d></d></a>', '/a/d', '<e>fff</e>') AS val4,
- >UpdateXML('<a><d></d><b>ccc</b><d></d></a>', '/a/d', '<e>fff</e>') AS val5
- >\G
*************************** 1。排******************** ******* val1:<e> fff </ e> val2:<a> <b> ccc </ b> <d> </ d> </a> val3:<a> <e> fff </ e> <d> </ d> </a> val4:<a> <b> ccc </ b> <e> fff </ e> </a> val5:<a> <d> </ d> <b> ccc </ b> <d> </ d> </a>
深入讨论XPath语法和用法超出了本手册的范围。 有关确切信息, 请参阅 XML Path Language(XPath)1.0规范 。 对于那些 刚接触XPath 或希望重新学习基础知识的人来说,一个有用的资源是 Zvon.org XPath教程 ,该 教程 有多种语言版本。
一些基本XPath表达式的描述和示例如下:
/
tag
匹配
if和仅
匹配
根元素。
<
tag
/><
tag
/>
示例:
/a
匹配,
<a><b/></a>
因为它匹配最外层(根)标记。
它与内部
a
元素
不匹配
,
<b><a/></b>
因为在这个实例中它是另一个元素的子元素。
/
tag1
/tag2
当且仅当它是子
元素
时才
匹配
,并且
是根元素。
<
tag2
/><
tag1
/><
tag1
/>
示例:
/a/b
匹配
b
XML片段
中的
元素,
<a><b/></a>
因为它是根元素的子元素
a
。
它没有匹配,
<b><a/></b>
因为在这种情况下,
b
是根元素(因此没有其他元素的子元素)。
XPath表达式也没有匹配
<a><c><b/></c></a>
;
在这里,
b
是一个后代
a
,但实际上并不是一个孩子
a
。
该构造可扩展到三个或更多个元素。
例如,XPath表达式
/a/b/c
匹配
c
片段
中的
元素
<a><b><c/></b></a>
。
//
tag
匹配任何实例
。
<
tag
>
示例:
//a
匹配
a
以下任何一项
中的
元素:
<a><b><c/></b></a>
;
<c><a><b/></a></b>
;
<c><b><a/></b></c>
。
//
可以结合使用
/
。
例如,
//a/b
匹配
b
任一片段
中的
元素
<a><b/></a>
或
<c><a><b/></a></c>
。
//
相当于
。
一个常见的错误是将此与此混淆
,尽管后一种表达式实际上可能导致非常不同的结果,如下所示:
tag
/descendant-or-self::*/
tag
/descendant-or-self::
tag
MySQL的>SET @xml = '<a><b><c>w</c><b>x</b><d>y</d>z</b></a>';
查询正常,0行受影响(0.00秒) MySQL的>SELECT @xml;
+ ----------------------------------------- + | @xml | + ----------------------------------------- + | <a> <b> <c> w </ c> <b> x </ b> <d> y </ d> z </ b> </a> | + ----------------------------------------- + 1排(0.00秒) MySQL的>SELECT ExtractValue(@xml, '//b[1]');
+ ------------------------------ + | ExtractValue(@xml,'// b [1]')| + ------------------------------ + | xz | + ------------------------------ + 1排(0.00秒) MySQL的>SELECT ExtractValue(@xml, '//b[2]');
+ ------------------------------ + | ExtractValue(@xml,'// b [2]')| + ------------------------------ + | | + ------------------------------ + 1排(0.01秒) MySQL的>SELECT ExtractValue(@xml, '/descendant-or-self::*/b[1]');
+ ------------------------------------------------- - + | ExtractValue(@xml,'/ descendant-or-self :: * / b [1]')| + ------------------------------------------------- - + | xz | + ------------------------------------------------- - + 1排(0.06秒) MySQL的>SELECT ExtractValue(@xml, '/descendant-or-self::*/b[2]');
+ ------------------------------------------------- - + | ExtractValue(@xml,'/ descendant-or-self :: * / b [2]')| + ------------------------------------------------- - + | | + ------------------------------------------------- - + 1排(0.00秒) MySQL的>SELECT ExtractValue(@xml, '/descendant-or-self::b[1]');
+ ------------------------------------------------- + | ExtractValue(@xml,'/ descendant-or-self :: b [1]')| + ------------------------------------------------- + | z | + ------------------------------------------------- + 1排(0.00秒) MySQL的>SELECT ExtractValue(@xml, '/descendant-or-self::b[2]');
+ ------------------------------------------------- + | ExtractValue(@xml,'/ descendant-or-self :: b [2]')| + ------------------------------------------------- + | x | + ------------------------------------------------- + 1排(0.00秒)
的
*
操作者充当
“
通配符
”
的任何元素相匹配。
例如,表达式
/*/b
匹配
b
任一XML片段
中的
元素
<a><b/></a>
或
<c><b/></c>
。
但是,表达式不会在片段中产生匹配,
<b><a/></b>
因为它
b
必须是某个其他元素的子元素。
通配符可以在任何位置使用:表达式
/*/b/*
将匹配
b
本身不是根元素
的
元素的
任何子
元素。
您可以使用
|
(
UNION
)运算符
匹配任何几个定位器
。
例如,表达式
//b|//c
匹配
XML目标
中的所有
元素
b
和
c
元素。
还可以基于其一个或多个属性的值来匹配元素。
这是使用语法完成的
。
例如,表达式
匹配
片段
中的第二个
元素
。
要匹配
任何
元素
,请使用XPath表达式
。
tag
[@attribute
="value
"]//b[@id="idB"]
b
<a><b id="idA"/><c/><b
id="idB"/></a>
attribute
="value
"//*[
attribute
="value
"]
要过滤多个属性值,只需连续使用多个属性比较子句。
例如,表达式
//b[@c="x"][@d="y"]
匹配
<b c="x" d="y"/>
给定XML片段中任何位置出现
的元素
。
要查找相同属性与多个值中的任何一个匹配的元素,可以使用
|
运算
符连接的多个定位
符。
例如,要匹配
b
其
c
属性具有值23或17的
所有
元素
,请使用表达式
//b[@c="23"]|//b[@c="17"]
。
您也可以使用逻辑
or
运算符来实现此目的:
//b[@c="23" or @c="17"]
。
or
和/
之间的区别
|
是
or
连接条件,同时
|
连接结果集。
XPath限制。 这些函数支持的XPath语法目前受到以下限制:
'/a/b[@c=@d]'
不支持
节点集到节点集的比较(例如
)。
支持所有标准XPath比较运算符。 (缺陷号22823)
相对定位符表达式在根节点的上下文中解析。 例如,请考虑以下查询和结果:
mysql>SELECT ExtractValue(
- >'<a><b c="1">X</b><b c="2">Y</b></a>',
- >'a/b'
- >) AS result;
+ -------- + | 结果| + -------- + | XY | + -------- + 1排(0.03秒)
在这种情况下,定位器
a/b
解析为
/a/b
。
谓词中也支持相对定位器。
在以下示例中,
d[../@c="1"]
解析为
/a/b[@c="1"]/d
:
mysql>SELECT ExtractValue(
- >'<a>
- ><b c="1"><d>X</d></b>
- ><b c="2"><d>X</d></b>
- ></a>',
- >'a/b/d[../@c="1"]')
- >AS result;
+ -------- + | 结果| + -------- + | X | + -------- + 1排(0.00秒)
不允许使用以表达式为前缀的定位符作为标量值(包括变量引用,文字,数字和标量函数调用),并且它们的使用会导致错误。
::
不支持
将
运算符与节点类型结合使用,例如:
axis
::comment()
axis
::text()
axis
::processing-instructions()
axis
::node()
但是,支持名称测试(例如
和
),如以下示例所示:
axis
::name
axis
::*
MySQL的>SELECT ExtractValue('<a><b>x</b><c>y</c></a>','/a/child::b');
+ ------------------------------------------------- ------ + | ExtractValue('<a> <b> x </ b> <c> y </ c> </a>','/ a / child :: b')| + ------------------------------------------------- ------ + | x | + ------------------------------------------------- ------ + 1排(0.02秒) MySQL的>SELECT ExtractValue('<a><b>x</b><c>y</c></a>','/a/child::*');
+ ------------------------------------------------- ------ + | ExtractValue('<a> <b> x </ b> <c> y </ c> </a>','/ a / child :: *')| + ------------------------------------------------- ------ + | xy | + ------------------------------------------------- ------ + 1排(0.01秒)
“ 向上和向下 ” 导航是不是在情况下,路径会导致支持 “ 上面 ” 的根元素。 也就是说,您不能使用与给定元素的祖先的后代匹配的表达式,其中当前元素的一个或多个祖先也是根元素的祖先(参见Bug#16321)。
不支持以下XPath函数,或者已指出已知问题:
id()
lang()
local-name()
name()
namespace-uri()
normalize-space()
starts-with()
string()
substring-after()
substring-before()
translate()
不支持以下轴:
following-sibling
following
preceding-sibling
preceding
XPath表达式作为参数传递,
ExtractValue()
并且
UpdateXML()
可能
:
在元素选择器中
包含冒号字符(
),这使得它们可以使用带有XML命名空间符号的标记。
例如:
MySQL的>SET @xml = '<a>111<b:c>222<d>333</d><e:f>444</e:f></b:c></a>';
查询正常,0行受影响(0.00秒) MySQL的>SELECT ExtractValue(@xml, '//e:f');
+ ----------------------------- + | ExtractValue(@xml,'// e:f')| + ----------------------------- + | 444 | + ----------------------------- + 1排(0.00秒) MySQL的>SELECT UpdateXML(@xml, '//b:c', '<g:h>555</g:h>');
+ -------------------------------------------- + | UpdateXML(@xml,'// b:c','<g:h> 555 </ g:h>')| + -------------------------------------------- + | <a> 111 <g:h> 555 </ g:h> </a> | + -------------------------------------------- + 1排(0.00秒)
这在某些方面类似于
Apache Xalan
和其他一些解析器
所允许的
,并且比要求命名空间声明或使用
namespace-uri()
和
local-name()
函数
要简单得多
。
错误处理。
对于这两个
ExtractValue()
和
UpdateXML()
,使用的XPath定位器必须有效和要搜索的XML必须由被正确地嵌套和关闭元件。
如果定位器无效,则会生成错误:
mysql> ERROR 1105(HY000):XPATH语法错误:'&a'SELECT ExtractValue('<a>c</a><b/>', '/&a');
如果
xml_frag
不包含正确嵌套和关闭的元素,
NULL
则返回并生成警告,如下例所示:
MySQL的>SELECT ExtractValue('<a>c</a><b', '//a');
+ ----------------------------------- + | ExtractValue('<a> c </a> <b','// a')| + ----------------------------------- + | NULL | + ----------------------------------- + 1排,1警告(0.00秒) MySQL的>SHOW WARNINGS\G
*************************** 1。排******************** ******* 等级:警告 代码:1525 消息:XML值不正确:'第1行pos 11处的解析错误: END-OF-INPUT意外('>'想要'' 1排(0.00秒) MySQL的>SELECT ExtractValue('<a>c</a><b/>', '//a');
+ ------------------------------- + | ExtractValue('<a> c </a> <b />','// a')| + ------------------------------- + | c | + ------------------------------- + 1排(0.00秒)
用作第三个参数替换XML到
UpdateXML()
被
不
检查,以确定是否它仅由被正确地嵌套和关闭元件。
XPath注入。 当恶意代码被引入系统以获得对特权和数据的未授权访问时,就会发生 代码注入 。 它基于利用开发人员对用户输入数据的类型和内容所做的假设。 XPath在这方面也不例外。
可能发生这种情况的常见情况是应用程序通过将登录名和密码的组合与XML文件中的组合进行匹配来处理授权,使用类似这样的XPath表达式:
// user [login / text()='neapolitan'和password / text()='1c3cr34m'] / attribute :: id
这是与此类似的SQL语句的XPath:
SELECT id FROM users WHERE login ='neapolitan'AND password''1c3cr34m';
使用XPath的PHP应用程序可能会像这样处理登录过程:
<?PHP $ file =“users.xml”; $ login = $ POST [“login”]; $ password = $ POST [“password”]; $ xpath =“// user [login / text()= $ login and password / text()= $ password] / attribute :: id”; if(file_exists($ file)) { $ xml = simplexml_load_file($ file); if($ result = $ xml-> xpath($ xpath)) echo“您现在以用户$ result [0]身份登录。”; 其他 echo“登录名或密码无效。”; } 其他 退出(“无法打开$ file。”); ?>
不对输入执行检查。
这意味着恶意用户可以
通过输入
登录名和密码
来
“
短路
”
测试
' or 1=1
,从而得到
$xpath
如下所示的评估:
// user [login / text()=''或1 = 1和password / text()=''或1 = 1] / attribute :: id
由于方括号内的表达式始终求值为
true
,因此它实际上与此对应,它与
XML文档
id
中每个
user
元素
的
属性
相匹配
:
//用户/属性:: ID
可以绕过这种特定攻击的一种方法是简单地引用要在插值中插入的变量名
$xpath
,强制将从Web表单传递的值转换为字符串:
$ xpath =“// user [login / text()='$ login'和password / text()='$ password'] / attribute :: id”;
这与通常建议用于防止SQL注入攻击的策略相同。 通常,您应该遵循的用于防止XPath注入攻击的实践与防止SQL注入相同:
从未接受过应用程序中用户的未经测试的数据。
检查所有用户提交的数据类型; 拒绝或转换错误类型的数据
测试超出范围值的数值数据; 截断,舍入或拒绝超出范围的值。 测试非法字符的字符串,并将其删除或拒绝包含它们的输入。
请勿输出可能为未经授权的用户提供可用于危害系统的线索的显式错误消息; 请将这些记录到文件或数据库表中。
正如SQL注入攻击可用于获取有关数据库模式的信息一样,XPath注入也可用于遍历XML文件以揭示其结构,如Amit Klein的论文 Blind XPath Injection (PDF文件,46KB)中所述。
检查发送回客户端的输出也很重要。
考虑一下当我们使用MySQL
ExtractValue()
函数
时会发生什么
:
mysql>SELECT ExtractValue(
- >LOAD_FILE('users.xml'),
- >'//user[login/text()="" or 1=1 and password/text()="" or 1=1]/attribute::id'
- >) AS id;
+ ------------------------------- + | id | + ------------------------------- + | 00327 13579 02403 42354 28570 | + ------------------------------- + 1排(0.01秒)
因为
ExtractValue()
将多个匹配作为单个空格分隔的字符串返回,所以此注入攻击将包含在
users.xml
用户
内的每个有效ID
作为单行输出提供。
作为额外的安全措施,您还应该在将输出返回给用户之前对其进行测试。
这是一个简单的例子:
mysql>SELECT @id = ExtractValue(
- >LOAD_FILE('users.xml'),
- >'//user[login/text()="" or 1=1 and password/text()="" or 1=1]/attribute::id'
- >);
查询正常,0行受影响(0.00秒) mysql>SELECT IF(
- >INSTR(@id, ' ') = 0,
- >@id,
- >'Unable to retrieve user ID')
- >AS singleID;
+ ---------------------------- + | singleID | + ---------------------------- + | 无法检索用户ID | + ---------------------------- + 1排(0.00秒)
通常,安全地向用户返回数据的准则与接受用户输入的准则相同。 这些可以概括为:
始终测试输出数据的类型和允许值。
永远不允许未经授权的用户查看可能提供有关可能用于利用它的应用程序的信息的错误消息。
位的函数和操作包括
BIT_COUNT()
,
BIT_AND()
,
BIT_OR()
,
BIT_XOR()
,
&
,
|
,
^
,
~
,
<<
,和
>>
。
(该
BIT_AND()
,
BIT_OR()
和
BIT_XOR()
聚集函数描述在
第12.20.1,“集合(GROUP BY)函数描述”
。)在此之前的MySQL 8.0,所需的比特的函数和操作
BIGINT
(64位整数)的参数和返回的
BIGINT
值,因此他们有最大范围为64位。
非
BIGINT
参数
BIGINT
在执行操作之前
被转换为
可能发生截断。
在MySQL 8.0中,位函数和运算符允许二进制字符串类型参数(
BINARY
,
VARBINARY
和
BLOB
类型)并返回类似的值,这使它们能够获取参数并生成大于64位的返回值。
非二进制字符串参数将
BIGINT
像以前一样
转换为
并进行处理。
这种行为改变的含义是二进制字符串参数的位操作可能在MySQL 8.0中产生与5.7中不同的结果。 有关如何准备在MySQL 5.7为MySQL 5.7和8.0之间的潜在的不兼容信息,请参见 位函数和操作符 ,在 MySQL的5.7参考手册 。
MySQL 8.0之前的位操作只处理无符号的64位整数参数和结果值(即无符号
BIGINT
值)。
BIGINT
必要时
转换其他类型的参数
。
例子:
此语句对数字文字进行操作,视为无符号64位整数:
MySQL的> SELECT 127 | 128, 128 << 2, BIT_COUNT(15);
+ ----------- + ---------- + --------------- +
| 127 | 128 | 128 << 2 | BIT_COUNT(15)|
+ ----------- + ---------- + --------------- +
| 255 | 512 | 4 |
+ ----------- + ---------- + --------------- +
在执行与第一个语句相同的操作并生成相同的结果之前,
此语句对字符串参数(
'127'
to
127
,等等)
执行to-number转换
:
MySQL的> SELECT '127' | '128', '128' << 2, BIT_COUNT('15');
+ --------------- + ------------ + ----------------- +
| '127'| '128'| '128'<< 2 | BIT_COUNT('15')|
+ --------------- + ------------ + ----------------- +
| 255 | 512 | 4 |
+ --------------- + ------------ + ----------------- +
此语句将十六进制文字用于位操作参数。 默认情况下,MySQL将十六进制文字视为二进制字符串,但在数字上下文中将它们计算为数字(请参见 第9.1.4节“十六进制文字” )。 在MySQL 8.0之前,数字上下文包括位操作。 例子:
MySQL的> SELECT X'7F' | X'80', X'80' << 2, BIT_COUNT(X'0F');
+ --------------- + ------------ + ------------------ +
| X'7F'| X'80'| X'80'<< 2 | BIT_COUNT(X'0F')|
+ --------------- + ------------ + ------------------ +
| 255 | 512 | 4 |
+ --------------- + ------------ + ------------------ +
位操作中位值文字的处理类似于十六进制文字(即数字)。
MySQL 8.0扩展位操作以直接处理二进制字符串参数(无需转换)并生成二进制字符串结果。 (非整数或二进制字符串的参数仍然像以前一样转换为整数。)此扩展通过以下方式增强位操作:
在长于64位的值上可以进行位操作。
对更自然地表示为二进制字符串而不是整数的值执行位操作更容易。
例如,考虑UUID值和IPv6地址,它们具有如下所示的人类可读文本格式:
UUID:6ccd780c-baba-1026-9564-5b8c656024db IPv6:fe80 :: 219:d1ff:fe91:1a72
以这些格式操作文本字符串是很麻烦的。
另一种方法是将它们转换为没有分隔符的固定长度的二进制字符串。
UUID_TO_BIN()
并且
INET6_ATON()
每个产生一个数据类型的值
BINARY(16)
,一个16字节(128位)长的二进制字符串。
以下语句说明了这一点(
HEX()
用于生成可显示的值):
MySQL的>SELECT HEX(UUID_TO_BIN('6ccd780c-baba-1026-9564-5b8c656024db'));
+ ------------------------------------------------- --------- + | HEX(UUID_TO_BIN('6ccd780c-baba-1026-9564-5b8c656024db'))| + ------------------------------------------------- --------- + | 6CCD780CBABA102695645B8C656024DB | + ------------------------------------------------- --------- + MySQL的>SELECT HEX(INET6_ATON('fe80::219:d1ff:fe91:1a72'));
+ --------------------------------------------- + | HEX(INET6_ATON('fe80 :: 219:d1ff:fe91:1a72'))| + --------------------------------------------- + | FE800000000000000219D1FFFE911A72 | + --------------------------------------------- +
这些二进制值可以通过位操作轻松操作,以执行诸如从UUID值中提取时间戳或提取IPv6地址的网络和主机部分等操作。 (例如,请参阅本讨论的后面部分。)
该计为二进制字符串参数包括列值,例程参数,局部变量和用户定义的变量具有一个二进制串类型:
BINARY
,
VARBINARY
,或的一个
BLOB
类型。
那么十六进制文字和位文字呢? 回想一下,默认情况下这些是MySQL中的二进制字符串,但是数字上下文中的数字。 它们如何处理MySQL 8.0中的位操作? MySQL是否继续在数字上下文中评估它们,就像MySQL 8.0之前一样? 或做位操作评估它们作为二进制字符串,现在二进制字符串可以办理 “ 本地 ” ,无需转换?
答:通常使用十六进制文字或位文字指定位操作的参数,意图表示数字,因此当所有位参数都是十六进制或位文字时,MySQL继续在数值上下文中评估位操作,以实现向后兼容性。
如果您需要将评估作为二进制字符串,那么很容易实现:使用
_binary
至少一个文字
的
介绍人。
这些位操作将十六进制文字和位文字计算为整数:
MySQL的> SELECT X'40' | X'01', b'11110001' & b'01001111';
+ --------------- + --------------------------- +
| X'40'| X'01'| b'11110001'&b'01001111'|
+ --------------- + --------------------------- +
| 65 | 65 |
+ --------------- + --------------------------- +
由于
_binary
介绍人的
原因,这些位操作将十六进制文字和位文字评估为二进制字符串
:
MySQL的> SELECT _binary X'40' | X'01', b'11110001' & _binary b'01001111';
+ ----------------------- + ------------------------- ---------- +
| _binary X'40'| X'01'| b'11110001'&_binary b'01001111'|
+ ----------------------- + ------------------------- ---------- +
| A | A |
+ ----------------------- + ------------------------- ---------- +
尽管两个语句中的位操作产生的数值为65,但第二个语句在二进制字符串上下文中运行,其中65为ASCII
A
。
在数值计算上下文中,十六进制文字和位文字参数的允许值最多为64位,结果也是如此。 相反,在二进制字符串评估上下文中,允许的参数(和结果)可以超过64位:
MySQL的> SELECT _binary X'4040404040404040' | X'0102030405060708';
+ ------------------------------------------------- - +
| _binary X'4040404040404040'| X'0102030405060708'|
+ ------------------------------------------------- - +
| ABCDEFGH |
+ ------------------------------------------------- - +
有几种方法可以在位操作中引用十六进制文字或位文字来引起二进制字符串评估:
_binaryliteral
BINARYliteral
CAST(literal
作为二进制)
生成十六进制文字或位文字的二进制字符串评估的另一种方法是将它们分配给用户定义的变量,这会导致变量具有二进制字符串类型:
mysql>SET @v1 = X'40', @v2 = X'01', @v3 = b'11110001', @v4 = b'01001111';
mysql>SELECT @v1 | @v2, @v3 & @v4;
+ ----------- ----------- + + | @ v1 | @ v2 | @ v3&@ v4 | + ----------- ----------- + + | A | A | + ----------- ----------- + +
在二进制字符串上下文中,按位操作参数必须具有相同的长度或发生
ER_INVALID_BITWISE_OPERANDS_SIZE
错误:
MySQL的> SELECT _binary X'40' | X'0001';
ERROR 3513(HY000):按位的二进制操作数
运营商必须具有相同的长度
要满足等长要求,请使用前导零位填充较短的值,或者如果较长的值以前导零位开头并且可接受较短的结果值,请将它们剥离:
MySQL的>SELECT _binary X'0040' | X'0001';
+ --------------------------- + | _binary X'0040'| X'0001'| + --------------------------- + | A | + --------------------------- + MySQL的>SELECT _binary X'40' | X'01';
+ ----------------------- + | _binary X'40'| X'01'| + ----------------------- + | A | + ----------------------- +
填充或汽提也可以使用的功能,例如来实现
LPAD()
,
RPAD()
,
SUBSTR()
,或
CAST()
。
在这种情况下,表达式参数不再是所有文字而
_binary
变得不必要。
例子:
MySQL的>SELECT LPAD(X'40', 2, X'00') | X'0001';
+ --------------------------------- + | LPAD(X'40',2,X'00')| X'0001'| + --------------------------------- + | A | + --------------------------------- + MySQL的>SELECT X'40' | SUBSTR(X'0001', 2, 1);
+ ------------------------------- + | X'40'| SUBSTR(X'0001',2,1)| + ------------------------------- + | A | + ------------------------------- +
以下示例说明如何使用位操作来提取UUID值的一部分,在本例中为时间戳和IEEE 802节点号。 该技术需要每个提取部分的位掩码。
将文本UUID转换为相应的16字节二进制值,以便可以使用二进制字符串上下文中的位操作来操作它:
mysql>SET @uuid = UUID_TO_BIN('6ccd780c-baba-1026-9564-5b8c656024db');
mysql>SELECT HEX(@uuid);
+ ---------------------------------- + | HEX(@uuid)| + ---------------------------------- + | 6CCD780CBABA102695645B8C656024DB | + ---------------------------------- +
构造值的时间戳和节点号部分的位掩码。 时间戳包括前三个部分(64位,位0到63),节点号是最后一部分(48位,位80到127):
mysql>SET @ts_mask = CAST(X'FFFFFFFFFFFFFFFF' AS BINARY(16));
mysql>SET @node_mask = CAST(X'FFFFFFFFFFFF' AS BINARY(16)) >> 80;
mysql>SELECT HEX(@ts_mask);
+ ---------------------------------- + | HEX(@ts_mask)| + ---------------------------------- + | FFFFFFFFFFFFFFFF0000000000000000 | + ---------------------------------- + MySQL的>SELECT HEX(@node_mask);
+ ---------------------------------- + | HEX(@node_mask)| + ---------------------------------- + | 00000000000000000000FFFFFFFFFFFF | + ---------------------------------- +
该
CAST(... AS BINARY(16))
功能用在这里,因为掩模必须是相同的长度作为对它们所施加的UUID值。
使用其他函数将掩码填充到所需长度可以产生相同的结果:
SET @ ts_mask = RPAD(X'FFFFFFFFFFFFFFFF',16,X'00'); SET @node_mask = LPAD(X'FFFFFFFFFFFF',16,X'00');
使用掩码来提取时间戳和节点号部分:
MySQL的>SELECT HEX(@uuid & @ts_mask) AS 'timestamp part';
+ ---------------------------------- + | 时间戳部分| + ---------------------------------- + | 6CCD780CBABA10260000000000000000 | + ---------------------------------- + MySQL的>SELECT HEX(@uuid & @node_mask) AS 'node part';
+ ---------------------------------- + | 节点部分| + ---------------------------------- + | 000000000000000000005B8C656024DB | + ---------------------------------- +
前面的示例使用这些位操作:right shift(
>>
)和按位AND(
&
)。
UUID_TO_BIN()
获取一个标志,导致在生成的二进制UUID值中进行一些位重新排列。
如果使用该标志,请相应地修改提取掩码。
下一个示例使用位操作来提取IPv6地址的网络和主机部分。 假设网络部分的长度为80位。 然后主机部分的长度为128-80 = 48位。 要提取地址的网络和主机部分,将其转换为二进制字符串,然后在二进制字符串上下文中使用位操作。
将文本IPv6地址转换为相应的二进制字符串:
MySQL的> SET @ip = INET6_ATON('fe80::219:d1ff:fe91:1a72');
以位为单位定义网络长度:
MySQL的> SET @net_len = 80;
通过向左或向右移动全1地址来构造网络和主机掩码。
要做到这一点,请从地址开始
::
,这是所有零的简写,正如您可以通过将其转换为二进制字符串所示:
MySQL的> SELECT HEX(INET6_ATON('::')) AS 'all zeros';
+ ---------------------------------- +
| 全零|
+ ---------------------------------- +
| 00000000000000000000000000000000 |
+ ---------------------------------- +
要生成互补值(全1),请使用
~
运算符反转位:
MySQL的> SELECT HEX(~INET6_ATON('::')) AS 'all ones';
+ ---------------------------------- +
| 所有的|
+ ---------------------------------- +
| FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF |
+ ---------------------------------- +
向左或向右移动全1值以生成网络和主机掩码:
mysql>SET @net_mask = ~INET6_ATON('::') << (128 - @net_len);
mysql>SET @host_mask = ~INET6_ATON('::') >> @net_len;
显示掩码以验证它们是否覆盖了地址的正确部分:
MySQL的>SELECT INET6_NTOA(@net_mask) AS 'network mask';
+ ---------------------------- + | 网络掩码| + ---------------------------- + | ffff:ffff:ffff:ffff:ffff :: | + ---------------------------- + MySQL的>SELECT INET6_NTOA(@host_mask) AS 'host mask';
+ ------------------------ + | 主机面具| + ------------------------ + | :: ffff:255.255.255.255 | + ------------------------ +
提取并显示地址的网络和主机部分:
mysql>SET @net_part = @ip & @net_mask;
mysql>SET @host_part = @ip & @host_mask;
mysql>SELECT INET6_NTOA(@net_part) AS 'network part';
+ ----------------- + | 网络部分| + ----------------- + | fe80 :: 219:0:0:0 | + ----------------- + MySQL的>SELECT INET6_NTOA(@host_part) AS 'host part';
+ ------------------ + | 主持人部分| + ------------------ + | :: d1ff:fe91:1a72 | + ------------------ +
前面的示例使用这些位操作:Complement(
~
),left shift(
<<
)和按位AND(
&
)。
其余的讨论提供了有关每组位操作的参数处理的详细信息,有关位操作中字面值处理的更多信息,以及MySQL 8.0和旧MySQL版本之间潜在的不兼容性。
对于
&
,
|
和
^
位操作,结果类型取决于参数是作为二进制字符串还是数字计算:
当参数具有二进制字符串类型时,会发生二进制字符串评估,并且其中至少有一个不是十六进制文字,位字面值或
NULL
文字。
否则进行数值计算,必要时将参数转换为无符号64位整数。
二进制字符串求值会生成与参数长度相同的二进制字符串。
如果参数长度不等,
ER_INVALID_BITWISE_OPERANDS_SIZE
则会发生错误。
数值计算生成无符号的64位整数。
数值评估的例子:
MySQL的> SELECT 64 | 1, X'40' | X'01';
+ -------- + -------- +
| 64 | 1 | X'40'| X'01'|
+ -------- + -------- +
| 65 | 65 |
+ -------- + -------- +
二进制字符串评估的示例:
MySQL的>SELECT _binary X'40' | X'01';
+ ----------------------- + | _binary X'40'| X'01'| + ----------------------- + | A | + ----------------------- + mysql>SET @var1 = X'40', @var2 = X'01';
mysql>SELECT @var1 | @var2;
+ --------------- + | @ var1 | @ var2 | + --------------- + | A | + --------------- +
对于
~
,
<<
和
>>
位操作,结果类型取决于bit参数是否被计算为二进制字符串或数字:
当bit参数具有二进制字符串类型且不是十六进制文字,位字面值或
NULL
文字
时,会发生二进制字符串评估
。
否则进行数值计算,必要时将参数转换为无符号的64位整数。
二进制字符串评估生成与bit参数长度相同的二进制字符串。 数值计算生成无符号的64位整数。
对于移位操作,无论参数类型如何,在值结束时移位的位都会在没有警告的情况下丢失。 特别是,如果移位计数大于或等于位参数中的位数,则结果中的所有位都为0。
数值评估的例子:
MySQL的> SELECT ~0, 64 << 2, X'40' << 2;
+ ---------------------- + --------- + ------------ +
| 〜0 | 64 << 2 | X'40'<< 2 |
+ ---------------------- + --------- + ------------ +
| 18446744073709551615 | 256 | 256 |
+ ---------------------- + --------- + ------------ +
二进制字符串评估的示例:
MySQL的>SELECT HEX(_binary X'1111000022220000' >> 16);
+ ---------------------------------------- + | HEX(_binary X'1111000022220000'>> 16)| + ---------------------------------------- + | 0000111100002222 | + ---------------------------------------- + MySQL的>SELECT HEX(_binary X'1111000022220000' << 16);
+ ---------------------------------------- + | HEX(_binary X'1111000022220000'<< 16)| + ---------------------------------------- + | 0000222200000000 | + ---------------------------------------- + mysql>SET @var1 = X'F0F0F0F0';
mysql>SELECT HEX(~@var1);
+ ------------- + | HEX(〜@ var1)| + ------------- + | 0F0F0F0F | + ------------- +
该
BIT_COUNT()
函数始终返回无符号的64位整数,或者
NULL
如果参数为
NULL
。
MySQL的>SELECT BIT_COUNT(127);
+ ---------------- + | BIT_COUNT(127)| + ---------------- + | 7 | + ---------------- + MySQL的>SELECT BIT_COUNT(b'010101'), BIT_COUNT(_binary b'010101');
+ ---------------------- + -------------------------- ---- + | BIT_COUNT(b'010101')| BIT_COUNT(_binary b'010101')| + ---------------------- + -------------------------- ---- + | 3 | 3 | + ---------------------- + -------------------------- ---- +
对于
BIT_AND()
,
BIT_OR()
和
BIT_XOR()
位的功能,结果类型取决于该函数的参数值是否被评价为二进制字符串或数字:
当参数值具有二进制字符串类型且参数不是十六进制文字,位字面值或
NULL
文字
时,会发生二进制字符串评估
。
否则进行数值计算,必要时将参数值转换为无符号64位整数。
二进制字符串评估生成与参数值长度相同的二进制字符串。
如果参数值具有不相等的长度,
ER_INVALID_BITWISE_OPERANDS_SIZE
则会发生错误。
如果参数大小超过511个字节,
ER_INVALID_BITWISE_AGGREGATE_OPERANDS_SIZE
则会发生错误。
数值计算生成无符号的64位整数。
NULL
除非所有值都是,否则值不会影响结果
NULL
。
在这种情况下,结果是一个中性值,其长度与参数值的长度相同(所有位1表示
BIT_AND()
,所有位0表示
BIT_OR()
,和
BIT_XOR()
)。
例:
mysql>CREATE TABLE t (group_id INT, a VARBINARY(6));
mysql>INSERT INTO t VALUES (1, NULL);
mysql>INSERT INTO t VALUES (1, NULL);
mysql>INSERT INTO t VALUES (2, NULL);
mysql>INSERT INTO t VALUES (2, X'1234');
mysql>INSERT INTO t VALUES (2, X'FF34');
mysql>SELECT HEX(BIT_AND(a)), HEX(BIT_OR(a)), HEX(BIT_XOR(a))
FROM t GROUP BY group_id;
+ ----------------- + ---------------- -------------- + --- + | HEX(BIT_AND(a))| HEX(BIT_OR(a))| HEX(BIT_XOR(a))| + ----------------- + ---------------- -------------- + --- + | FFFFFFFFFFFF | 000000000000 | 000000000000 | | 1234 | FF34 | ED00 | + ----------------- + ---------------- -------------- + --- +
为了向后兼容,当所有位参数都是十六进制文字,位文字或
NULL
文字
时,MySQL 8.0会在数值上下文中评估位操作
。
也就是说,如果所有位参数都是非简化的十六进制文字,位文字或
NULL
文字
,则对二进制字符串位参数的位操作不使用二进制字符串求值
。
(如果这些文字是使用
_binary
介绍人,
BINARY
操作符或其他明确指定为二进制字符串的方式
编写的,则不适用于此类文字
。)
刚刚描述的文字处理与MySQL 8.0之前的处理相同。 例子:
这些位操作在数值上下文中计算文字并生成
BIGINT
结果:
b'0001'| b'0010' X'0008'<< 8
这些位操作
NULL
在数值上下文中计算并生成
BIGINT
具有
NULL
值
的
结果
:
NULL和NULL NULL >> 4
在MySQL 8.0中,您可以通过明确指示至少一个参数是二进制字符串,使这些操作评估二进制字符串上下文中的参数:
_binary b'0001'| b'0010' _binary X'0008'<< 8 BINARY NULL&NULL BINARY NULL >> 4
最后两个表达式的结果
NULL
与没有
BINARY
运算符一样,但结果的数据类型是二进制字符串类型而不是整数类型。
因为位操作可以在MySQL 8.0中本地处理二进制字符串参数,所以某些表达式在MySQL 8.0中产生的结果与在5.7中不同。 需要注意的五个有问题的表达类型是:
nonliteral_binary
{&| ^} {&| ^} {<< >>} 〜()binary
binary
nonliteral_binary
nonliteral_binary
anything
nonliteral_binary
AGGR_BIT_FUNC
nonliteral_binary
这些表达式
BIGINT
在MySQL 5.7中
返回
,在8.0中
返回
二进制字符串。
符号说明:
有关如何准备在MySQL 5.7为MySQL 5.7和8.0之间的潜在的不兼容信息,请参见 位函数和操作符 ,在 MySQL的5.7参考手册 。
以下列表描述了可用的位功能和运算符:
按位OR。
结果类型取决于参数是作为二进制字符串还是数字计算:
当参数具有二进制字符串类型时,会发生二进制字符串评估,并且其中至少有一个不是十六进制文字,位字面值或
NULL
文字。
否则进行数值计算,必要时将参数转换为无符号64位整数。
二进制字符串求值会生成与参数长度相同的二进制字符串。
如果参数长度不等,
ER_INVALID_BITWISE_OPERANDS_SIZE
则会发生错误。
数值计算生成无符号的64位整数。
有关更多信息,请参阅本节中的介绍性讨论。
MySQL的>SELECT 29 | 15;
- > 31 MySQL的>SELECT _binary X'40404040' | X'01020304';
- >'ABCD'
按位AND。
结果类型取决于参数是作为二进制字符串还是数字计算:
当参数具有二进制字符串类型时,会发生二进制字符串评估,并且其中至少有一个不是十六进制文字,位字面值或
NULL
文字。
否则进行数值计算,必要时将参数转换为无符号64位整数。
二进制字符串求值会生成与参数长度相同的二进制字符串。
如果参数长度不等,
ER_INVALID_BITWISE_OPERANDS_SIZE
则会发生错误。
数值计算生成无符号的64位整数。
有关更多信息,请参阅本节中的介绍性讨论。
MySQL的>SELECT 29 & 15;
- > 13 MySQL的>SELECT HEX(_binary X'FF' & b'11110000');
- >'F0'
按位异或。
结果类型取决于参数是作为二进制字符串还是数字计算:
当参数具有二进制字符串类型时,会发生二进制字符串评估,并且其中至少有一个不是十六进制文字,位字面值或
NULL
文字。
否则进行数值计算,必要时将参数转换为无符号64位整数。
二进制字符串求值会生成与参数长度相同的二进制字符串。
如果参数长度不等,
ER_INVALID_BITWISE_OPERANDS_SIZE
则会发生错误。
数值计算生成无符号的64位整数。
有关更多信息,请参阅本节中的介绍性讨论。
MySQL的>SELECT 1 ^ 1;
- > 0 MySQL的>SELECT 1 ^ 0;
- > 1 MySQL的>SELECT 11 ^ 3;
- > 8 MySQL的>SELECT HEX(_binary X'FEDC' ^ X'1111');
- >'EFCD'
将longlong(
BIGINT
)数字或二进制字符串向左
移位
。
结果类型取决于bit参数是否被计算为二进制字符串或数字:
当bit参数具有二进制字符串类型且不是十六进制文字,位字面值或
NULL
文字
时,会发生二进制字符串评估
。
否则进行数值计算,必要时将参数转换为无符号的64位整数。
二进制字符串评估生成与bit参数长度相同的二进制字符串。 数值计算生成无符号的64位整数。
无论参数类型如何,在没有警告的情况下,在值结束时移位的位都会丢失。 特别是,如果移位计数大于或等于位参数中的位数,则结果中的所有位都为0。
有关更多信息,请参阅本节中的介绍性讨论。
MySQL的>SELECT 1 << 2;
- > 4 MySQL的>SELECT HEX(_binary X'00FF00FF00FF' << 8);
- >'FF00FF00FF00'
将longlong(
BIGINT
)数字或二进制字符串向右
移位
。
结果类型取决于bit参数是否被计算为二进制字符串或数字:
当bit参数具有二进制字符串类型且不是十六进制文字,位字面值或
NULL
文字
时,会发生二进制字符串评估
。
否则进行数值计算,必要时将参数转换为无符号的64位整数。
二进制字符串评估生成与bit参数长度相同的二进制字符串。 数值计算生成无符号的64位整数。
无论参数类型如何,在没有警告的情况下,在值结束时移位的位都会丢失。 特别是,如果移位计数大于或等于位参数中的位数,则结果中的所有位都为0。
有关更多信息,请参阅本节中的介绍性讨论。
MySQL的>SELECT 4 >> 2;
- > 1 MySQL的>SELECT HEX(_binary X'00FF00FF00FF' >> 8);
- >'0000FF00FF00'
反转所有位。
结果类型取决于bit参数是否被计算为二进制字符串或数字:
当bit参数具有二进制字符串类型且不是十六进制文字,位字面值或
NULL
文字
时,会发生二进制字符串评估
。
否则进行数值计算,必要时将参数转换为无符号的64位整数。
二进制字符串评估生成与bit参数长度相同的二进制字符串。 数值计算生成无符号的64位整数。
有关更多信息,请参阅本节中的介绍性讨论。
MySQL的>SELECT 5 & ~1;
- > 4 MySQL的>SELECT HEX(~X'0000FFFF1111EEEE');
- >'FFFF0000EEEE1111'
返回参数中设置的位数,
N
作为无符号的64位整数,或者
NULL
参数是否为
NULL
。
MySQL的>SELECT BIT_COUNT(64), BIT_COUNT(BINARY 64);
- > 1,7 MySQL的>SELECT BIT_COUNT('64'), BIT_COUNT(_binary '64');
- > 1,7 MySQL的>SELECT BIT_COUNT(X'40'), BIT_COUNT(_binary X'40');
- > 1,1
表12.17加密功能
名称 | 描述 |
---|---|
AES_DECRYPT() |
使用AES解密 |
AES_ENCRYPT() |
使用AES加密 |
ASYMMETRIC_DECRYPT() |
使用私钥或公钥解密密文 |
ASYMMETRIC_DERIVE() |
从非对称密钥导出对称密钥 |
ASYMMETRIC_ENCRYPT() |
使用私钥或公钥加密明文 |
ASYMMETRIC_SIGN() |
从摘要生成签名 |
ASYMMETRIC_VERIFY() |
验证签名是否与摘要匹配 |
COMPRESS() |
将结果作为二进制字符串返回 |
CREATE_ASYMMETRIC_PRIV_KEY() |
创建私钥 |
CREATE_ASYMMETRIC_PUB_KEY() |
创建公钥 |
CREATE_DH_PARAMETERS() |
生成共享DH密钥 |
CREATE_DIGEST() |
从字符串生成摘要 |
DECODE() |
解码使用ENCODE()加密的字符串 |
DES_DECRYPT() |
解密一个字符串 |
DES_ENCRYPT() |
加密字符串 |
ENCODE() |
编码一个字符串 |
ENCRYPT() |
加密字符串 |
MD5() |
计算MD5校验和 |
PASSWORD() |
计算并返回密码字符串 |
RANDOM_BYTES() |
返回一个随机字节向量 |
SHA1()
,
SHA()
|
计算SHA-1 160位校验和 |
SHA2() |
计算SHA-2校验和 |
STATEMENT_DIGEST() |
计算语句摘要哈希值 |
STATEMENT_DIGEST_TEXT() |
计算规范化语句摘要 |
UNCOMPRESS() |
解压缩压缩的字符串 |
UNCOMPRESSED_LENGTH() |
压缩前返回字符串的长度 |
VALIDATE_PASSWORD_STRENGTH() |
确定密码的强度 |
许多加密和压缩函数返回结果可能包含任意字节值的字符串。
如果你想存储这些结果,使用与一列
VARBINARY
或
BLOB
二进制字符串数据类型。
这将避免可能会更改数据值的尾随空格删除或字符集转换的潜在问题,例如,如果使用非二进制字符串数据类型(
,
)
CHAR
,
则可能会出现此问题
。
VARCHAR
TEXT
一些加密函数返回ASCII字符的字符串:
MD5()
,
SHA()
,
SHA1()
,
SHA2()
,
STATEMENT_DIGEST()
,
STATEMENT_DIGEST_TEXT()
。
它们的返回值是一个字符串,它具有由
系统变量
character_set_connection
和
collation_connection
系统变量
确定的字符集和排序规则
。
除非字符集是,否则这是非二进制字符串
binary
。
如果应用程序存储来自诸如
MD5()
或
SHA1()
返回十六进制数字字符串的
函数的值,
则可以通过将十六进制表示转换为二进制
UNHEX()
并
使用
将结果存储在
列中
来获得更有效的存储和比较
。
每对十六进制数字需要二进制形式的一个字节,因此值
取决于十六进制字符串的长度。
值为16,
值为20
。
对于
,
范围从28到32,具体取决于指定结果的所需位长度的参数。
BINARY(
N
)N
N
MD5()
SHA1()
SHA2()
N
将十六进制字符串存储在
CHAR
列中
的大小惩罚
至少为两次,如果该值存储在使用该
utf8
字符集
的列中
(每个字符使用4个字节)
,则最多为八次
。
存储字符串还会导致比较较慢,因为值较大且需要考虑字符集排序规则。
假设应用程序将
MD5()
字符串值
存储
在
CHAR(32)
列中:
CREATE TABLE md5_tbl(md5_val CHAR(32),...); INSERT INTO md5_tbl(md5_val,...)VALUES(MD5('abcdef'),...);
以十六进制字符串转换为更紧凑的形式,修改使用应用程序
UNHEX()
,并
BINARY(16)
改为如下:
CREATE TABLE md5_tbl(md5_val BINARY(16),...); INSERT INTO md5_tbl(md5_val,...)VALUES(UNHEX(MD5('abcdef')),...);
应该准备应用程序来处理非常罕见的情况,即散列函数为两个不同的输入值产生相同的值。 使冲突可检测的一种方法是使哈希列成为主键。
已知对MD5和SHA-1算法的利用。
您可能希望考虑使用本节中描述的另一种单向加密函数,例如
SHA2()
。
除非使用SSL连接,否则作为加密函数参数提供的密码或其他敏感值将以明文形式发送到MySQL服务器。 此外,这些值将出现在它们所写的任何MySQL日志中。 为避免这些类型的暴露,应用程序可以在将敏感值发送到服务器之前加密客户端上的敏感值。 相同的考虑因素适用于加密密钥。 为了避免暴露这些,应用程序可以使用存储过程来加密和解密服务器端的值。
AES_DECRYPT(
crypt_str
,key_str
[,init_vector
])
此功能使用官方AES(高级加密标准)算法解密数据。
有关更多信息,请参阅的说明
AES_ENCRYPT()
。
可选的初始化向量参数,
init_vector
。
使用
AES_DECRYPT()
的语句对于基于语句的复制不安全。
AES_ENCRYPT(
str
,key_str
[,init_vector
])
AES_ENCRYPT()
并
AES_DECRYPT()
使用官方的AES(高级加密标准)算法实现数据的加密和解密,该算法以前称为
“
Rijndael”。
“
AES标准允许各种密钥长度。
默认情况下,这些函数实现具有128位密钥长度的AES。
可以使用196或256位的密钥长度,如稍后所述。
密钥长度是性能和安全性之间的权衡。
AES_ENCRYPT()
str
使用密钥字符串
加密
字符串
key_str
并返回包含加密输出的二进制字符串。
使用密钥字符串
AES_DECRYPT()
解密加密
crypt_str
的字符串
key_str
并返回原始明文字符串。
如果任一函数参数是
NULL
,则函数返回
NULL
。
的
str
和
crypt_str
参数可以是任何长度,并且填充被自动添加到
str
所以它是所要求的基于块的算法,如AES的块的倍数。
此
AES_DECRYPT()
功能
将自动删除此填充
。
crypt_str
可以使用以下公式计算
长度
:
16 *(trunc(string_length
/ 16)+ 1)
对于128位密钥长度,将密钥传递给
key_str
参数
的最安全方法
是创建一个真正随机的128位值并将其作为二进制值传递。
例如:
插入到t VALUES(1,AES_ENCRYPT('text',UNHEX('F3229A0B371ED2D9441B830D21A390C3')));
密码短语可用于通过对密码短语进行散列来生成AES密钥。 例如:
插入到t VALUES(1,AES_ENCRYPT('text',UNHEX(SHA2('我的秘密密码',512))));
不要直接传递密码或密码
crypt_str
,先将其哈希。
此文档的早期版本建议使用前一种方法,但不再推荐使用此方法,因为此处显示的示例更安全。
如果
AES_DECRYPT()
检测到无效数据或填充不正确,则返回
NULL
。
但是,
如果输入数据或密钥无效
,则可能
AES_DECRYPT()
返回非
NULL
值(可能是垃圾)。
AES_ENCRYPT()
并
AES_DECRYPT()
允许控制块加密模式并采用可选的
init_vector
初始化向量参数:
所述
block_encryption_mode
系统变量控制用于基于块的加密算法的模式。
其默认值为
aes-128-ecb
,表示使用密钥长度128位和ECB模式进行加密。
有关此变量的允许值的说明,请参见
第5.1.8节“服务器系统变量”
。
可选
init_vector
参数为需要它的块加密模式提供初始化向量。
对于需要可选
init_vector
参数的
模式
,它必须是16个字节或更长(忽略超过16个字节)。
如果
init_vector
缺少
则会发生错误
。
对于不需要的模式
init_vector
,将忽略该
模式,
并在指定时生成警告。
可以通过调用生成用于初始化向量的随机字节串
RANDOM_BYTES(16)
。
对于需要初始化向量的加密模式,必须使用相同的向量进行加密和解密。
mysql>SET block_encryption_mode = 'aes-256-cbc';
mysql>SET @key_str = SHA2('My secret passphrase',512);
mysql>SET @init_vector = RANDOM_BYTES(16);
mysql>SET @crypt_str = AES_ENCRYPT('text',@key_str,@init_vector);
mysql>SELECT AES_DECRYPT(@crypt_str,@key_str,@init_vector);
+ ----------------------------------------------- + | AES_DECRYPT(@ crypt_str,@ key_str,@ init_vector)| + ----------------------------------------------- + | 文字| + ----------------------------------------------- +
下表列出了每种允许的块加密模式,支持它的SSL库以及是否需要初始化向量参数。
块加密模式 | 支持模式的SSL库 | 初始化向量必需 |
---|---|---|
欧洲央行 | OpenSSL,wolfSSL | 没有 |
CBC | OpenSSL,wolfSSL | 是 |
CFB1 | OpenSSL的 | 是 |
CFB8 | OpenSSL的 | 是 |
CFB128 | OpenSSL的 | 是 |
OFB | OpenSSL的 | 是 |
对基于语句的复制
使用
AES_ENCRYPT()
或
AES_DECRYPT()
不安全的语句。
压缩字符串并将结果作为二进制字符串返回。
这个函数要求MySQL已经用压缩库编译,如
zlib
。
否则,返回值始终为
NULL
。
压缩后的字符串可以解压缩
UNCOMPRESS()
。
MySQL的>SELECT LENGTH(COMPRESS(REPEAT('a',1000)));
- > 21 MySQL的>SELECT LENGTH(COMPRESS(''));
- > 0 MySQL的>SELECT LENGTH(COMPRESS('a'));
- > 13 MySQL的>SELECT LENGTH(COMPRESS(REPEAT('a',16)));
- > 15
压缩的字符串内容按以下方式存储:
在MySQL 8.0.3中删除了此功能。
考虑使用
AES_ENCRYPT()
而
AES_DECRYPT()
不是。
DES_DECRYPT(
crypt_str
[,key_str
])
在MySQL 8.0.3中删除了此功能。
考虑使用
AES_ENCRYPT()
而
AES_DECRYPT()
不是。
DES_ENCRYPT(
str
[,{key_num
|key_str
}])
在MySQL 8.0.3中删除了此功能。
考虑使用
AES_ENCRYPT()
而
AES_DECRYPT()
不是。
在MySQL 8.0.3中删除了此功能。
考虑使用
AES_ENCRYPT()
而
AES_DECRYPT()
不是。
在MySQL 8.0.3中删除了此功能。
对于单向散列,请考虑使用
SHA2()
。
计算字符串的MD5 128位校验和。
该值以32个十六进制数字的字符串形式返回,或者
NULL
如果参数为
NULL
。
例如,返回值可以用作散列键。
请参阅本节开头的有关有效存储哈希值的说明。
返回值是连接字符集中的字符串。
如果启用了FIPS模式,则
MD5()
返回
NULL
。
请参见
第6.5节“FIPS支持”
。
MySQL的> SELECT MD5('testing');
- >'ae2b1fca515949e5d54fb22b8ed95575'
这是 “ RSA Data Security,Inc。MD5消息摘要算法”。 ”
请参阅本节开头的有关MD5算法的说明。
在MySQL 8.0.11中删除了此功能。
此函数返回
len
使用SSL库的随机数生成器生成
的
随机字节
的二进制字符串
。
允许的值
len
范围为1到1024.对于该范围之外的值,将
RANDOM_BYTES()
生成警告并返回
NULL
。
RANDOM_BYTES()
可用于为
AES_DECRYPT()
和
AES_ENCRYPT()
函数
提供初始化向量
。
要在该上下文中使用,
len
必须至少为16.允许更大的值,但忽略超过16的字节。
RANDOM_BYTES()
生成一个随机值,使其结果不确定。
因此,使用此函数的语句对于基于语句的复制是不安全的。
计算字符串的SHA-1 160位校验和,如RFC 3174(安全散列算法)中所述。
该值以40个十六进制数字的字符串形式返回,或者
NULL
如果参数为
NULL
。
此函数的一种可能用途是作为哈希键。
请参阅本节开头的有关有效存储哈希值的说明。
SHA()
是的同义词
SHA1()
。
返回值是连接字符集中的字符串。
MySQL的> SELECT SHA1('abc');
- >'a9993e364706816aba3e25717850c26c9cd0d89d'
计算SHA-2系列散列函数(SHA-224,SHA-256,SHA-384和SHA-512)。
第一个参数是要散列的明文字符串。
第二个参数表示结果的所需位长度,其值必须为224,256,384,512或0(相当于256)。
如果任一参数是
NULL
或者哈希长度不是允许值之一,则返回值为
NULL
。
否则,函数结果是包含所需位数的散列值。
请参阅本节开头的有关有效存储哈希值的说明。
返回值是连接字符集中的字符串。
MySQL的> SELECT SHA2('abc', 224);
- >'23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7'
仅当MySQL已配置SSL支持时,此功能才有效。 请参见 第6.3节“使用加密连接” 。
将SQL语句作为字符串,将语句摘要哈希值作为连接字符集中的字符串返回,或者
NULL
如果参数为
NULL
。
相关
STATEMENT_DIGEST_TEXT()
函数返回规范化语句摘要。
有关
语句摘要的
信息,请参见
第26.10节“性能模式语句摘要和采样”
。
这两个函数都使用MySQL解析器来解析语句。 如果解析失败,则会发生错误。 仅当语句作为文字字符串提供时,错误消息才包含解析错误。
的
max_digest_length
系统变量决定用于计算归一化的语句消化提供给这些功能的最大字节数。
mysql>SET @stmt = 'SELECT * FROM mytable WHERE cola = 10 AND colb = 20';
mysql>SELECT STATEMENT_DIGEST(@stmt);
+ ------------------------------------------------- ----------------- + | STATEMENT_DIGEST(@stmt)| + ------------------------------------------------- ----------------- + | 3bb95eeade896657c4526e74ff2a2862039d0a0fe8a9e7155b5fe492cbd78387 | + ------------------------------------------------- ----------------- + MySQL的>SELECT STATEMENT_DIGEST_TEXT(@stmt);
+ ------------------------------------------------- --------- + | STATEMENT_DIGEST_TEXT(@stmt)| + ------------------------------------------------- --------- + | SELECT * FROM`mytable` WHERE`cola` =?AND`colb` =?| + ------------------------------------------------- --------- +
STATEMENT_DIGEST_TEXT(
statement
)
将SQL语句作为字符串给出,将规范化的语句摘要作为连接字符集中的字符串返回,或者
NULL
如果参数为
NULL
。
有关其他讨论和示例,请参阅相关
STATEMENT_DIGEST()
功能
的说明
。
UNCOMPRESS(
string_to_uncompress
)
解压缩由
COMPRESS()
函数
压缩的字符串
。
如果参数不是压缩值,则结果为
NULL
。
这个函数要求MySQL已经用压缩库编译,如
zlib
。
否则,返回值始终为
NULL
。
MySQL的>SELECT UNCOMPRESS(COMPRESS('any string'));
- >'任何字符串' MySQL的>SELECT UNCOMPRESS('any string');
- > NULL
UNCOMPRESSED_LENGTH(
compressed_string
)
返回压缩字符串压缩之前的长度。
MySQL的> SELECT UNCOMPRESSED_LENGTH(COMPRESS(REPEAT('a',30)));
- > 30
VALIDATE_PASSWORD_STRENGTH(
str
)
给定表示明文密码的参数,此函数返回一个整数以指示密码的强度。 返回值的范围从0(弱)到100(强)。
密码评估由
组件
VALIDATE_PASSWORD_STRENGTH()
完成
validate_password
。
如果未安装该组件,则该函数始终返回0.有关安装的信息
validate_password
,请参见
第6.4.3节“密码验证组件”
。
要检查或配置影响密码测试的参数,请检查或设置由其实现的系统变量
validate_password
。
请参见
第6.4.3.2节“密码验证选项和变量”
。
密码经过越来越严格的测试,返回值反映了满足哪些测试,如下表所示。
此外,如果
validate_password.check_user_name
启用
了
系统变量且密码与用户名匹配,则
VALIDATE_PASSWORD_STRENGTH()
无论如何
validate_password
设置
其他
系统变量,都
返回0
。
密码测试 | 回报价值 |
---|---|
长度<4 | 0 |
长度≥4且<
validate_password.length
|
25 |
满足政策1(
LOW
)
|
50 |
满足政策2(
MEDIUM
)
|
75 |
满足政策3(
STRONG
)
|
100 |
本节介绍用于操作用户级锁的函数。
表12.18锁定功能
名称 | 描述 |
---|---|
GET_LOCK() |
获取命名锁 |
IS_FREE_LOCK() |
命名锁是否免费 |
IS_USED_LOCK() |
命名锁是否正在使用; 返回连接标识符,如果为true |
RELEASE_ALL_LOCKS() |
释放所有当前命名的锁 |
RELEASE_LOCK() |
释放命名锁 |
尝试
str
使用超时
timeout
秒
获取具有字符串给定名称的锁
。
负值
timeout
表示无限超时。
锁是独家的。
由一个会话持有,其他会话无法获得同名的锁。
返回
1
如果成功获得锁,
0
如果尝试超时(例如,由于另一个客户端已先前锁定的名称),或者
NULL
如果发生错误(比如内存溢出或线程与被杀
中mysqladmin杀
)。
GET_LOCK()
通过执行
RELEASE_LOCK()
或隐式地在会话终止时(正常或异常),
显式释放
获得的锁
。
GET_LOCK()
在事务提交或回滚时
,
不会释放
获得的锁
。
GET_LOCK()
使用元数据锁定(MDL)子系统实现。
可以获取多个同时锁定,
GET_LOCK()
并且不释放任何现有锁定。
例如,假设您执行以下语句:
SELECT GET_LOCK('lock1',10); SELECT GET_LOCK('lock2',10); SELECT RELEASE_LOCK('lock2'); SELECT RELEASE_LOCK('lock1');
第二个
GET_LOCK()
获取第二个锁,两个
RELEASE_LOCK()
调用返回1(成功)。
甚至可以为给定会话获取同名的多个锁。 在获取会话释放其名称的所有锁之前,其他会话无法获取具有该名称的锁。
获取的唯一命名锁定
GET_LOCK()
出现在Performance Schema
metadata_locks
表中。
该
OBJECT_TYPE
柱说,
USER LEVEL LOCK
和
OBJECT_NAME
列表示锁名。
在为
同一
名称
获取多个锁的情况下
,只有名称的第一个锁在
metadata_locks
表中
注册一行
。
名称的后续锁定会增加锁定中的计数器,但不会获取其他元数据锁定。
metadata_locks
释放名称上的最后一个锁实例时,将删除锁
的
行。
获取多个锁的能力意味着客户端之间可能存在死锁。
发生这种情况时,服务器会选择一个调用者并终止其锁定获取请求并显示
ER_USER_LOCK_DEADLOCK
错误。
此错误不会导致事务回滚。
MySQL对64个字符的锁名称强制执行最大长度。
GET_LOCK()
可用于实现应用程序锁定或模拟记录锁定。
名称在服务器范围内被锁定。
如果名称已在一个会话中锁定,
GET_LOCK()
阻止另一个会话请求具有相同名称的锁。
这使得同意给定锁定名称的客户端能够使用该名称执行协作建议锁定。
但请注意,它还使不在合作客户端集合中的客户端能够无意或有意地锁定名称,从而阻止任何合作客户端锁定该名称。
降低这种可能性的一种方法是使用特定于数据库或特定于应用程序的锁名称。
例如,使用表单
db_name.str
或的
锁名称
app_name.str
。
如果多个客户端正在等待锁定,则它们将获取它的顺序是未定义的。 应用程序不应假设客户端将按照发出锁定请求的顺序获取锁定。
GET_LOCK()
对于基于语句的复制是不安全的。
如果在
binlog_format
设置
为时使用此功能,则会记录警告
STATEMENT
。
由于能够获取多个命名锁,因此单个语句可以获取大量锁。 例如:
INSERT INTO ...从G1中选择GET_LOCK(t1.col_name);
这些类型的陈述可能会产生某些不利影响。 例如,如果语句部分失败并回滚,则仍然存在获取到失败点的锁。 如果意图是在插入的行和获取的锁之间存在对应关系,则不会满足该意图。 此外,如果按特定顺序授予锁定很重要,请注意结果集顺序可能会有所不同,具体取决于优化程序选择的执行计划。 由于这些原因,最好将应用程序限制为每个语句的单个锁定获取调用。
不同的锁定接口可用作插件服务或一组用户定义的函数。
与由
GET_LOCK()
相关函数
提供的接口不同,此接口提供锁名称空间和不同的读写锁
。
有关详细信息,请参见
第29.3.1节“锁定服务”
。
检查命名的锁是否
str
可以自由使用(即未锁定)。
返回
1
如果锁是免费的(没有人正在使用的锁),
0
如果锁处于使用中,并且
NULL
如果发生错误(例如,一个不正确的参数)。
此函数对于基于语句的复制不安全。
如果在
binlog_format
设置
为时使用此功能,则会记录警告
STATEMENT
。
检查命名的锁是否
str
正在使用(即锁定)。
如果是,则返回持有锁的客户端会话的连接标识符。
否则,它返回
NULL
。
此函数对于基于语句的复制不安全。
如果在
binlog_format
设置
为时使用此功能,则会记录警告
STATEMENT
。
释放当前会话持有的所有命名锁,并返回释放的锁数(如果没有则返回0)
此函数对于基于语句的复制不安全。
如果在
binlog_format
设置
为时使用此功能,则会记录警告
STATEMENT
。
释放由
str
获得
的字符串命名的锁
GET_LOCK()
。
返回
1
如果锁被释放,
0
如果锁不是由该线程(在这种情况下,锁定不会被释放)成立,
NULL
如果不存在命名的锁。
如果从未通过调用获得锁定
GET_LOCK()
或者之前已经释放
锁定,则锁定不存在
。
该
DO
声明使用方便
RELEASE_LOCK()
。
请参见
第13.2.3节“DO语法”
。
此函数对于基于语句的复制不安全。
如果在
binlog_format
设置
为时使用此功能,则会记录警告
STATEMENT
。
表12.19信息功能
名称 | 描述 |
---|---|
BENCHMARK() |
反复执行表达式 |
CHARSET() |
返回参数的字符集 |
COERCIBILITY() |
返回字符串参数的归类强制性值 |
COLLATION() |
返回字符串参数的排序规则 |
CONNECTION_ID() |
返回连接的连接ID(线程ID) |
CURRENT_ROLE() |
返回当前活动角色 |
CURRENT_USER()
,
CURRENT_USER
|
经过身份验证的用户名和主机名 |
DATABASE() |
返回默认(当前)数据库名称 |
FOUND_ROWS() |
对于带有LIMIT子句的SELECT,返回的行数没有LIMIT子句 |
ICU_VERSION() |
ICU库版本 |
LAST_INSERT_ID() |
最后一次INSERT的AUTOINCREMENT列的值 |
ROLES_GRAPHML() |
返回表示内存角色子图的GraphML文档 |
ROW_COUNT() |
行数已更新 |
SCHEMA() |
DATABASE()的同义词 |
SESSION_USER() |
USER()的同义词 |
SYSTEM_USER() |
USER()的同义词 |
USER() |
客户端提供的用户名和主机名 |
VERSION() |
返回表示MySQL服务器版本的字符串 |
该
BENCHMARK()
函数
expr
重复
执行表达式
count
次数。
它可用于计算MySQL处理表达式的速度。
结果值始终为
0
。
预期用途来自
mysql
客户端,它报告查询执行时间:
MySQL的> SELECT BENCHMARK(1000000,AES_ENCRYPT('hello','goodbye'));
+ ------------------------------------------------- - +
| BENCHMARK(1000000,AES_ENCRYPT('你好','再见'))|
+ ------------------------------------------------- - +
| 0 |
+ ------------------------------------------------- - +
1排(4.74秒)
报告的时间是客户端的已用时间,而不是服务器端的CPU时间。
建议
BENCHMARK()
多次
执行
,并根据服务器计算机的负载程度来解释结果。
BENCHMARK()
用于测量标量表达式的运行时性能,这对您使用它和解释结果的方式有一些重要的影响:
只能使用标量表达式。
虽然表达式可以是子查询,但它必须返回单个列,最多只返回一行。
例如,
BENCHMARK(10, (SELECT
* FROM
t))
如果表
t
具有多个列或多个行
,
则会失败
。
执行
语句
时间与执行所
涉及的开销量不同。
这两个具有非常不同的执行配置文件,您不应期望它们花费相同的时间。
前者涉及解析器,优化器,表锁定和运行时评估
时间。
后者仅涉及运行时评估
SELECT
expr
N
SELECT BENCHMARK(
N
,
expr
)N
N
次,和所有其他组件只有一次。
已经分配的内存结构被重用,并且运行时优化(例如已经针对聚合函数评估的结果的本地缓存)可以改变结果。
BENCHMARK()
因此,
使用
通过给予该组件更多权重并消除
由网络,解析器,优化器等引入
的
“
噪声
”
来测量运行时组件的性能
。
返回字符串参数的字符集。
MySQL的>SELECT CHARSET('abc');
- >'utf8' MySQL的>SELECT CHARSET(CONVERT('abc' USING latin1));
- >'latin1' MySQL的>SELECT CHARSET(USER());
- >'utf8'
返回字符串参数的排序规则强制性值。
MySQL的>SELECT COERCIBILITY('abc' COLLATE utf8_swedish_ci);
- > 0 MySQL的>SELECT COERCIBILITY(USER());
- > 3 MySQL的>SELECT COERCIBILITY('abc');
- > 4 MySQL的>SELECT COERCIBILITY(1000);
- > 5
返回值具有下表中显示的含义。 较低的值具有较高的优先级。
可压缩性 | 含义 | 例 |
---|---|---|
0 |
明确的整理 |
值与
COLLATE
条款
|
1 |
没有整理 | 具有不同排序规则的字符串的连接 |
2 |
隐式整理 | 列值,存储的例程参数或局部变量 |
3 |
系统常数 | USER()
回报价值
|
4 |
COERCIBLE | 文字字符串 |
5 |
数字 | 数值或时间价值 |
5 |
可忽略的 | NULL
或者来自的表达式
NULL
|
有关更多信息,请参见 第10.8.4节“表达式中的校对强制性” 。
返回字符串参数的排序规则。
MySQL的>SELECT COLLATION('abc');
- >'utf8_general_ci' MySQL的>SELECT COLLATION(_utf8mb4'abc');
- >'utf8mb4_0900_ai_ci' MySQL的>SELECT COLLATION(_latin1'abc');
- >'latin1_swedish_ci'
返回连接的连接ID(线程ID)。 每个连接都具有在当前连接的客户端集中唯一的ID。
返回
CONNECTION_ID()
的值
ID
与
INFORMATION_SCHEMA.PROCESSLIST
表中的
Id
列,
SHOW PROCESSLIST
输出
PROCESSLIST_ID
列和Performance Schema
threads
表
的
列中
显示的值类型相同
。
MySQL的> SELECT CONNECTION_ID();
- > 23786
返回一个
utf8
字符串,其中包含当前会话的当前活动角色,以逗号分隔,或者
NONE
如果没有。
该值反映了
sql_quote_show_create
系统变量
的设置
。
假设帐户被授予如下角色:
GRANT'r1','r2'到'u1'@'localhost'; 将DEFAULT ROLE ALL设置为'u1'@'localhost';
在会话中
u1
,初始
CURRENT_ROLE()
值指定默认帐户角色。
使用以下
SET
ROLE
更改:
MySQL的>SELECT CURRENT_ROLE();
+ ------------------- + | CURRENT_ROLE()| + ------------------- + | `r1` @`%`,`r2` @`%`| + ------------------- + MySQL的>SET ROLE 'r1'; SELECT CURRENT_ROLE();
+ ---------------- + | CURRENT_ROLE()| + ---------------- + | `r1` @`%`| + ---------------- +
返回服务器用于验证当前客户端的MySQL帐户的用户名和主机名组合。
此帐户确定您的访问权限。
返回值是
utf8
字符集中
的字符串
。
值的值
CURRENT_USER()
可以与值不同
USER()
。
MySQL的>SELECT USER();
- >'davida @ localhost' MySQL的>SELECT * FROM mysql.user;
错误1044:用户''@ localhost'拒绝访问 数据库'mysql' MySQL的>SELECT CURRENT_USER();
- >'@localhost'
该示例说明尽管客户端指定了用户名
davida
(由
USER()
函数
的值指示
),但服务器使用匿名用户帐户对客户端进行身份验证(如
CURRENT_USER()
值
的空用户名部分所示
)。
可能出现的一种方式是授权表中没有列出帐户
davida
。
在存储的程序或视图中,
CURRENT_USER()
返回定义对象的用户的帐户(由其
DEFINER
值指定),除非使用该
SQL SECURITY INVOKER
特征进行
定义
。
在后一种情况下,
CURRENT_USER()
返回对象的调用者。
触发器和事件没有选项来定义
SQL
SECURITY
特征,因此对于这些对象,
CURRENT_USER()
返回定义对象的用户的帐户。
要返回调用者,请使用
USER()
或
SESSION_USER()
。
以下语句支持使用该
CURRENT_USER()
函数代替受影响的用户或定义者的名称(以及可能的主机);
在这种情况下,
CURRENT_USER()
根据需要扩展:
有关此扩展
CURRENT_USER()
对复制
的影响的信息
,请参见
第17.4.1.8节“CURRENT_USER()的复制”
。
以
utf8
字符集中
的字符串形式返回默认(当前)数据库名称
。
如果没有默认数据库,则
DATABASE()
返回
NULL
。
在存储例程中,默认数据库是与例程关联的数据库,该数据库不一定与调用上下文中的默认数据库相同。
MySQL的> SELECT DATABASE();
- >'测试'
如果没有默认数据库,则
DATABASE()
返回
NULL
。
该
SQL_CALC_FOUND_ROWS
查询修改和相应的
FOUND_ROWS()
功能已被弃用例如MySQL 8.0.17,并会在将来的MySQL版本中删除。
作为替代,考虑执行您的查询
LIMIT
,然后使用
COUNT(*)
和不
使用第二个查询
LIMIT
来确定是否有其他行。
例如,而不是这些查询:
SELECT SQL_CALC_FOUND_ROWS * FROM tbl_name
WHERE id> 100 LIMIT 10;
SELECT FOUND_ROWS();
改为使用这些查询:
SELECT * FROM tbl_name
WHERE id> 100 LIMIT 10;
SELECT COUNT(*)WHERE id> 100;
COUNT(*)
受到某些优化。
SQL_CALC_FOUND_ROWS
导致某些优化被禁用。
一个
SELECT
语句可能包括一个
LIMIT
条款,限制服务器返回给客户端的行数。
在某些情况下,需要知道语句在没有的
LIMIT
情况下
返回了多少行
,但是没有再次运行语句。
要获取此行计数,请
SQL_CALC_FOUND_ROWS
在
SELECT
语句中
包含一个
选项
,然后
在
以后调用
FOUND_ROWS()
:
mysql> - > mysql>SELECT SQL_CALC_FOUND_ROWS * FROM
tbl_name
WHERE id > 100 LIMIT 10;
SELECT FOUND_ROWS();
第二个
SELECT
返回一个数字,表示如果
SELECT
没有该
LIMIT
子句
,第一个
将返回的
行数
。
如果
SQL_CALC_FOUND_ROWS
最近成功的
SELECT
语句中
没有该
选项,则
FOUND_ROWS()
返回该
语句
返回的结果集中的行数。
如果语句包含
LIMIT
子句,则
FOUND_ROWS()
返回最多行数。
例如,
FOUND_ROWS()
如果语句包含
LIMIT
10
或
,则分别返回10或60
LIMIT 50, 10
。
可用的行计数
FOUND_ROWS()
是暂时的,并且不会在语句后面的
SELECT SQL_CALC_FOUND_ROWS
语句
之后可用
。
如果您需要稍后参考该值,请将其保存:
mysql>SELECT SQL_CALC_FOUND_ROWS * FROM ... ;
mysql>SET @rows = FOUND_ROWS();
如果您正在使用
SELECT
SQL_CALC_FOUND_ROWS
,MySQL必须计算完整结果集中的行数。
但是,这比没有再次运行查询要快
LIMIT
,因为结果集不需要发送到客户端。
SQL_CALC_FOUND_ROWS
并且
FOUND_ROWS()
在您想要限制查询返回的行数的情况下非常有用,但是在不再次运行查询的情况下也可以确定完整结果集中的行数。
一个示例是一个Web脚本,它显示一个分页显示,其中包含指向显示搜索结果其他部分的页面的链接。
使用
FOUND_ROWS()
可以确定结果的其余部分需要多少其他页面。
语句
的使用
SQL_CALC_FOUND_ROWS
和
FOUND_ROWS()
复杂性
UNION
比简单
SELECT
语句
更复杂
,因为
LIMIT
可能出现在多个地方
UNION
。
它可以应用于
整个结果
SELECT
中的
单个
语句,
也可以应用于
UNION
全局
UNION
结果。
SQL_CALC_FOUND_ROWS
for
的意图
UNION
是它应该返回没有全局返回的行计数
LIMIT
。
使用的条件
SQL_CALC_FOUND_ROWS
有
UNION
如下:
FOUND_ROWS()
仅当
UNION
ALL
使用时
,值
才是精确的
。
如果
UNION
不
ALL
使用,则会发生重复删除,其值
FOUND_ROWS()
仅为近似值。
如果no
LIMIT
中存在
no
UNION
,
SQL_CALC_FOUND_ROWS
则忽略
该
函数并返回创建的临时表中的行数以进行处理
UNION
。
除了此处描述的情况之外,行为
FOUND_ROWS()
是未定义的(例如,其值在
SELECT
语句失败后出现错误)。
FOUND_ROWS()
使用基于语句的复制不能可靠地复制。
使用基于行的复制自动复制此功能。
用于支持正则表达式操作的Unicode国际组件(ICU)库的版本(请参见 第12.5.2节“正则表达式” )。 此功能主要用于测试用例。
LAST_INSERT_ID()
,
LAST_INSERT_ID(
expr
)
如果没有参数,则
LAST_INSERT_ID()
返回一个
BIGINT UNSIGNED
(64位)值,表示
AUTO_INCREMENT
由于最近执行的
INSERT
语句
而
成功为
列添加
的第一个自动生成的值
。
LAST_INSERT_ID()
如果没有成功插入行,则
值
保持不变。
使用参数,
LAST_INSERT_ID()
返回无符号整数。
例如,在插入生成
AUTO_INCREMENT
值
的行之后
,您可以获得如下值:
MySQL的> SELECT LAST_INSERT_ID();
- > 195
当前正在执行的语句不会影响其值
LAST_INSERT_ID()
。
假设您
AUTO_INCREMENT
使用一个语句
生成一个
值,然后
LAST_INSERT_ID()
在多行
INSERT
语句中
引用
,该行将行
插入到具有自己
AUTO_INCREMENT
列
的表中
。
LAST_INSERT_ID()
第二个陈述中
的价值
将保持稳定;
它的第二行和后一行的值不受先前行插入的影响。
(但是,如果将参考混合到
LAST_INSERT_ID()
和
,则效果未定义。)
LAST_INSERT_ID(
expr
)
如果前一个语句返回错误,则值为
LAST_INSERT_ID()
undefined。
对于事务表,如果语句由于错误而回滚,则值为
LAST_INSERT_ID()
undefined。
对于手动
ROLLBACK
,其值
LAST_INSERT_ID()
不会恢复到事务之前的值;
它仍然保持原样
ROLLBACK
。
在存储例程(过程或函数)或触发器
LAST_INSERT_ID()
的主体内
,
更改的
值与
在这些对象的主体外执行的语句
的
更改方式相同。
LAST_INSERT_ID()
以下语句可以看出
存储的例程或触发器对其值的影响
取决于例程的类型:
如果存储过程执行更改值的语句,则更改的值
LAST_INSERT_ID()
将由过程调用之后的语句看到。
对于更改值的存储函数和触发器,当函数或触发器结束时,将恢复该值,因此后续语句将不会看到更改的值。
生成的ID在
每个连接的基础上
在服务器中维护
。
这意味着函数返回给定客户端的
AUTO_INCREMENT
值
是为该客户端
影响
AUTO_INCREMENT
列
的
最新语句生成
的第一个
值
。
此值不受其他客户端的影响,即使它们生成
AUTO_INCREMENT
自己的值。
此行为可确保每个客户端都可以检索自己的ID,而无需关心其他客户端的活动,也无需锁定或事务。
LAST_INSERT_ID()
如果将
AUTO_INCREMENT
行
的
列
设置
为非
“
魔术
”
值(即,不是
NULL
和不是
的值),
则不会更改
值
0
。
如果您将使用一个多行
INSERT
的语句,
LAST_INSERT_ID()
返回所产生的价值
第一次
插入的行
只
。
这样做的原因是可以轻松地重现
INSERT
与其他服务器
相同的
语句。
例如:
MySQL的>USE test;
MySQL的>CREATE TABLE t (
id INT AUTO_INCREMENT NOT NULL PRIMARY KEY,
name VARCHAR(10) NOT NULL
);
MySQL的>INSERT INTO t VALUES (NULL, 'Bob');
MySQL的>SELECT * FROM t;
+ ---- + ------ + | id | 名字| + ---- + ------ + | 1 | 鲍勃| + ---- + ------ + MySQL的>SELECT LAST_INSERT_ID();
+ ------------------ + | LAST_INSERT_ID()| + ------------------ + | 1 | + ------------------ + MySQL的>INSERT INTO t VALUES
(NULL, 'Mary'), (NULL, 'Jane'), (NULL, 'Lisa');
MySQL的>SELECT * FROM t;
+ ---- + ------ + | id | 名字| + ---- + ------ + | 1 | 鲍勃| | 2 | 玛丽| | 3 | 简| | 4 | 丽莎| + ---- + ------ + MySQL的>SELECT LAST_INSERT_ID();
+ ------------------ + | LAST_INSERT_ID()| + ------------------ + | 2 | + ------------------ +
虽然第二个
INSERT
语句插入了三个新行
t
,但是为这些行中的第一行生成的ID是
2
,并且这个值是由
LAST_INSERT_ID()
以下
SELECT
语句
返回的
。
如果使用
INSERT
IGNORE
并且忽略该行,则
LAST_INSERT_ID()
保持与当前值保持不变(如果连接尚未成功
INSERT
,
则返回0
),对于非事务表,
AUTO_INCREMENT
计数器不会递增。
对于
InnoDB
表,
AUTO_INCREMENT
如果
innodb_autoinc_lock_mode
设置为
1
或
,则
计数器会递增
2
,如以下示例所示:
MySQL的>USE test;
MySQL的>SELECT @@innodb_autoinc_lock_mode;
+ ---------------------------- + | @@ innodb_autoinc_lock_mode | + ---------------------------- + | 1 | + ---------------------------- + MySQL的>CREATE TABLE `t` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`val` INT(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `i1` (`val`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
#插入两行 MySQL的>INSERT INTO t (val) VALUES (1),(2);
#with auto_increment_offset = 1,插入行 #结果AUTO_INCREMENT值为3 MySQL的>SHOW CREATE TABLE t\G
*************************** 1。排******************** ******* 表:t 创建表:CREATE TABLE`t`( `id` int(11)NOT NULL AUTO_INCREMENT, `val` int(11)DEFAULT NULL, PRIMARY KEY(`id`), 独特的钥匙`i1`(`val`) )ENGINE = InnoDB AUTO_INCREMENT = 3 DEFAULT CHARSET = latin1 #LAST_INSERT_ID()返回第一个自动生成的 为AUTO_INCREMENT列成功插入的#value MySQL的>SELECT LAST_INSERT_ID();
+ ------------------ + | LAST_INSERT_ID()| + ------------------ + | 1 | + ------------------ + #尝试插入重复行失败但忽略错误 MySQL的>INSERT IGNORE INTO t (val) VALUES (1),(2);
查询正常,0行受影响(0.00秒) 记录:2个重复:2个警告:0 #with innodb_autoinc_lock_mode = 1,AUTO_INCREMENT计数器 对于忽略的行,#递增 MySQL的>SHOW CREATE TABLE t\G
*************************** 1。排******************** ******* 表:t 创建表:CREATE TABLE`t`( `id` int(11)NOT NULL AUTO_INCREMENT, `val` int(11)DEFAULT NULL, PRIMARY KEY(`id`), 独特的钥匙`i1`(`val`) )ENGINE = InnoDB AUTO_INCREMENT = 5 DEFAULT CHARSET = latin1 #LAST_INSERT_ID未更改,因为前一个插入不成功 MySQL的>SELECT LAST_INSERT_ID();
+ ------------------ + | LAST_INSERT_ID()| + ------------------ + | 1 | + ------------------ +
有关更多信息,请参见 第15.6.1.4节“InnoDB中的AUTO_INCREMENT处理” 。
如果
expr
作为参数给出,则参数
LAST_INSERT_ID()
的值由函数返回,并记住作为要返回的下一个值
LAST_INSERT_ID()
。
这可以用来模拟序列:
创建一个表来保存序列计数器并初始化它:
mysql>CREATE TABLE sequence (id INT NOT NULL);
mysql>INSERT INTO sequence VALUES (0);
使用该表生成如下序列号:
mysql>UPDATE sequence SET id=LAST_INSERT_ID(id+1);
mysql>SELECT LAST_INSERT_ID();
该
UPDATE
语句递增序列计数器并使下一次调用
LAST_INSERT_ID()
返回更新的值。
该
SELECT
语句检索该值。
在
mysql_insert_id()
C API函数也可以用于获取价值。
请参见
第28.7.7.38节“mysql_insert_id()”
。
您可以在不调用的情况下生成序列
LAST_INSERT_ID()
,但以这种方式使用函数的实用程序是ID值在服务器中作为最后自动生成的值进行维护。
它是多用户安全的,因为多个客户端可以发出
UPDATE
语句并使用
SELECT
语句(或
mysql_insert_id()
)
获取自己的序列值
,而不会影响或受到生成其自己的序列值的其他客户端的影响。
请注意,
mysql_insert_id()
仅在
语句
INSERT
和
UPDATE
语句
之后更新
,因此
在执行其他SQL语句(如
或)
之后,
无法使用C API函数来检索值
。
LAST_INSERT_ID(
expr
)SELECT
SET
返回
utf8
包含表示内存角色子图的GraphML文档
的
字符串。
该
ROLE_ADMIN
或
SUPER
特权才能看到的内容
<graphml>
元素。
否则,结果只显示一个空元素:
MySQL的> SELECT ROLES_GRAPHML();
+ ------------------------------------------------- - +
| ROLES_GRAPHML()|
+ ------------------------------------------------- - +
| <?xml version =“1.0”encoding =“UTF-8”?> <graphml /> |
+ ------------------------------------------------- - +
ROW_COUNT()
返回一个值,如下所示:
DDL语句:0。这适用于诸如
CREATE TABLE
或的
语句
DROP
TABLE
。
除
SELECT
以下之外的
DML语句
:受影响的行数。
这适用于报表等
UPDATE
,
INSERT
或
DELETE
(如前),但现在还声明,如
ALTER
TABLE
和
LOAD
DATA
。
SELECT
:如果语句返回结果集,则返回-1;如果不返回,则返回
“
受影响
”
的行数
。
例如,for
SELECT * FROM t1
,
ROW_COUNT()
返回-1。
For
,
返回写入文件的行数。
SELECT * FROM t1 INTO OUTFILE
'
file_name
'ROW_COUNT()
SIGNAL
陈述:0。
对于
UPDATE
语句,默认情况下受影响的行值是实际更改的行数。
如果
在连接到
mysqld
时
指定了
CLIENT_FOUND_ROWS
标志
,则受影响的行值是
“
找到
”
的行数
;
也就是说,与
条款
相匹配
。
mysql_real_connect()
WHERE
对于
REPLACE
语句,如果新行替换旧行,则affected-rows值为2,因为在这种情况下,在删除副本后插入了一行。
对于
INSERT
... ON DUPLICATE KEY UPDATE
语句,如果将行作为新行插入,则每行的受影响行值为1;如果更新现有行,则为2,如果现有行设置为其当前值,则为0。
如果指定
CLIENT_FOUND_ROWS
标志,则如果将现有行设置为其当前值,则affected-rows值为1(不为0)。
该
ROW_COUNT()
值类似于
mysql_affected_rows()
C API函数中
的值
以及
mysql
客户端在语句执行后显示
的行计数
。
MySQL的>INSERT INTO t VALUES(1),(2),(3);
查询OK,3行受影响(0.00秒) 记录:3个重复:0个警告:0 MySQL的>SELECT ROW_COUNT();
+ ------------- + | ROW_COUNT()| + ------------- + | 3 | + ------------- + 1排(0.00秒) MySQL的>DELETE FROM t WHERE i IN(1,2);
查询正常,2行受影响(0.00秒) MySQL的>SELECT ROW_COUNT();
+ ------------- + | ROW_COUNT()| + ------------- + | 2 | + ------------- + 1排(0.00秒)
ROW_COUNT()
使用基于语句的复制不能可靠地复制。
使用基于行的复制自动复制此功能。
此功能是其同义词
DATABASE()
。
SESSION_USER()
是...的同义词
USER()
。
SYSTEM_USER()
是...的同义词
USER()
。
该
SYSTEM_USER()
功能与
SYSTEM_USER
特权不同。
前者返回当前的MySQL帐户名。
后者区分系统用户和常规用户帐户类别(请参见
第6.2.11节“帐户类别”
)。
以
utf8
字符集中
的字符串形式返回当前MySQL用户名和主机名
。
MySQL的> SELECT USER();
- >'davida @ localhost'
该值表示您在连接到服务器时指定的用户名,以及您连接的客户端主机。
该值可以不同于
CURRENT_USER()
。
返回表示MySQL服务器版本的字符串。
该字符串使用
utf8
字符集。
除版本号外,该值可能还有一个后缀。
见的描述
version
在系统变量
第5.1.8节,“服务器系统变量”
。
此函数对于基于语句的复制不安全。
如果在
binlog_format
设置
为时使用此功能,则会记录警告
STATEMENT
。
MySQL的> SELECT VERSION();
- >'8.0.18-standard'
MySQL提供了对空间数据执行各种操作的功能。 这些功能可以根据它们执行的操作类型分为几个主要类别:
以各种格式创建几何的函数(WKT,WKB,内部)
在格式之间转换几何的函数
访问几何的定性或定量属性的函数
描述两个几何之间关系的函数
从现有几何创建新几何的函数
有关MySQL支持使用空间数据的一般背景,请参见 第11.5节“空间数据类型” 。
下表列出了每个空间函数,并提供了每个空间函数的简短描述。
表12.20空间函数
空间值或几何具有 第11.5.2.2节“几何类”中 描述的属性 。 以下讨论列出了一般空间函数参数处理特征。 特定函数或函数组可能具有其他参数处理特性,如发生这些函数描述的部分所述。
空间函数仅针对有效几何值定义。
几何的空间参考标识符(SRID)标识定义几何的坐标空间。 在MySQL中,SRID值是与几何值关联的整数。 最大可用SRID值为2 32 -1。 如果给出更大的值,则仅使用低32位。
SRID 0表示无限平坦的笛卡尔平面,其轴没有单位。 要确保SRID 0行为,请使用SRID 0创建几何值。如果未指定SRID,则SRID 0是新几何值的默认值。
任何空间函数生成的几何值都会继承几何参数的SRID。
采用多个几何参数的空间函数要求这些参数具有相同的SRID值(即,低32位中的相同值)。
假设相等的SRID,空间函数在执行相等检查后不对它们执行任何操作;
使用笛卡尔坐标(SRID 0)隐式处理几何值。
如果空间函数返回
ER_GIS_DIFFERENT_SRIDS
,则意味着几何参数并非都具有相同的SRID。
您必须修改它们以具有相同的SRID。
该 开放地理空间联盟 准则要求输入多边形已经被关闭,因此未闭合的多边形拒绝为无效,而不是被关闭。
空几何集合处理如下:可以将空WKT输入几何集合指定为
'GEOMETRYCOLLECTION()'
。
这也是由生成空几何集合的空间操作产生的输出WKT。
在解析嵌套几何集合期间,集合被展平,其基本组件用于各种GIS操作以计算结果。 这为用户提供了额外的灵活性,因为不必担心几何数据的唯一性。 嵌套几何集合可以从嵌套的GIS函数调用生成,而不必首先显式展平。
这些函数将知名文本(WKT)表示和可选的空间参考系统标识符(SRID)作为参数。 它们返回相应的几何体。 有关WKT格式的说明,请参阅 熟知文本(WKT)格式 。
本节中的函数检测笛卡尔或地理空间参照系(SRS)中的参数,并返回适合SRS的结果。
ST_GeomFromText()
接受任何几何类型的WKT值作为其第一个参数。
其他函数提供特定于类型的构造函数,用于构造每种几何类型的几何值。
诸如
ST_MPointFromText()
和
ST_GeomFromText()
接受WKT格式的
MultiPoint
值
表示的
函数允许值内的各个点被括号括起来。
例如,以下两个函数调用都是有效的:
ST_MPointFromText('MULTIPOINT(1 1,2 2,3 3)') ST_MPointFromText('MULTIPOINT((1 1),(2 2),(3 3))')
比如函数
ST_GeomFromText()
接受WKT几何集合参数了解双方开放地理信息系统
'GEOMETRYCOLLECTION EMPTY'
标准语法和MySQL的
'GEOMETRYCOLLECTION()'
非标准语法。
如函数
ST_AsWKT()
产生WKT值产生
'GEOMETRYCOLLECTION
EMPTY'
标准语法:
mysql>SET @s1 = ST_GeomFromText('GEOMETRYCOLLECTION()');
mysql>SET @s2 = ST_GeomFromText('GEOMETRYCOLLECTION EMPTY');
mysql>SELECT ST_AsWKT(@s1), ST_AsWKT(@s2);
+ -------------------------- + ---------------------- ---- + | ST_AsWKT(@ s1)| ST_AsWKT(@ s2)| + -------------------------- + ---------------------- ---- + | GEOMETRYCOLLECTION EMPTY | GEOMETRYCOLLECTION EMPTY | + -------------------------- + ---------------------- ---- +
除非另有说明,否则本节中的函数处理其参数如下:
如果任何几何参数是
NULL
或者不是语法上格式良好的几何,或者如果SRID参数是
NULL
,则返回值为
NULL
。
默认情况下,地理坐标(纬度,经度)按几何参数的空间参考系统指定的顺序进行解释。
options
可以给出
可选
参数来覆盖默认轴顺序。
options
由逗号分隔列表组成
。
唯一
允许的值
是
,允许值为
,
和
(默认值)。
key
=value
key
axis-order
lat-long
long-lat
srid-defined
如果
options
参数是
NULL
,则返回值为
NULL
。
如果
options
参数无效,则会发生错误以指示原因。
如果SRID参数引用未定义的空间参考系统(SRS),
ER_SRS_NOT_FOUND
则会发生错误。
对于地理SRS几何参数,如果任何参数的经度或纬度超出范围,则会发生错误:
如果经度值不在范围(-180,180)内,
ER_LONGITUDE_OUT_OF_RANGE
则会发生错误。
如果纬度值不在[-90,90]范围内,
ER_LATITUDE_OUT_OF_RANGE
则会发生错误。
显示的范围以度为单位。 如果SRS使用其他单位,则该范围使用其单位中的相应值。 由于浮点运算,精确的范围限制略有偏差。
这些函数可用于从WKT值创建几何:
ST_GeomCollFromText(
,
,
wkt
[,
srid
[,
options
]])ST_GeometryCollectionFromText(
wkt
[,
srid
[,
options
]])ST_GeomCollFromTxt(
wkt
[,
srid
[,
options
]])
GeometryCollection
使用其WKT表示和SRID
构造
值。
这些函数处理它们的参数,如本节的介绍中所述。
mysql>SET @g = "MULTILINESTRING((10 10, 11 11), (9 9, 10 10))";
mysql>SELECT ST_AsText(ST_GeomCollFromText(@g));
+ -------------------------------------------- + | ST_AsText(ST_GeomCollFromText(@g))| + -------------------------------------------- + | MULTILINESTRING((10 10,11 11),(9 9,10 10))| + -------------------------------------------- +
ST_GeomFromText(
,
wkt
[,
srid
[,
options
]])ST_GeometryFromText(
wkt
[,
srid
[,
options
]])
使用其WKT表示和SRID构造任何类型的几何值。
这些函数处理它们的参数,如本节的介绍中所述。
ST_LineFromText(
,
wkt
[,
srid
[,
options
]])ST_LineStringFromText(
wkt
[,
srid
[,
options
]])
LineString
使用其WKT表示和SRID
构造
值。
这些函数处理它们的参数,如本节的介绍中所述。
ST_MLineFromText(
,
wkt
[,
srid
[,
options
]])ST_MultiLineStringFromText(
wkt
[,
srid
[,
options
]])
MultiLineString
使用其WKT表示和SRID
构造
值。
这些函数处理它们的参数,如本节的介绍中所述。
ST_MPointFromText(
,
wkt
[,
srid
[,
options
]])ST_MultiPointFromText(
wkt
[,
srid
[,
options
]])
MultiPoint
使用其WKT表示和SRID
构造
值。
这些函数处理它们的参数,如本节的介绍中所述。
ST_MPolyFromText(
,
wkt
[,
srid
[,
options
]])ST_MultiPolygonFromText(
wkt
[,
srid
[,
options
]])
MultiPolygon
使用其WKT表示和SRID
构造
值。
这些函数处理它们的参数,如本节的介绍中所述。
ST_PointFromText(
wkt
[,
srid
[,
options
]])
Point
使用其WKT表示和SRID
构造
值。
ST_PointFromText()
处理其参数,如本节的介绍中所述。
ST_PolyFromText(
,
wkt
[,
srid
[,
options
]])ST_PolygonFromText(
wkt
[,
srid
[,
options
]])
Polygon
使用其WKT表示和SRID
构造
值。
这些函数处理它们的参数,如本节的介绍中所述。
这些函数将参数a作为
BLOB
包含已知二进制(WKB)表示的参数,并且可选地包含空间参考系统标识符(SRID)。
它们返回相应的几何体。
有关WKB格式的说明,请参见
熟知二进制(WKB)格式
。
本节中的函数检测笛卡尔或地理空间参照系(SRS)中的参数,并返回适合SRS的结果。
ST_GeomFromWKB()
接受任何几何类型的WKB值作为其第一个参数。
其他函数提供特定于类型的构造函数,用于构造每种几何类型的几何值。
在MySQL 8.0之前,这些函数还接受了 第12.16.5节“创建几何值的MySQL特定函数”中 的函数返回的几何对象 。 不再允许使用几何参数并产生错误。 要将调用从使用几何参数迁移到使用WKB参数,请遵循以下准则:
重写结构,如
ST_GeomFromWKB(Point(0,
0))
作为
Point(0, 0)
。
重写诸如
ST_GeomFromWKB(Point(0,
0), 4326)
as
ST_SRID(Point(0, 0),
4326)
或
ST_GeomFromWKB(ST_AsWKB(Point(0,
0)), 4326)
。之类的
结构
。
除非另有说明,否则本节中的函数处理其参数如下:
如果是WKB或SRID参数
NULL
,则返回值为
NULL
。
默认情况下,地理坐标(纬度,经度)按几何参数的空间参考系统指定的顺序进行解释。
options
可以给出
可选
参数来覆盖默认轴顺序。
options
由逗号分隔列表组成
。
唯一
允许的值
是
,允许值为
,
和
(默认值)。
key
=value
key
axis-order
lat-long
long-lat
srid-defined
如果
options
参数是
NULL
,则返回值为
NULL
。
如果
options
参数无效,则会发生错误以指示原因。
如果SRID参数引用未定义的空间参考系统(SRS),
ER_SRS_NOT_FOUND
则会发生错误。
对于地理SRS几何参数,如果任何参数的经度或纬度超出范围,则会发生错误:
如果经度值不在范围(-180,180)内,
ER_LONGITUDE_OUT_OF_RANGE
则会发生错误。
如果纬度值不在[-90,90]范围内,
ER_LATITUDE_OUT_OF_RANGE
则会发生错误。
显示的范围以度为单位。 如果SRS使用其他单位,则该范围使用其单位中的相应值。 由于浮点运算,精确的范围限制略有偏差。
这些函数可用于从WKB值创建几何:
ST_GeomCollFromWKB(
,
wkb
[,
srid
[,
options
]])ST_GeometryCollectionFromWKB(
wkb
[,
srid
[,
options
]])
GeometryCollection
使用其WKB表示和SRID
构造
值。
这些函数处理它们的参数,如本节的介绍中所述。
ST_GeomFromWKB(
,
wkb
[,
srid
[,
options
]])ST_GeometryFromWKB(
wkb
[,
srid
[,
options
]])
使用其WKB表示和SRID构造任何类型的几何值。
这些函数处理它们的参数,如本节的介绍中所述。
ST_LineFromWKB(
,
wkb
[,
srid
[,
options
]])ST_LineStringFromWKB(
wkb
[,
srid
[,
options
]])
LineString
使用其WKB表示和SRID
构造
值。
这些函数处理它们的参数,如本节的介绍中所述。
ST_MLineFromWKB(
,
wkb
[,
srid
[,
options
]])ST_MultiLineStringFromWKB(
wkb
[,
srid
[,
options
]])
MultiLineString
使用其WKB表示和SRID
构造
值。
这些函数处理它们的参数,如本节的介绍中所述。
ST_MPointFromWKB(
,
wkb
[,
srid
[,
options
]])ST_MultiPointFromWKB(
wkb
[,
srid
[,
options
]])
MultiPoint
使用其WKB表示和SRID
构造
值。
这些函数处理它们的参数,如本节的介绍中所述。
ST_MPolyFromWKB(
,
wkb
[,
srid
[,
options
]])ST_MultiPolygonFromWKB(
wkb
[,
srid
[,
options
]])
MultiPolygon
使用其WKB表示和SRID
构造
值。
这些函数处理它们的参数,如本节的介绍中所述。
ST_PointFromWKB(
wkb
[,
srid
[,
options
]])
Point
使用其WKB表示和SRID
构造
值。
ST_PointFromWKB()
处理其参数,如本节的介绍中所述。
ST_PolyFromWKB(
,
wkb
[,
srid
[,
options
]])ST_PolygonFromWKB(
wkb
[,
srid
[,
options
]])
Polygon
使用其WKB表示和SRID
构造
值。
这些函数处理它们的参数,如本节的介绍中所述。
MySQL提供了一组有用的非标准函数来创建几何值。 本节中描述的函数是OpenGIS规范的MySQL扩展。
这些函数从WKB值或几何对象作为参数生成几何对象。
如果任何参数不是正确对象类型的正确WKB或几何表示,则返回值为
NULL
。
例如,您可以将几何返回值
Point()
直接插入到
POINT
列中:
INSERT INTO t1(pt_col)VALUES(Point(1,2));
GeomCollection
根据几何参数
构造一个
值。
GeomCollection()
返回参数中包含的所有适当几何,即使存在不支持的几何体也是如此。
GeomCollection()
允许不带参数作为创建空几何的方法。
此外,诸如
ST_GeomFromText()
接受WKT几何集合参数的函数同时理解OpenGIS
'GEOMETRYCOLLECTION EMPTY'
标准语法和MySQL
'GEOMETRYCOLLECTION()'
非标准语法。
GeomCollection()
并且
GeometryCollection()
是具有
GeomCollection()
首选功能的
同义词
。
GeometryCollection(
g
[, g
] ...)
GeomCollection
根据几何参数
构造一个
值。
GeometryCollection()
返回参数中包含的所有适当几何,即使存在不支持的几何体也是如此。
GeometryCollection()
允许不带参数作为创建空几何的方法。
此外,诸如
ST_GeomFromText()
接受WKT几何集合参数的函数同时理解OpenGIS
'GEOMETRYCOLLECTION EMPTY'
标准语法和MySQL
'GEOMETRYCOLLECTION()'
非标准语法。
GeomCollection()
并且
GeometryCollection()
是具有
GeomCollection()
首选功能的
同义词
。
LineString
根据许多
Point
或WKB
Point
参数
构造一个
值
。
如果参数的数量小于2,则返回值为
NULL
。
MultiLineString(
ls
[, ls
] ...)
MultiLineString
使用
LineString
或WKB
LineString
参数
构造
值
。
MultiPoint
使用
Point
或WKB
Point
参数
构造
值
。
MultiPolygon(
poly
[, poly
] ...)
MultiPolygon
根据一组
Polygon
或WKB
Polygon
参数
构造一个
值
。
Point
使用其坐标
构造a
。
Polygon
根据许多
LineString
或WKB
LineString
参数
构造一个
值
。
如果任何参数不表示
LinearRing
(即,不是封闭且简单
LineString
),则返回值为
NULL
。
MySQL支持本节中列出的函数,用于将几何值从内部几何格式转换为WKT或WKB格式,或者用于交换X和Y坐标的顺序。
还有将字符串从WKT或WKB格式转换为内部几何格式的函数。 请参见 第12.16.3节“从WKT值创建几何值的函数” 和 第12.16.4节“从WKB值创建几何值的函数” 。
比如函数
ST_GeomFromText()
接受WKT几何集合参数了解双方开放地理信息系统
'GEOMETRYCOLLECTION EMPTY'
标准语法和MySQL的
'GEOMETRYCOLLECTION()'
非标准语法。
生成空几何集合的另一种方法是通过
GeometryCollection()
不带参数
调用
。
如函数
ST_AsWKT()
产生WKT值产生
'GEOMETRYCOLLECTION
EMPTY'
标准语法:
mysql>SET @s1 = ST_GeomFromText('GEOMETRYCOLLECTION()');
mysql>SET @s2 = ST_GeomFromText('GEOMETRYCOLLECTION EMPTY');
mysql>SELECT ST_AsWKT(@s1), ST_AsWKT(@s2);
+ -------------------------- + ---------------------- ---- + | ST_AsWKT(@ s1)| ST_AsWKT(@ s2)| + -------------------------- + ---------------------- ---- + | GEOMETRYCOLLECTION EMPTY | GEOMETRYCOLLECTION EMPTY | + -------------------------- + ---------------------- ---- + MySQL的>SELECT ST_AsWKT(GeomCollection());
+ ---------------------------- + | ST_AsWKT(GeomCollection())| + ---------------------------- + | GEOMETRYCOLLECTION EMPTY | + ---------------------------- +
除非另有说明,否则本节中的函数处理其参数如下:
如果有任何参数
NULL
,则返回值为
NULL
。
如果任何几何参数不是语法上格式良好的几何体,
ER_GIS_INVALID_DATA
则会发生错误。
如果任何几何参数位于未定义的空间参照系中,则轴将按照它们在几何图形中出现的顺序输出,并发出
ER_WARN_SRS_NOT_FOUND_AXIS_ORDER
警告。
默认情况下,地理坐标(纬度,经度)按几何参数的空间参考系统指定的顺序进行解释。
options
可以给出
可选
参数来覆盖默认轴顺序。
options
由逗号分隔列表组成
。
唯一
允许的值
是
,允许值为
,
和
(默认值)。
key
=value
key
axis-order
lat-long
long-lat
srid-defined
如果
options
参数是
NULL
,则返回值为
NULL
。
如果
options
参数无效,则会发生错误以指示原因。
否则,返回值为非
NULL
。
这些函数可用于格式转换或坐标交换:
ST_AsBinary(
,
g
[, options
])ST_AsWKB(
g
[, options
])
将内部几何格式的值转换为其WKB表示并返回二进制结果。
函数返回值具有应用于几何参数的空间参考系统指定的顺序的地理坐标(纬度,经度)。
options
可以给出
可选
参数来覆盖默认轴顺序。
ST_AsBinary()
并
ST_AsWKB()
按照本节的介绍中的描述处理它们的参数。
mysql>SET @g = ST_LineFromText('LINESTRING(0 5,5 10,10 15)', 4326);
mysql>SELECT ST_AsText(ST_GeomFromWKB(ST_AsWKB(@g)));
+ ----------------------------------------- + | ST_AsText(ST_GeomFromWKB(ST_AsWKB(@g)))| + ----------------------------------------- + | LINESTRING(5 0,10 5,15 10)| + ----------------------------------------- + MySQL的>SELECT ST_AsText(ST_GeomFromWKB(ST_AsWKB(@g, 'axis-order=long-lat')));
+ ------------------------------------------------- --------------- + | ST_AsText(ST_GeomFromWKB(ST_AsWKB(@ g,'axis-order = long-lat')))| + ------------------------------------------------- --------------- + | LINESTRING(0 5,5 10,10 15)| + ------------------------------------------------- --------------- + MySQL的>SELECT ST_AsText(ST_GeomFromWKB(ST_AsWKB(@g, 'axis-order=lat-long')));
+ ------------------------------------------------- --------------- + | ST_AsText(ST_GeomFromWKB(ST_AsWKB(@ g,'axis-order = lat-long')))| + ------------------------------------------------- --------------- + | LINESTRING(5 0,10 5,15 10)| + ------------------------------------------------- --------------- +
ST_AsText(
,
g
[,
options
])ST_AsWKT(
g
[, options
])
将内部几何格式的值转换为其WKT表示形式并返回字符串结果。
函数返回值具有应用于几何参数的空间参考系统指定的顺序的地理坐标(纬度,经度)。
options
可以给出
可选
参数来覆盖默认轴顺序。
ST_AsText()
和
ST_AsWKT()
按照本节的介绍中的描述处理它们的参数。
mysql>SET @g = 'LineString(1 1,2 2,3 3)';
mysql>SELECT ST_AsText(ST_GeomFromText(@g));
+ -------------------------------- + | ST_AsText(ST_GeomFromText(@g))| + -------------------------------- + | LINESTRING(1 1,2 2,3 3)| + -------------------------------- +
输出为
MultiPoint
值的
包括每个点周围的括号。
例如:
MySQL的> SELECT ST_AsText(ST_GeomFromText(@mp));
+ --------------------------------- +
| ST_AsText(ST_GeomFromText(@mp))|
+ --------------------------------- +
| MULTIPOINT((1 1),(2 2),(3 3))|
+ --------------------------------- +
接受内部几何格式的参数,交换几何中每个坐标对的X和Y值,并返回结果。
ST_SwapXY()
处理其参数,如本节的介绍中所述。
mysql>SET @g = ST_LineFromText('LINESTRING(0 5,5 10,10 15)');
mysql>SELECT ST_AsText(@g);
+ ---------------------------- + | ST_AsText(@g)| + ---------------------------- + | LINESTRING(0 5,5 10,10 15)| + ---------------------------- + MySQL的>SELECT ST_AsText(ST_SwapXY(@g));
+ ---------------------------- + | ST_AsText(ST_SwapXY(@g))| + ---------------------------- + | LINESTRING(5 0,10 5,15 10)| + ---------------------------- +
属于该组的每个函数都将几何值作为其参数,并返回几何的一些定量或定性属性。
某些函数限制其参数类型。
NULL
如果参数的几何类型不正确,则
返回此类函数
。
例如,
如果对象类型既不是
也不
是
,则
ST_Area()
返回polygon函数
。
NULL
Polygon
MultiPolygon
本节中列出的函数不限制其参数并接受任何类型的几何值。
除非另有说明,否则本节中的函数处理其参数如下:
如果有任何参数
NULL
,则返回值为
NULL
。
如果任何几何参数不是语法上格式良好的几何体,
ER_GIS_INVALID_DATA
则会发生错误。
如果任何几何参数具有引用未定义空间参考系统(SRS)的SRID值,
ER_SRS_NOT_FOUND
则会发生错误。
如果任何SRID参数不在32位无符号整数的范围内,
ER_DATA_OUT_OF_RANGE
则会发生错误。
如果任何SRID参数引用未定义的SRS,
ER_SRS_NOT_FOUND
则会发生错误。
否则,返回值为非
NULL
。
这些函数可用于获取几何属性:
返回几何值的固有尺寸
g
。
尺寸可以是-1,0,1或2.这些值的含义在
第11.5.2.2节“几何类”中给出
。
ST_Dimension()
处理其参数,如本节的介绍中所述。
MySQL的> SELECT ST_Dimension(ST_GeomFromText('LineString(1 1,2 2)'));
+ ------------------------------------------------- ----- +
| ST_Dimension(ST_GeomFromText('LineString(1 1,2 2)'))|
+ ------------------------------------------------- ----- +
| 1 |
+ ------------------------------------------------- ----- +
返回几何值的最小边界矩形(MBR)
g
。
结果将返回
Polygon
为由边界框的角点定义
的
值:
POLYGON((MINX MINY,MAXX MINY,MAXX MAXY,MINX MAXY,MINX MINY))
MySQL的> SELECT ST_AsText(ST_Envelope(ST_GeomFromText('LineString(1 1,2 2)')));
+ ------------------------------------------------- --------------- +
| ST_AsText(ST_Envelope(ST_GeomFromText('LineString(1 1,2 2)')))|
+ ------------------------------------------------- --------------- +
| POLYGON((1 1,2 1,2 2,1 2,1 1))|
+ ------------------------------------------------- --------------- +
如果参数是点或垂直或水平线段,
ST_Envelope()
返回点或线段作为其MBR,而不是返回无效多边形:
MySQL的> SELECT ST_AsText(ST_Envelope(ST_GeomFromText('LineString(1 1,1 2)')));
+ ------------------------------------------------- --------------- +
| ST_AsText(ST_Envelope(ST_GeomFromText('LineString(1 1,1 2)')))|
+ ------------------------------------------------- --------------- +
| LINESTRING(1 1,1 2)|
+ ------------------------------------------------- --------------- +
ST_Envelope()
处理其参数,如本节的介绍中所述,但有以下例外:
如果几何具有地理空间参考系统(SRS)的SRID值,
ER_NOT_IMPLEMENTED_FOR_GEOGRAPHIC_SRS
则会发生错误。
返回二进制字符串,指示几何实例所属的几何类型的名称
g
。
该名称对应于一个可实例化的
Geometry
子类。
ST_GeometryType()
处理其参数,如本节的介绍中所述。
MySQL的> SELECT ST_GeometryType(ST_GeomFromText('POINT(1 1)'));
+ ------------------------------------------------ +
| ST_GeometryType(ST_GeomFromText('POINT(1 1)'))|
+ ------------------------------------------------ +
| 要点|
+ ------------------------------------------------ +
此函数是占位符,对于空几何集合值返回1,否则返回0。
唯一有效的空几何体以空几何集合值的形式表示。
MySQL不支持GIS
EMPTY
等
POINT
EMPTY
。
ST_IsEmpty()
处理其参数,如本节的介绍中所述。
如果
g
根据ISO
SQL / MM第3部分:空间
标准
,几何值
很简单,
则返回1
。
ST_IsSimple()
如果参数不简单,则返回0。
第11.5.2节“OpenGIS几何模型”中 给出的可实例化几何类的描述 包括导致类实例被分类为不简单的特定条件。
ST_IsSimple()
处理其参数,如本节的介绍中所述,但有以下例外:
如果几何体具有经度或纬度超出范围的地理SRS,则会发生错误:
如果任何经度参数不在范围(-180,180)内,
ER_LONGITUDE_OUT_OF_RANGE
则会发生错误。
如果任何纬度参数不在[-90,90]范围内,
ER_LATITUDE_OUT_OF_RANGE
则会发生错误。
显示的范围以度为单位。 由于浮点运算,精确的范围限制略有偏差。
使用表示有效几何对象的单个参数
g
,
ST_SRID()
返回一个整数,指示与之关联的空间参考系统(SRS)的ID
g
。
使用表示有效SRID值的可选第二个参数,
ST_SRID()
返回与其第一个参数具有相同类型的对象,其SRID值等于第二个参数。
这只设置对象的SRID值;
它不执行任何坐标值的转换。
ST_SRID()
处理其参数,如本节的介绍中所述,但有以下例外:
对于单参数语法,
ST_SRID()
即使它引用未定义的SRS,也会返回几何SRID。
一个
ER_SRS_NOT_FOUND
不会发生错误。
ST_SRID(
并且
不同如下:
g
,
target_srid
)ST_Transform(
g
,
target_srid
)
ST_SRID()
更改几何SRID值而不转换其坐标。
ST_Transform()
除了更改其SRID值之外,还会转换几何坐标。
mysql>SET @g = ST_GeomFromText('LineString(1 1,2 2)', 0);
mysql>SELECT ST_SRID(@g);
+ ------------- + | ST_SRID(@g)| + ------------- + | 0 | + ------------- + mysql>SET @g = ST_SRID(@g, 4326);
mysql>SELECT ST_SRID(@g);
+ ------------- + | ST_SRID(@g)| + ------------- + | 4326 | + ------------- +
通过传递
ST_SRID()
用于创建空间值的MySQL特定函数之一的结果以及SRID值,
可以在特定SRID中创建几何
。
例如:
SET @ g1 = ST_SRID(Point(1,1),4326);
但是,该方法在SRID 0中创建几何,然后将其强制转换为SRID 4326(WGS 84)。 一个更好的选择是使用正确的空间参考系统创建几何体。 例如:
SET @ g1 = ST_PointFromText('POINT(1 1)',4326); SET @ g1 = ST_GeomFromText('POINT(1 1)',4326);
双参数形式
ST_SRID()
对于纠正或更改具有不正确SRID的几何的SRS等任务非常有用。
A
Point
由X和Y坐标组成,可以分别使用
ST_X()
和
ST_Y()
函数获得。
这些函数还允许使用可选的第二个参数来指定X或Y坐标值,在这种情况下,函数结果是
Point
来自第一个参数
的
对象,其中相应的坐标被修改为等于第二个参数。
对于
Point
具有地理空间参考系统(SRS)的对象,可以分别使用
ST_Longitude()
和
ST_Latitude()
函数
获得经度和纬度
。
这些函数还允许指定经度或纬度值的可选第二个参数,在这种情况下,函数结果是
Point
第一个参数中
的
对象,其经度或纬度被修改为等于第二个参数。
除非另有说明,否则本节中的函数处理其参数如下:
如果有任何参数
NULL
,则返回值为
NULL
。
如果任何几何参数是有效几何但不是
Point
对象,
ER_UNEXPECTED_GEOMETRY_TYPE
则会发生错误。
如果任何几何参数不是语法上格式良好的几何体,
ER_GIS_INVALID_DATA
则会发生错误。
如果任何几何参数具有引用未定义空间参考系统(SRS)的SRID值,
ER_SRS_NOT_FOUND
则会发生错误。
如果提供了一种X或Y坐标的参数和值是
-inf
,
+inf
,或
NaN
,一个
ER_DATA_OUT_OF_RANGE
发生错误。
如果经度或纬度参数超出范围,则会发生错误:
如果任何经度参数不在范围(-180,180)内,
ER_LONGITUDE_OUT_OF_RANGE
则会发生错误。
如果任何纬度参数不在[-90,90]范围内,
ER_LATITUDE_OUT_OF_RANGE
则会发生错误。
显示的范围以度为单位。 由于浮点运算,精确的范围限制略有偏差。
否则,返回值为非
NULL
。
这些函数可用于获取点属性:
ST_Latitude(
p
[, new_latitude_val
])
使用表示
具有地理空间参照系(SRS)
的有效
Point
对象
的单个参数
p
,
ST_Latitude()
将纬度值
p
作为双精度数返回。
使用表示有效纬度值的可选第二个参数,
ST_Latitude()
返回一个
Point
对象,如第一个参数,其纬度等于第二个参数。
ST_Latitude()
处理其参数,如本节的介绍中所述,另外如果
Point
对象有效但没有地理SRS,
ER_SRS_NOT_GEOGRAPHIC
则会发生错误。
mysql>SET @pt = ST_GeomFromText('POINT(45 90)', 4326);
mysql>SELECT ST_Latitude(@pt);
+ ------------------ + | ST_Latitude(@pt)| + ------------------ + | 45 | + ------------------ + MySQL的>SELECT ST_AsText(ST_Latitude(@pt, 10));
+ --------------------------------- + | ST_AsText(ST_Latitude(@ ct,10))| + --------------------------------- + | 要点(10 90)| + --------------------------------- +
此功能已在MySQL 8.0.12中添加。
ST_Longitude(
p
[, new_longitude_val
])
使用表示
具有地理空间参照系(SRS)
的有效
Point
对象
的单个参数
p
,
ST_Longitude()
将经度值
p
作为双精度数返回。
使用表示有效经度值的可选第二个参数,
ST_Longitude()
返回一个
Point
对象,如第一个参数,其经度等于第二个参数。
ST_Longitude()
处理其参数,如本节的介绍中所述,另外如果
Point
对象有效但没有地理SRS,
ER_SRS_NOT_GEOGRAPHIC
则会发生错误。
mysql>SET @pt = ST_GeomFromText('POINT(45 90)', 4326);
mysql>SELECT ST_Longitude(@pt);
+ ------------------- + | ST_Longitude(@pt)| + ------------------- + | 90 | + ------------------- + MySQL的>SELECT ST_AsText(ST_Longitude(@pt, 10));
+ ---------------------------------- + | ST_AsText(ST_Longitude(@pt,10))| + ---------------------------------- + | 要点(45 10)| + ---------------------------------- +
此功能已在MySQL 8.0.12中添加。
使用表示有效
Point
对象
的单个参数
p
,
ST_X()
将X坐标值
p
作为双精度数返回。
从MySQL 8.0.12开始,X坐标被认为是指
Point
空间参照系(SRS)定义
中首先出现的轴
。
使用可选的第二个参数,
ST_X()
返回一个
Point
对象,如第一个参数,其X坐标等于第二个参数。
从MySQL 8.0.12开始,如果
Point
对象具有地理SRS,则第二个参数必须在经度或纬度值的适当范围内。
ST_X()
处理其参数,如本节的介绍中所述。
MySQL的>SELECT ST_X(Point(56.7, 53.34));
+ -------------------------- + | ST_X(Point(56.7,53.34))| + -------------------------- + | 56.7 | + -------------------------- + MySQL的>SELECT ST_AsText(ST_X(Point(56.7, 53.34), 10.5));
+ ------------------------------------------- + | ST_AsText(ST_X(Point(56.7,53.34),10.5))| + ------------------------------------------- + | 要点(10.5 53.34)| + ------------------------------------------- +
使用表示有效
Point
对象
的单个参数
p
,
ST_Y()
将Y坐标值
p
作为双精度数返回。
从MySQL 8.0.12开始,Y坐标被认为是指
Point
空间参照系(SRS)定义
中第二个出现的轴
。
使用可选的第二个参数,
ST_Y()
返回一个
Point
对象,如第一个参数,其Y坐标等于第二个参数。
从MySQL 8.0.12开始,如果
Point
对象具有地理SRS,则第二个参数必须在经度或纬度值的适当范围内。
ST_Y()
处理其参数,如本节的介绍中所述。
MySQL的>SELECT ST_Y(Point(56.7, 53.34));
+ -------------------------- + | ST_Y(Point(56.7,53.34))| + -------------------------- + | 53.34 | + -------------------------- + MySQL的>SELECT ST_AsText(ST_Y(Point(56.7, 53.34), 10.5));
+ ------------------------------------------- + | ST_AsText(ST_Y(Point(56.7,53.34),10.5))| + ------------------------------------------- + | 要点(56.7 10.5)| + ------------------------------------------- +
A
LineString
由
Point
值
组成
。
您可以提取a的特定点
LineString
,计算它包含的点数或获取其长度。
本节中的某些功能也适用于
MultiLineString
值。
除非另有说明,否则本节中的函数处理其参数如下:
如果任何参数是
NULL
或任何几何参数是空几何,则返回值为
NULL
。
如果任何几何参数不是语法上格式良好的几何体,
ER_GIS_INVALID_DATA
则会发生错误。
如果任何几何参数具有引用未定义空间参考系统(SRS)的SRID值,
ER_SRS_NOT_FOUND
则会发生错误。
否则,返回值为非
NULL
。
这些函数可用于获取线串属性:
返回
Point
该
LineString
值
的端点
ls
。
ST_EndPoint()
处理其参数,如本节的介绍中所述。
mysql>SET @ls = 'LineString(1 1,2 2,3 3)';
mysql>SELECT ST_AsText(ST_EndPoint(ST_GeomFromText(@ls)));
+ ---------------------------------------------- + | ST_AsText(ST_EndPoint(ST_GeomFromText(@ls)))| + ---------------------------------------------- + | 要点(3 3)| + ---------------------------------------------- +
对于
LineString
值
ls
,
ST_IsClosed()
如果
ls
关闭
则返回1
(即,它
ST_StartPoint()
和
ST_EndPoint()
值相同)。
对于一个
MultiLineString
值
ls
,
ST_IsClosed()
则返回1,如果
ls
是封闭的(即,
ST_StartPoint()
和
ST_EndPoint()
值是彼此相同
LineString
的
ls
)。
ST_IsClosed()
如果返回0
ls
是不封闭的,而
NULL
如果
ls
是
NULL
。
ST_IsClosed()
处理其参数,如本节的介绍中所述,但有以下例外:
如果几何具有地理空间参考系统(SRS)的SRID值,
ER_NOT_IMPLEMENTED_FOR_GEOGRAPHIC_SRS
则会发生错误。
mysql>SET @ls1 = 'LineString(1 1,2 2,3 3,2 2)';
mysql>SET @ls2 = 'LineString(1 1,2 2,3 3,1 1)';
MySQL的>SELECT ST_IsClosed(ST_GeomFromText(@ls1));
+ ------------------------------------ + | ST_IsClosed(ST_GeomFromText(@ ls1))| + ------------------------------------ + | 0 | + ------------------------------------ + MySQL的>SELECT ST_IsClosed(ST_GeomFromText(@ls2));
+ ------------------------------------ + | ST_IsClosed(ST_GeomFromText(@ ls2))| + ------------------------------------ + | 1 | + ------------------------------------ + MySQL的>SET @ls3 = 'MultiLineString((1 1,2 2,3 3),(4 4,5 5))';
MySQL的>SELECT ST_IsClosed(ST_GeomFromText(@ls3));
+ ------------------------------------ + | ST_IsClosed(ST_GeomFromText(@ ls3))| + ------------------------------------ + | 0 | + ------------------------------------ +
返回一个双精度数字,表示
其关联空间参照系
中的
LineString
或
MultiLineString
值
的长度
ls
。
MultiLineString
值
的长度
等于其元素长度的总和。
ST_Length()
计算结果如下:
如果几何
LineString
在笛卡尔SRS中
有效
,则返回值是几何的笛卡尔长度。
如果几何
MultiLineString
在笛卡尔SRS
中是有效的
,则返回值是其元素的笛卡尔长度的总和。
如果几何
LineString
在地理SRS中
有效
,则返回值是该SRS中几何的大地长度(以米为单位)。
如果几何
MultiLineString
在地理SRS中
有效
,则返回值是该SRS中其元素的大地长度之和(以米为单位)。
ST_Length()
处理其参数,如本节的介绍中所述,但有以下例外:
如果几何不是
LineString
或者
MultiLineString
,返回值是
NULL
。
如果几何在几何上无效,则结果是未定义的长度(即,它可以是任何数字),或者发生错误。
如果长度计算结果是
+inf
,则发生
ER_DATA_OUT_OF_RANGE
错误。
如果几何体具有经度或纬度超出范围的地理SRS,则会发生错误:
如果任何经度参数不在范围(-180,180)内,
ER_LONGITUDE_OUT_OF_RANGE
则会发生错误。
如果任何纬度参数不在[-90,90]范围内,
ER_LATITUDE_OUT_OF_RANGE
则会发生错误。
显示的范围以度为单位。 由于浮点运算,精确的范围限制略有偏差。
从MySQL 8.0.16开始,
ST_Length()
允许使用可选
unit
参数来指定返回长度值的线性单位。
这些规则适用于:
如果指定了单元但MySQL不支持,
ER_UNIT_NOT_FOUND
则会发生错误。
如果指定了支持的线性单位且SRID为0,
ER_GEOMETRY_IN_UNKNOWN_LENGTH_UNIT
则会发生错误。
如果指定了受支持的线性单位且SRID不为0,则结果为该单位。
如果未指定单位,则结果以几何的SRS为单位,无论是笛卡尔坐标还是地理坐标。 目前,所有MySQL SRS都以米为单位表示。
如果在
INFORMATION_SCHEMA
ST_UNITS_OF_MEASURE
表中
找到,则支持单位
。
请参见
第25.29节“INFORMATION_SCHEMA ST_UNITS_OF_MEASURE表”
。
mysql>SET @ls = ST_GeomFromText('LineString(1 1,2 2,3 3)');
mysql>SELECT ST_Length(@ls);
+ -------------------- + | ST_Length(@ls)| + -------------------- + | 2.8284271247461903 | + -------------------- + mysql>SET @mls = ST_GeomFromText('MultiLineString((1 1,2 2,3 3),(4 4,5 5))');
mysql>SELECT ST_Length(@mls);
+ ------------------- + | ST_Length(@mls)| + ------------------- + | 4.242640687119286 | + ------------------- + mysql>SET @ls = ST_GeomFromText('LineString(1 1,2 2,3 3)', 4326);
mysql>SELECT ST_Length(@ls);
+ ------------------- + | ST_Length(@ls)| + ------------------- + | 313701.9623204328 | + ------------------- + MySQL的>SELECT ST_Length(@ls, 'metre');
+ ------------------------- + | ST_Length(@ls,'meter')| + ------------------------- + | 313701.9623204328 | + ------------------------- + MySQL的>SELECT ST_Length(@ls, 'foot');
+ ------------------------ + | ST_Length(@ls,'foot')| + ------------------------ + | 1029205.9131247795 | + ------------------------ +
返回的数量
Point
中的对象
LineString
值
ls
。
ST_NumPoints()
处理其参数,如本节的介绍中所述。
mysql>SET @ls = 'LineString(1 1,2 2,3 3)';
mysql>SELECT ST_NumPoints(ST_GeomFromText(@ls));
+ ------------------------------------ + | ST_NumPoints(ST_GeomFromText(@ls))| + ------------------------------------ + | 3 | + ------------------------------------ +
返回
N
个
Point
中
Linestring
值
ls
。
点数从1开始编号。
ST_PointN()
处理其参数,如本节的介绍中所述。
mysql>SET @ls = 'LineString(1 1,2 2,3 3)';
mysql>SELECT ST_AsText(ST_PointN(ST_GeomFromText(@ls),2));
+ ---------------------------------------------- + | ST_AsText(ST_PointN(ST_GeomFromText(@ls),2))| + ---------------------------------------------- + | 要点(2 2)| + ---------------------------------------------- +
返回
Point
那是的起点
LineString
值
ls
。
ST_StartPoint()
处理其参数,如本节的介绍中所述。
mysql>SET @ls = 'LineString(1 1,2 2,3 3)';
mysql>SELECT ST_AsText(ST_StartPoint(ST_GeomFromText(@ls)));
+ ------------------------------------------------ + | ST_AsText(ST_StartPoint(ST_GeomFromText(@ls)))| + ------------------------------------------------ + | 要点(1 1)| + ------------------------------------------------ +
本节中的函数返回属性
Polygon
或
MultiPolygon
值。
除非另有说明,否则本节中的函数处理其参数如下:
如果任何参数是
NULL
或任何几何参数是空几何,则返回值为
NULL
。
如果任何几何参数不是语法上格式良好的几何体,
ER_GIS_INVALID_DATA
则会发生错误。
如果任何几何参数具有引用未定义空间参考系统(SRS)的SRID值,
ER_SRS_NOT_FOUND
则会发生错误。
对于采用多个几何参数的函数,如果这些参数不具有相同的SRID,
ER_GIS_DIFFERENT_SRIDS
则会发生错误。
否则,返回值为非
NULL
。
这些函数可用于获取多边形属性:
返回一个双精度数字,表示
在其空间参照系中测量
的
Polygon
或
MultiPolygon
参数
的区域
。
从MySQL 8.0.13开始,
ST_Area()
按照本节的介绍中的描述处理其参数,但有以下例外:
如果几何在几何上无效,则结果是未定义区域(即,它可以是任何数字),或者发生错误。
如果几何有效但不是
Polygon
或
MultiPolygon
对象,
ER_UNEXPECTED_GEOMETRY_TYPE
则会发生错误。
如果几何
Polygon
在笛卡尔SRS
中是有效的
,则结果是多边形的笛卡尔区域。
如果几何
MultiPolygon
在笛卡尔SRS
中是有效的
,则结果是多边形的笛卡尔面积的总和。
如果几何
Polygon
在地理SRS中
有效
,则结果是该SRS中多边形的大地测量区域,以平方米为单位。
如果几何
MultiPolygon
在地理SRS中
有效
,则结果是该SRS中多边形的大地面积总和,以平方米为单位。
如果导致区域计算
+inf
,则发生
ER_DATA_OUT_OF_RANGE
错误。
如果几何体具有经度或纬度超出范围的地理SRS,则会发生错误:
如果任何经度参数不在范围(-180,180)内,
ER_LONGITUDE_OUT_OF_RANGE
则会发生错误。
如果任何纬度参数不在[-90,90]范围内,
ER_LATITUDE_OUT_OF_RANGE
则会发生错误。
显示的范围以度为单位。 由于浮点运算,精确的范围限制略有偏差。
在MySQL 8.0.13之前,
ST_Area()
按照本节的介绍中的描述处理其参数,但有以下例外:
对于维度0或1的参数,结果为0。
如果几何为空,则返回值为0而不是
NULL
。
对于几何集合,结果是所有组件的面积值的总和。 如果几何集合为空,则其区域返回为0。
如果几何具有地理空间参考系统(SRS)的SRID值,
ER_NOT_IMPLEMENTED_FOR_GEOGRAPHIC_SRS
则会发生错误。
mysql> mysql>SET @poly =
'Polygon((0 0,0 3,3 0,0 0),(1 1,1 2,2 1,1 1))';
SELECT ST_Area(ST_GeomFromText(@poly));
+ --------------------------------- + | ST_Area(ST_GeomFromText(@poly))| + --------------------------------- + | 4 | + --------------------------------- + mysql> mysql>SET @mpoly =
'MultiPolygon(((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1)))';
SELECT ST_Area(ST_GeomFromText(@mpoly));
+ ---------------------------------- + | ST_Area(ST_GeomFromText(@mpoly))| + ---------------------------------- + | 8 | + ---------------------------------- +
返回
Polygon
或
MultiPolygon
参数
的数学质心
作为
Point
。
结果不能保证在
MultiPolygon
。
此函数通过计算集合中最高维度的组件的质心点来处理几何集合。
这样的成分被提取并制作成单个
MultiPolygon
,
MultiLineString
或
MultiPoint
为质心计算。
ST_Centroid()
处理其参数,如本节的介绍中所述,但有以下例外:
返回值是
NULL
参数为空几何集合的附加条件。
如果几何具有地理空间参考系统(SRS)的SRID值,
ER_NOT_IMPLEMENTED_FOR_GEOGRAPHIC_SRS
则会发生错误。
mysql> mysql>SET @poly =
ST_GeomFromText('POLYGON((0 0,10 0,10 10,0 10,0 0),(5 5,7 5,7 7,5 7,5 5))');
SELECT ST_GeometryType(@poly),ST_AsText(ST_Centroid(@poly));
+ ------------------------ + ------------------------ -------------------- + | ST_GeometryType(@poly)| ST_AsText(ST_Centroid(@poly))| + ------------------------ + ------------------------ -------------------- + | POLYGON | 要点(4.958333333333333 4.958333333333333)| + ------------------------ + ------------------------ -------------------- +
返回
Polygon
值的
外环
poly
作为a
LineString
。
ST_ExteriorRing()
处理其参数,如本节的介绍中所述。
mysql> mysql>SET @poly =
'Polygon((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1))';
SELECT ST_AsText(ST_ExteriorRing(ST_GeomFromText(@poly)));
+ ------------------------------------------------- --- + | ST_AsText(ST_ExteriorRing(ST_GeomFromText(@ poly)))| + ------------------------------------------------- --- + | LINESTRING(0 0,0 3,3 3,3 0,0 0)| + ------------------------------------------------- --- +
返回
N
了个内环
Polygon
值
poly
作为
LineString
。
戒指从1开始编号。
ST_InteriorRingN()
处理其参数,如本节的介绍中所述。
mysql> mysql>SET @poly =
'Polygon((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1))';
SELECT ST_AsText(ST_InteriorRingN(ST_GeomFromText(@poly),1));
+ ------------------------------------------------- ------ + | ST_AsText(ST_InteriorRingN(ST_GeomFromText(@ poly),1))| + ------------------------------------------------- ------ + | LINESTRING(1 1,1 2,2 2,2 1,1 1)| + ------------------------------------------------- ------ +
ST_NumInteriorRing(
,
poly
)ST_NumInteriorRings(
poly
)
返回内部环的数量
Polygon
值
poly
。
ST_NumInteriorRing()
和
ST_NuminteriorRings()
按照本节的介绍中的描述处理它们的参数。
mysql> mysql>SET @poly =
'Polygon((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1))';
SELECT ST_NumInteriorRings(ST_GeomFromText(@poly));
+ --------------------------------------------- + | ST_NumInteriorRings(ST_GeomFromText(@poly))| + --------------------------------------------- + | 1 | + --------------------------------------------- +
这些函数返回
GeometryCollection
值的
属性
。
除非另有说明,否则本节中的函数处理其参数如下:
如果任何参数是
NULL
或任何几何参数是空几何,则返回值为
NULL
。
如果任何几何参数不是语法上格式良好的几何体,
ER_GIS_INVALID_DATA
则会发生错误。
如果任何几何参数具有引用未定义空间参考系统(SRS)的SRID值,
ER_SRS_NOT_FOUND
则会发生错误。
否则,返回值为非
NULL
。
这些函数可用于获取几何集合属性:
返回
值
中的
N
第th个几何
。
几何图形从1开始编号。
GeometryCollection
gc
ST_GeometryN()
处理其参数,如本节的介绍中所述。
mysql>SET @gc = 'GeometryCollection(Point(1 1),LineString(2 2, 3 3))';
mysql>SELECT ST_AsText(ST_GeometryN(ST_GeomFromText(@gc),1));
+ ------------------------------------------------- + | ST_AsText(ST_GeometryN(ST_GeomFromText(@gc),1))| + ------------------------------------------------- + | 要点(1 1)| + ------------------------------------------------- +
返回几何数量
GeometryCollection
值
gc
。
ST_NumGeometries()
处理其参数,如本节的介绍中所述。
mysql>SET @gc = 'GeometryCollection(Point(1 1),LineString(2 2, 3 3))';
mysql>SELECT ST_NumGeometries(ST_GeomFromText(@gc));
+ ---------------------------------------- + | ST_NumGeometries(ST_GeomFromText(@gc))| + ---------------------------------------- + | 2 | + ---------------------------------------- +
OpenGIS提出了许多可以生成几何的函数。 它们旨在实现空间运算符。
这些函数支持所有参数类型组合,但根据 Open Geospatial Consortium 规范 不适用的参数类型组合除外 。
除非另有说明,否则本节中的函数处理其参数如下:
如果有任何参数
NULL
,则返回值为
NULL
。
如果任何几何参数不是语法上格式良好的几何体,
ER_GIS_INVALID_DATA
则会发生错误。
如果任何几何参数具有引用未定义空间参考系统(SRS)的SRID值,
ER_SRS_NOT_FOUND
则会发生错误。
对于采用多个几何参数的函数,如果这些参数不具有相同的SRID,
ER_GIS_DIFFERENT_SRIDS
则会发生错误。
如果任何geometry参数具有地理SRS的SRID值,
ER_NOT_IMPLEMENTED_FOR_GEOGRAPHIC_SRS
则会发生错误。
否则,返回值为非
NULL
。
这些空间操作员功能可用:
ST_Buffer(
g
,
d
[,
strategy1
[,
strategy2
[,
strategy3
]]])
返回一个几何图形,表示距几何体值的距离
g
小于或等于距离的
所有点
d
。
如果geometry参数为空,则
ST_Buffer()
返回空几何。
如果距离为0,则
ST_Buffer()
返回几何参数不变:
mysql>SET @pt = ST_GeomFromText('POINT(0 0)');
mysql>SELECT ST_AsText(ST_Buffer(@pt, 0));
+ ------------------------------ + | ST_AsText(ST_Buffer(@pt,0))| + ------------------------------ + | POINT(0 0)| + ------------------------------ +
ST_Buffer()
支持负距离
Polygon
和
MultiPolygon
值,以及包含
Polygon
或
MultiPolygon
值的
几何集合
。
结果可能是空几何。
ST_Buffer()
在distance参数后最多允许三个可选的策略参数。
策略影响缓冲计算。
这些参数是
ST_Buffer_Strategy()
函数
生成的字节字符串值
,用于点,连接和结束策略:
点策略适用于
Point
和
MultiPoint
几何。
如果未指定点策略,则默认为
ST_Buffer_Strategy('point_circle',
32)
。
加入策略适用于
LineString
,
MultiLineString
,
Polygon
,和
MultiPolygon
几何形状。
如果未指定连接策略,则默认为
ST_Buffer_Strategy('join_round',
32)
。
最终策略适用于
LineString
和
MultiLineString
几何。
如果未指定结束策略,则默认为
ST_Buffer_Strategy('end_round',
32)
。
可以指定每种类型的最多一种策略,并且可以以任何顺序给出它们。
ST_Buffer()
处理其参数,如本节的介绍中所述,但有以下例外:
用于为负的距离
Point
,
MultiPoint
,
LineString
,和
MultiLineString
的值,而对于不包含任何几何形状的集合
Polygon
或
MultiPolygon
值时,
ER_WRONG_ARGUMENTS
会出现误差。
如果指定了给定类型的多个策略,
ER_WRONG_ARGUMENTS
则会发生错误。
mysql>SET @pt = ST_GeomFromText('POINT(0 0)');
mysql>SET @pt_strategy = ST_Buffer_Strategy('point_square');
mysql>SELECT ST_AsText(ST_Buffer(@pt, 2, @pt_strategy));
+ -------------------------------------------- + | ST_AsText(ST_Buffer(@pt,2,@ ts_strategy))| + -------------------------------------------- + | POLYGON(( - 2 -2,2 -2,2 2,-2 2,-2 -2))| + -------------------------------------------- +
mysql>SET @ls = ST_GeomFromText('LINESTRING(0 0,0 5,5 5)');
mysql>SET @end_strategy = ST_Buffer_Strategy('end_flat');
mysql>SET @join_strategy = ST_Buffer_Strategy('join_round', 10);
mysql>SELECT ST_AsText(ST_Buffer(@ls, 5, @end_strategy, @join_strategy))
+ ------------------------------------------------- -------------- + | ST_AsText(ST_Buffer(@ls,5,@ end_strategy,@ join_strategy))| + ------------------------------------------------- -------------- + | POLYGON((5 5,5 10,0 10,-3.5355339059327373 8.535533905932738,| | -5 5,-5 0,0 0,5 0,5 5))| + ------------------------------------------------- -------------- +
ST_Buffer_Strategy(
strategy
[,
points_per_circle
])
此函数返回一个策略字节字符串,用于
ST_Buffer()
影响缓冲区计算。
有关策略的信息,请访问 Boost.org 。
第一个参数必须是指示策略选项的字符串:
对于点策略,允许的值是
'point_circle'
和
'point_square'
。
对于连接策略,允许的值是
'join_round'
和
'join_miter'
。
对于最终策略,允许的值是
'end_round'
和
'end_flat'
。
如果第一个参数是
'point_circle'
,
'join_round'
,
'join_miter'
,或
'end_round'
,该
points_per_circle
参数必须被给定为正的数值。
最大值
points_per_circle
是
max_points_in_geometry
系统变量
的值
。
有关示例,请参阅说明
ST_Buffer()
。
ST_Buffer_Strategy()
处理其参数,如本节的介绍中所述,但有以下例外:
如果任何参数无效,
ER_WRONG_ARGUMENTS
则会发生错误。
如果第一个参数是
'point_square'
或
'end_flat'
,则
points_per_circle
不能给出参数或发生
ER_WRONG_ARGUMENTS
错误。
返回表示几何值的凸包的几何
g
。
此函数通过首先检查其顶点是否为共线来计算几何体的凸包。
如果是这样,该函数返回一个线性外壳,否则返回一个多边形外壳。
此函数通过提取集合的所有组件的所有顶点,
MultiPoint
从中
创建
值以及计算其凸包来
处理几何集合
。
ST_ConvexHull()
处理其参数,如本节的介绍中所述,但有以下例外:
返回值是
NULL
参数为空几何集合的附加条件。
mysql>SET @g = 'MULTIPOINT(5 0,25 0,15 10,15 25)';
mysql>SELECT ST_AsText(ST_ConvexHull(ST_GeomFromText(@g)));
+ ----------------------------------------------- + | ST_AsText(ST_ConvexHull(ST_GeomFromText(@g)))| + ----------------------------------------------- + | POLYGON((5 0,25 0,15 25,5 0))| + ----------------------------------------------- +
返回表示几何值的点集差异的几何形状
g1
和
g2
。
ST_Difference()
处理其参数,如本节的介绍中所述。
mysql>SET @g1 = Point(1,1), @g2 = Point(2,2);
mysql>SELECT ST_AsText(ST_Difference(@g1, @g2));
+ ------------------------------------ + | ST_AsText(ST_Difference(@ g1,@ g2))| + ------------------------------------ + | 要点(1 1)| + ------------------------------------ +
返回表示几何值的点交集的几何形状
g1
和
g2
。
ST_Intersection()
处理其参数,如本节的介绍中所述。
mysql>SET @g1 = ST_GeomFromText('LineString(1 1, 3 3)');
mysql>SET @g2 = ST_GeomFromText('LineString(1 3, 3 1)');
mysql>SELECT ST_AsText(ST_Intersection(@g1, @g2));
+ -------------------------------------- + | ST_AsText(ST_Intersection(@ g1,@ g2))| + -------------------------------------- + | 要点(2 2)| + -------------------------------------- +
返回表示设置的几何值的对称差的点的几何形状
g1
和
g2
,其被定义为:
g1
symdifferenceg2
:=(g1
联合g2
)差异(g1
交集g2
)
或者,在函数调用表示法中:
ST_SymDifference(g1
,g2
)= ST_Difference(ST_Union(g1
,g2
),ST_Intersection(g1
,g2
))
ST_SymDifference()
处理其参数,如本节的介绍中所述。
mysql>SET @g1 = Point(1,1), @g2 = Point(2,2);
mysql>SELECT ST_AsText(ST_SymDifference(@g1, @g2));
+ --------------------------------------- + | ST_AsText(ST_SymDifference(@ g1,@ g2))| + --------------------------------------- + | MULTIPOINT((1 1),(2 2))| + --------------------------------------- +
将几何体从一个空间参照系(SRS)转换为另一个。
返回值是与输入几何体相同类型的几何体,所有坐标都转换为目标SRID ,
target_srid
.
转换支持仅限于地理SRS,除非geometry参数的SRID与目标SRID值相同,在这种情况下,返回值是任何有效SRS的输入几何。
ST_Transform()
处理其参数,如本节的介绍中所述,但有以下例外:
具有地理SRS的SRID值的几何参数不会产生错误。
如果几何或目标SRID参数具有引用未定义空间参考系统(SRS)的SRID值,
ER_SRS_NOT_FOUND
则会发生错误。
如果几何体位于
ST_Transform()
无法转换
的SRS中,
ER_TRANSFORM_SOURCE_SRS_NOT_SUPPORTED
则会发生错误。
如果目标SRID位于
ST_Transform()
无法转换为
的SRS中,
ER_TRANSFORM_TARGET_SRS_NOT_SUPPORTED
则会发生错误。
如果几何体位于不是WGS 84且没有TOWGS84子句的SRS中,
ER_TRANSFORM_SOURCE_SRS_MISSING_TOWGS84
则会发生错误。
如果目标SRID位于不是WGS 84且没有TOWGS84子句的SRS中,
ER_TRANSFORM_TARGET_SRS_MISSING_TOWGS84
则会发生错误。
ST_SRID(
并且
不同如下:
g
,
target_srid
)ST_Transform(
g
,
target_srid
)
ST_SRID()
更改几何SRID值而不转换其坐标。
ST_Transform()
除了更改其SRID值之外,还会转换几何坐标。
mysql>SET @p = ST_GeomFromText('POINT(52.381389 13.064444)', 4326);
mysql>SELECT ST_AsText(@p);
+ ---------------------------- + | ST_AsText(@p)| + ---------------------------- + | 要点(52.381389 13.064444)| + ---------------------------- + mysql>SET @p = ST_Transform(@p, 4230);
mysql>SELECT ST_AsText(@p);
+ --------------------------------------------- + | ST_AsText(@p)| + --------------------------------------------- + | 要点(52.38208611407426 13.065520672345304)| + --------------------------------------------- +
返回表示几何值的点集联合的几何形状
g1
和
g2
。
ST_Union()
处理其参数,如本节的介绍中所述。
mysql>SET @g1 = ST_GeomFromText('LineString(1 1, 3 3)');
mysql>SET @g2 = ST_GeomFromText('LineString(1 3, 3 1)');
mysql>SELECT ST_AsText(ST_Union(@g1, @g2));
+ -------------------------------------- + | ST_AsText(ST_Union(@ g1,@ g2))| + -------------------------------------- + | MULTILINESTRING((1 1,3 3),(1 3,3 1))| + -------------------------------------- +
此外, 第12.16.7节“几何属性函数” 讨论了从现有几何构造新几何的几个函数。 有关这些功能的说明,请参阅该部分:
本节中描述的函数将两个几何作为参数,并返回它们之间的定性或定量关系。
MySQL使用OpenGIS规范定义的函数名实现两组函数。 一组使用精确的对象形状测试两个几何值之间的关系,另一组使用对象最小边界矩形(MBR)。
OpenGIS规范定义了以下函数来测试两个几何值之间的关系,
g1
并
g2
使用精确的对象形状。
返回值1和0分别表示true和false,除了
ST_Distance()
返回距离值。
本节中的函数检测笛卡尔或地理空间参照系(SRS)中的参数,并返回适合SRS的结果。
除非另有说明,否则本节中的函数处理其参数如下:
如果任何参数是
NULL
或任何几何参数是空几何,则返回值为
NULL
。
如果任何几何参数不是语法上格式良好的几何体,
ER_GIS_INVALID_DATA
则会发生错误。
如果任何几何参数引用未定义的空间参考系统(SRS),
ER_SRS_NOT_FOUND
则会发生错误。
对于采用多个几何参数的函数,如果这些参数不具有相同的SRID,
ER_GIS_DIFFERENT_SRIDS
则会发生错误。
如果任何几何参数在几何上无效,则结果为true或false(未定义哪个),或者发生错误。
对于地理SRS几何参数,如果任何参数的经度或纬度超出范围,则会发生错误:
如果经度值不在范围(-180,180)内,
ER_LONGITUDE_OUT_OF_RANGE
则会发生错误。
如果纬度值不在[-90,90]范围内,
ER_LATITUDE_OUT_OF_RANGE
则会发生错误。
显示的范围以度为单位。 如果SRS使用其他单位,则该范围使用其单位中的相应值。 由于浮点运算,精确的范围限制略有偏差。
否则,返回值为非
NULL
。
这些对象形状函数可用于测试几何关系:
返回1或0以指示是否
g1
完全包含
g2
。
这测试了相反的关系
ST_Within()
。
ST_Contains()
处理其参数,如本节的介绍中所述。
如果空间关系具有以下属性,则 两个几何在 空间上交叉 :
除非
g1
并且
g2
都是尺寸1:
如果内部的内部
具有与内部相同
但
不覆盖整个内部的
g1
十字形
。
g2
g2
g1
g2
g1
如果两个
g1
和
g2
是尺寸1的:如果线彼此交叉在一个有限数目的点(即,没有共同的线段,仅在普通的单点)。
此函数返回1或0以指示是否在
g1
空间上交叉
g2
。
ST_Crosses()
处理其参数,如本节前言中所述,但返回值是
NULL
针对以下附加条件:
g1
是2(
Polygon
或
MultiPolygon
)
维度
。
g2
是维度1(
Point
或
MultiPoint
)。
返回1或0以指示是否
g1
在空间上不相交(不相交)
g2
。
ST_Disjoint()
处理其参数,如本节的介绍中所述。
返回
几何参数的空间参照系(SRS)的长度单位
g1
和
之间的距离
g2
,
unit
如果指定
,则以可选
参数
为单位
。
此函数通过返回两个几何参数的所有组件组合中的最短距离来处理几何集合。
ST_Distance()
处理其几何参数,如本节前言中所述,但有以下例外:
ST_Distance()
检测地理(椭圆体)空间参照系中的参数,并返回椭圆体上的测地距离。
唯一允许的地理参数类型是
Point
和
Point
,或
Point
和
MultiPoint
(在任何参数顺序)。
如果在地理SRS中使用其他几何类型参数组合调用,
ER_NOT_IMPLEMENTED_FOR_GEOGRAPHIC_SRS
则会发生错误。
如果任何参数在几何上无效,则结果是未定义的距离(即,它可以是任何数字),或者发生错误。
如果中间或最终结果产生
NaN
或为负数,
ER_GIS_INVALID_DATA
则会发生错误。
从MySQL 8.0.14开始,
ST_Distance()
允许使用可选
unit
参数来指定返回距离值的线性单位。
这些规则适用于:
如果指定了单元但MySQL不支持,
ER_UNIT_NOT_FOUND
则会发生错误。
如果指定了支持的线性单位且SRID为0,
ER_GEOMETRY_IN_UNKNOWN_LENGTH_UNIT
则会发生错误。
如果指定了受支持的线性单位且SRID不为0,则结果为该单位。
如果未指定单位,则结果以几何的SRS为单位,无论是笛卡尔坐标还是地理坐标。 目前,所有MySQL SRS都以米为单位表示。
如果在
INFORMATION_SCHEMA
ST_UNITS_OF_MEASURE
表中
找到,则支持单位
。
请参见
第25.29节“INFORMATION_SCHEMA ST_UNITS_OF_MEASURE表”
。
mysql>SET @g1 = Point(1,1);
mysql>SET @g2 = Point(2,2);
mysql>SELECT ST_Distance(@g1, @g2);
+ ----------------------- + | ST_Distance(@ g1,@ g2)| + ----------------------- + | 1.4142135623730951 | + ----------------------- + mysql>SET @g1 = ST_GeomFromText('POINT(1 1)', 4326);
mysql>SET @g2 = ST_GeomFromText('POINT(2 2)', 4326);
mysql>SELECT ST_Distance(@g1, @g2);
+ ----------------------- + | ST_Distance(@ g1,@ g2)| + ----------------------- + | 156874.3859490455 | + ----------------------- + MySQL的>SELECT ST_Distance(@g1, @g2, 'metre');
+ -------------------------------- + | ST_Distance(@ g1,@ g2,'meter')| + -------------------------------- + | 156874.3859490455 | + -------------------------------- + MySQL的>SELECT ST_Distance(@g1, @g2, 'foot');
+ ------------------------------- + | ST_Distance(@ g1,@ g2,'foot')| + ------------------------------- + | 514679.7439273146 | + ------------------------------- +
有关球体上距离计算的特殊情况,请参阅该
ST_Distance_Sphere()
函数。
返回1或0以指示是否
g1
在空间上等于
g2
。
ST_Equals()
处理其参数,如本节的介绍中所述,除了它不返回
NULL
空几何参数。
mysql>SET @g1 = Point(1,1), @g2 = Point(2,2);
mysql>SELECT ST_Equals(@g1, @g1), ST_Equals(@g1, @g2);
+ --------------------- + --------------------- + | ST_Equals(@ g1,@ g1)| ST_Equals(@ g1,@ g2)| + --------------------- + --------------------- + | 1 | 0 | + --------------------- + --------------------- +
返回1或0以指示是否在
g1
空间上相交
g2
。
ST_Intersects()
处理其参数,如本节的介绍中所述。
如果它们相交,则 两个几何在 空间上重叠 ,并且它们的交点产生相同尺寸的几何形状但不等于给定几何形状中的任何一个。
此函数返回1或0以指示是否在
g1
空间上重叠
g2
。
ST_Overlaps()
处理其参数,如本节的介绍中所述,除了返回值是
NULL
针对两个几何的尺寸不相等的附加条件。
如果它们的内部不相交,则 两个几何在 空间上接触 ,但是一个几何的边界与另一个的边界或内部相交。
此函数返回1或0以指示是否在
g1
空间上接触
g2
。
ST_Touches()
处理其参数,如本节的介绍中所述,除了返回值是
NULL
针对两个几何都是维度0(
Point
或
MultiPoint
)
的附加条件
。
返回1或0以指示是否
g1
在空间内
g2
。
这测试了相反的关系
ST_Contains()
。
ST_Within()
处理其参数,如本节的介绍中所述。
MySQL提供用于测试最小外接矩形两个几何的(MBR)的之间的关系几个MySQL特定功能
g1
和
g2
。
返回值1和0分别表示true和false。
点的边界框被解释为边界和内部的点。
直水平或垂直线的边界框被解释为线的内部也是边界的线。 端点是边界点。
如果任何参数是几何集合,则这些参数的内部,边界和外部是集合中所有元素的并集的参数。
本节中的函数检测笛卡尔或地理空间参照系(SRS)中的参数,并返回适合SRS的结果。
除非另有说明,否则本节中的函数处理其参数如下:
如果有任何参数
NULL
或是空几何,则返回值为
NULL
。
如果任何几何参数不是语法上格式良好的几何体,
ER_GIS_INVALID_DATA
则会发生错误。
如果任何几何参数引用未定义的空间参考系统(SRS),
ER_SRS_NOT_FOUND
则会发生错误。
对于采用多个几何参数的函数,如果这些参数不具有相同的SRID,
ER_GIS_DIFFERENT_SRIDS
则会发生错误。
如果任何参数在几何上无效,则结果为true或false(未定义哪个),或者发生错误。
对于地理SRS几何参数,如果任何参数的经度或纬度超出范围,则会发生错误:
如果经度值不在范围(-180,180)内,
ER_LONGITUDE_OUT_OF_RANGE
则会发生错误。
如果纬度值不在[-90,90]范围内,
ER_LATITUDE_OUT_OF_RANGE
则会发生错误。
显示的范围以度为单位。 如果SRS使用其他单位,则该范围使用其单位中的相应值。 由于浮点运算,精确的范围限制略有偏差。
否则,返回值为非
NULL
。
这些MBR函数可用于测试几何关系:
返回1或0以指示最小边界矩形是否
g1
包含最小边界矩形
g2
。
这测试了相反的关系
MBRWithin()
。
MBRContains()
处理其参数,如本节的介绍中所述。
mysql>SET @g1 = ST_GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0))');
mysql>SET @g2 = ST_GeomFromText('Point(1 1)');
mysql>SELECT MBRContains(@g1,@g2), MBRWithin(@g2,@g1);
+ ---------------------- + -------------------- + | MBRContains(@ g1,@ g2)| MBRWithin(@ g2,@ g1)| + ---------------------- + -------------------- + | 1 | 1 | + ---------------------- + -------------------- +
返回1或0以指示最小边界矩形是否被最小边界矩形
g1
覆盖
g2
。
这测试了相反的关系
MBRCovers()
。
MBRCoveredBy()
处理其参数,如本节的介绍中所述。
mysql>SET @g1 = ST_GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0))');
mysql>SET @g2 = ST_GeomFromText('Point(1 1)');
mysql>SELECT MBRCovers(@g1,@g2), MBRCoveredby(@g1,@g2);
+ -------------------- + ----------------------- + | MBRCovers(@ g1,@ g2)| MBRCoveredby(@ g1,@ g2)| + -------------------- + ----------------------- + | 1 | 0 | + -------------------- + ----------------------- + MySQL的>SELECT MBRCovers(@g2,@g1), MBRCoveredby(@g2,@g1);
+ -------------------- + ----------------------- + | MBRCovers(@ g2,@ g1)| MBRCoveredby(@ g2,@ g1)| + -------------------- + ----------------------- + | 0 | 1 | + -------------------- + ----------------------- +
返回1或0以指示最小边界矩形是否
g1
覆盖最小边界矩形
g2
。
这测试了相反的关系
MBRCoveredBy()
。
请参阅
MBRCoveredBy()
示例的说明。
MBRCovers()
处理其参数,如本节的介绍中所述。
返回1或0,以指示两个几何的最小外接矩形是否
g1
和
g2
是不相交的(不相交)。
MBRDisjoint()
处理其参数,如本节的介绍中所述。
返回1或0,以指示最低是否界定两个几何的矩形
g1
和
g2
是相同的。
MBREquals()
处理其参数,如本节的介绍中所述,除了它不返回
NULL
空几何参数。
返回1或0,以指示两个几何的最小外接矩形是否
g1
和
g2
相交。
MBRIntersects()
处理其参数,如本节的介绍中所述。
如果它们相交,则 两个几何在 空间上重叠 ,并且它们的交点产生相同尺寸的几何形状但不等于给定几何形状中的任何一个。
此函数返回1或0,以指示是否所述两个几何的最小外接矩形
g1
和
g2
重叠。
MBROverlaps()
处理其参数,如本节的介绍中所述。
如果它们的内部不相交,则 两个几何在 空间上接触 ,但是一个几何的边界与另一个的边界或内部相交。
此函数返回1或0,以指示最低是否界定两个几何的矩形
g1
和
g2
触感。
MBRTouches()
处理其参数,如本节的介绍中所述。
返回1或0以指示最小边界矩形是否在最小边界矩形
g1
内
g2
。
这测试了相反的关系
MBRContains()
。
MBRWithin()
处理其参数,如本节的介绍中所述。
mysql>SET @g1 = ST_GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0))');
mysql>SET @g2 = ST_GeomFromText('Polygon((0 0,0 5,5 5,5 0,0 0))');
mysql>SELECT MBRWithin(@g1,@g2), MBRWithin(@g2,@g1);
+ -------------------- + -------------------- + | MBRWithin(@ g1,@ g2)| MBRWithin(@ g2,@ g1)| + -------------------- + -------------------- + | 1 | 0 | + -------------------- + -------------------- +
Geohash是一种将任意精度的纬度和经度坐标编码为文本字符串的系统。
Geohash值是仅包含从中选择的字符的字符串
"0123456789bcdefghjkmnpqrstuvwxyz"
。
本节中的函数允许操作geohash值,这为应用程序提供了导入和导出geohash数据的功能,以及索引和搜索geohash值的功能。
除非另有说明,否则本节中的函数处理其参数如下:
如果有任何参数
NULL
,则返回值为
NULL
。
如果任何参数无效,则会发生错误。
如果任何参数的经度或纬度超出范围,则会发生错误:
如果任何经度参数不在范围(-180,180)内,
ER_LONGITUDE_OUT_OF_RANGE
则会发生错误。
如果任何纬度参数不在[-90,90]范围内,
ER_LATITUDE_OUT_OF_RANGE
则会发生错误。
显示的范围以度为单位。 由于浮点运算,精确的范围限制略有偏差。
如果任何点参数没有SRID 0或4326,
ER_SRS_NOT_FOUND
则会发生错误。
point
参数SRID有效性未被检查。
如果任何SRID参数引用未定义的空间参考系统(SRS),
ER_SRS_NOT_FOUND
则会发生错误。
如果任何SRID参数不在32位无符号整数的范围内,
ER_DATA_OUT_OF_RANGE
则会发生错误。
否则,返回值为非
NULL
。
这些geohash功能可用:
ST_GeoHash(
,
longitude
,
latitude
,
max_length
)ST_GeoHash(
point
,
max_length
)
返回连接字符集和排序规则中的geohash字符串。
对于第一种语法,
longitude
必须是[-180,180]范围内的数字,并且
latitude
必须是[-90,90]范围内的数字。
对于第二种语法,
POINT
需要
一个
值,其中X和Y坐标分别位于经度和纬度的有效范围内。
生成的字符串不会超过
max_length
字符,其上限为100.字符串可能比
max_length
字符
短,
因为创建geohash值的算法会一直持续,直到创建了一个字符串,该字符串是位置或
max_length
字符
的精确表示形式
, 以先到者为准。
ST_GeoHash()
处理其参数,如本节的介绍中所述。
MySQL的> SELECT ST_GeoHash(180,0,10), ST_GeoHash(-180,-90,15);
+ ---------------------- + ------------------------- +
| ST_GeoHash(180,0,10)| ST_GeoHash(-180,-90,15)|
+ ---------------------- + ------------------------- +
| xbpbpbpbpb | 000000000000000 |
+ ---------------------- + ------------------------- +
ST_LatFromGeoHash(
geohash_str
)
从geohash字符串值返回纬度,作为[-90,90]范围内的双精度数。
的
ST_LatFromGeoHash()
解码功能读取来自不超过433个字符
geohash_str
的参数。
这表示坐标值的内部表示中的信息的上限。
超过433rd的字符将被忽略,即使它们是非法的并产生错误。
ST_LatFromGeoHash()
处理其参数,如本节的介绍中所述。
MySQL的> SELECT ST_LatFromGeoHash(ST_GeoHash(45,-20,10));
+ ------------------------------------------ +
| ST_LatFromGeoHash(ST_GeoHash(45,-20,10))|
+ ------------------------------------------ +
| -20 |
+ ------------------------------------------ +
ST_LongFromGeoHash(
geohash_str
)
从geohash字符串值返回经度,作为[-180,180]范围内的双精度数。
ST_LatFromGeoHash()
关于从
geohash_str
参数
处理的最大字符数
的描述中的注释
也适用于
ST_LongFromGeoHash()
。
ST_LongFromGeoHash()
处理其参数,如本节的介绍中所述。
MySQL的> SELECT ST_LongFromGeoHash(ST_GeoHash(45,-20,10));
+ ------------------------------------------- +
| ST_LongFromGeoHash(ST_GeoHash(45,-20,10))|
+ ------------------------------------------- +
| 45 |
+ ------------------------------------------- +
ST_PointFromGeoHash(
geohash_str
,
srid
)
POINT
给定geohash字符串值,
返回
包含已解码的geohash值的值。
该点的X和Y坐标分别是范围[-180,180]中的经度和范围[-90,90]中的纬度。
所述
srid
参数是一个32位无符号整数。
ST_LatFromGeoHash()
关于从
geohash_str
参数
处理的最大字符数
的描述中的注释
也适用于
ST_PointFromGeoHash()
。
ST_PointFromGeoHash()
处理其参数,如本节的介绍中所述。
mysql>SET @gh = ST_GeoHash(45,-20,10);
mysql>SELECT ST_AsText(ST_PointFromGeoHash(@gh,0));
+ --------------------------------------- + | ST_AsText(ST_PointFromGeoHash(@ gh,0))| + --------------------------------------- + | POINT(45 -20)| + --------------------------------------- +
本节介绍在GeoJSON文档和空间值之间进行转换的功能。 GeoJSON是一种用于编码几何/地理特征的开放标准。 有关更多信息,请访问 http://geojson.org 。 这里讨论的函数遵循GeoJSON规范1.0版。
GeoJSON支持MySQL支持的相同几何/地理数据类型。 除了从中提取几何对象外,不支持Feature和FeatureCollection对象。 CRS支持仅限于标识SRID的值。
MySQL还支持本机
JSON
数据类型和一组SQL函数,以启用对JSON值的操作。
有关更多信息,请参见
第11.6节“JSON数据类型”
和
第12.17节“JSON函数”
。
ST_AsGeoJSON(
g
[, max_dec_digits
[,
options
]])
从几何体生成GeoJSON对象
g
。
对象字符串具有连接字符集和排序规则。
如果有任何参数
NULL
,则返回值为
NULL
。
如果任何非
NULL
参数无效,则会发生错误。
max_dec_digits
,如果指定,则限制坐标的小数位数并导致输出舍入。
如果未指定,则此参数默认为其最大值2
32
- 1.最小值为0。
options
,如果指定,则是位掩码。
下表显示了允许的标志值。
如果geometry参数的SRID为0,则即使对于请求一个的标志值,也不会生成CRS对象。
旗帜价值 | 含义 |
---|---|
0 |
没有选择。
如果
options
未指定,
则为默认值
。
|
1 | 在输出中添加边界框。 |
2 |
在输出中添加短格式CRS URN。
默认格式是短格式(
)。
EPSG:
|
4 |
添加长格式CRS URN(
)。
此标志覆盖标志2.例如,选项值5和7表示相同(添加边界框和长格式CRS URN)。
urn:ogc:def:crs:EPSG::
|
MySQL的> SELECT ST_AsGeoJSON(ST_GeomFromText('POINT(11.11111 12.22222)'),2);
+ ------------------------------------------------- ------------ +
| ST_AsGeoJSON(ST_GeomFromText('POINT(11.11111 12.22222)'),2)|
+ ------------------------------------------------- ------------ +
| {“type”:“Point”,“coordinates”:[11.11,12.22]} |
+ ------------------------------------------------- ------------ +
ST_GeomFromGeoJSON(
str
[, options
[,
srid
]])
解析
str
表示GeoJSON对象
的字符串
并返回几何。
如果有任何参数
NULL
,则返回值为
NULL
。
如果任何非
NULL
参数无效,则会发生错误。
options
,如果给定,则描述如何处理包含坐标尺寸大于2的几何的GeoJSON文档。下表显示了允许的
options
值。
期权价值 | 含义 |
---|---|
1 |
拒绝文档并产生错误。
如果
options
未指定,
则为默认值
。
|
2,3,4 | 接受文档并剥离坐标以获得更高的坐标尺寸。 |
options
值2,3和4目前产生相同的效果。
如果将来支持坐标尺寸大于2的几何图形,则这些值将产生不同的效果。
的
srid
参数,如果给定的,必须是一个32位无符号整数。
如果未给出,则几何返回值的SRID为4326。
如果
srid
引用未定义的空间参照系(SRS),
ER_SRS_NOT_FOUND
则会发生错误。
对于地理SRS几何参数,如果任何参数的经度或纬度超出范围,则会发生错误:
如果经度值不在范围(-180,180)内,
ER_LONGITUDE_OUT_OF_RANGE
则会发生错误。
如果纬度值不在[-90,90]范围内,
ER_LATITUDE_OUT_OF_RANGE
则会发生错误。
显示的范围以度为单位。 如果SRS使用其他单位,则该范围使用其单位中的相应值。 由于浮点运算,精确的范围限制略有偏差。
GeoJSON几何,要素和要素集合对象可能具有
crs
属性。
解析函数解析
和
名称空间
中的命名CRS URN
,但不
解析
作为链接对象给出的CRS。
此外,
还被识别为SRID 4326.如果对象具有未被理解的CRS,则会发生错误,但如果
给出
可选
参数,则即使CRS无效,也会忽略任何CRS。
urn:ogc:def:crs:EPSG::
srid
EPSG:
srid
urn:ogc:def:crs:OGC:1.3:CRS84
srid
如果
crs
在GeoJSON文档的较低级别找到指定与顶级对象SRID不同的SRID
的
成员,
ER_INVALID_GEOJSON_CRS_NOT_TOP_LEVEL
则会发生错误。
正如GeoJSON规范中所指定的,解析对于
type
GeoJSON输入
的
成员(
Point
,
LineString
等等)
区分大小写
。
该规范没有提及其他解析的区分大小写,在MySQL中它不区分大小写。
此示例显示了简单GeoJSON对象的解析结果:
mysql>SET @json = '{ "type": "Point", "coordinates": [102.0, 0.0]}';
mysql>SELECT ST_AsText(ST_GeomFromGeoJSON(@json));
+ -------------------------------------- + | ST_AsText(ST_GeomFromGeoJSON(@json))| + -------------------------------------- + | 要点(102 0)| + -------------------------------------- +
本节中的函数提供了几何值的便捷操作。
除非另有说明,否则本节中的函数处理其参数如下:
如果有任何参数
NULL
,则返回值为
NULL
。
如果任何几何参数不是语法上格式良好的几何体,
ER_GIS_INVALID_DATA
则会发生错误。
如果任何几何参数具有引用未定义空间参考系统(SRS)的SRID值,
ER_SRS_NOT_FOUND
则会发生错误。
对于采用多个几何参数的函数,如果这些参数不具有相同的SRID,
ER_GIS_DIFFERENT_SRIDS
则会发生错误。
否则,返回值为非
NULL
。
这些便利功能可用:
ST_Distance_Sphere(
g1
,
g2
[,
radius
])
返回球体之间的最小球面距离
Point
或
MultiPoint
球体上的参数(以米为单位)。
(对于通用距离计算,请参阅
ST_Distance()
函数。)可选
radius
参数应以米为单位。
如果两个几何参数都是有效的笛卡尔坐标
Point
或
MultiPoint
SRID 0中的值,则返回值是具有所提供半径的球体上两个几何之间的最短距离。
如果省略,则默认半径为6,370,986米,点X和Y坐标分别以度为单位解释为经度和纬度。
如果两个几何参数均为有效
Point
或
MultiPoint
地理空间参照系(SRS)中的值,则返回值是球体上具有提供半径的两个几何之间的最短距离。
如果省略,则默认半径等于平均半径,定义为(2a + b)/ 3,其中a是半长轴,b是SRS的半短轴。
ST_Distance_Sphere()
处理其参数,如本节的介绍中所述,但有以下例外:
支持的几何参数组合是
Point
和
Point
,或
Point
和
MultiPoint
(以任何参数顺序)。
如果至少一个几何结构既不
Point
是
MultiPoint
,
也不
是SRID为0,
ER_NOT_IMPLEMENTED_FOR_CARTESIAN_SRS
则会发生错误。
如果至少一个几何结构既不
Point
是
MultiPoint
,
也不
是
SRID,则其SRID指的是地理SRS,
ER_NOT_IMPLEMENTED_FOR_GEOGRAPHIC_SRS
则会发生错误。
如果任何几何图形指的是投影的SRS,
ER_NOT_IMPLEMENTED_FOR_PROJECTED_SRS
则会发生错误。
如果任何参数的经度或纬度超出范围,则会发生错误:
如果任何经度参数不在范围(-180,180)内,
ER_LONGITUDE_OUT_OF_RANGE
则会发生错误。
如果任何纬度参数不在[-90,90]范围内,
ER_LATITUDE_OUT_OF_RANGE
则会发生错误。
显示的范围以度为单位。 如果SRS使用其他单位,则该范围使用其单位中的相应值。 由于浮点运算,精确的范围限制略有偏差。
如果
radius
参数存在但不是正数,
ER_NONPOSITIVE_RADIUS
则会发生错误。
如果距离超出双精度数的范围,
ER_STD_OVERFLOW_ERROR
则会发生错误。
mysql>SET @pt1 = ST_GeomFromText('POINT(0 0)');
mysql>SET @pt2 = ST_GeomFromText('POINT(180 0)');
mysql>SELECT ST_Distance_Sphere(@pt1, @pt2);
+ -------------------------------- + | ST_Distance_Sphere(@ pt1,@ pt2)| + -------------------------------- + | 20015042.813723423 | + -------------------------------- +
如果参数在几何上有效,则返回1;如果参数在几何上无效,则返回0。 几何有效性由OGC规范定义。
唯一有效的空几何体以空几何集合值的形式表示。
ST_IsValid()
在这种情况下返回1。
MySQL不支持GIS
EMPTY
等
POINT EMPTY
。
ST_IsValid()
处理其参数,如本节的介绍中所述,但有以下例外:
如果几何体具有经度或纬度超出范围的地理SRS,则会发生错误:
如果任何经度参数不在范围(-180,180)内,
ER_LONGITUDE_OUT_OF_RANGE
则会发生错误。
如果任何纬度参数不在[-90,90]范围内,
ER_LATITUDE_OUT_OF_RANGE
则会发生错误。
显示的范围以度为单位。 如果SRS使用其他单位,则该范围使用其单位中的相应值。 由于浮点运算,精确的范围限制略有偏差。
mysql>SET @ls1 = ST_GeomFromText('LINESTRING(0 0,-0.00 0,0.0 0)');
mysql>SET @ls2 = ST_GeomFromText('LINESTRING(0 0, 1 1)');
mysql>SELECT ST_IsValid(@ls1);
+ ------------------ + | ST_IsValid(@ ls1)| + ------------------ + | 0 | + ------------------ + MySQL的>SELECT ST_IsValid(@ls2);
+ ------------------ + | ST_IsValid(@ ls2)| + ------------------ + | 1 | + ------------------ +
返回形成围绕两点信封,作为一个矩形
Point
,
LineString
或
Polygon
。
使用笛卡尔坐标系而不是球体,椭球体或地球上进行计算。
给定两个点
pt1
和
pt2
,
ST_MakeEnvelope()
产生在这样一个抽象的平面结果的几何图形:
如果
pt1
并且
pt2
相等,结果就是重点
pt1
。
否则,如果
是垂直或水平线段,则结果是线段
。
(
pt1
,
pt2
)(
pt1
,
pt2
)
否则,结果是使用多边形
pt1
和
pt2
作为对角点
的多边形
。
结果几何的SRID为0。
ST_MakeEnvelope()
处理其参数,如本节的介绍中所述,但有以下例外:
如果参数不是
Point
值,
ER_WRONG_ARGUMENTS
则会发生错误。
如果
ER_GIS_INVALID_DATA
两个点的任何坐标值都是无穷大或附加条件,则会发生错误
NaN
。
如果任何几何具有地理空间参照系(SRS)的SRID值,
ER_NOT_IMPLEMENTED_FOR_GEOGRAPHIC_SRS
则会发生错误。
mysql>SET @pt1 = ST_GeomFromText('POINT(0 0)');
mysql>SET @pt2 = ST_GeomFromText('POINT(1 1)');
mysql>SELECT ST_AsText(ST_MakeEnvelope(@pt1, @pt2));
+ ---------------------------------------- + | ST_AsText(ST_MakeEnvelope(@ pt1,@ pt2))| + ---------------------------------------- + | POLYGON((0 0,1 0,1 1,0 1,0 0))| + ---------------------------------------- +
使用Douglas-Peucker算法简化几何,并返回相同类型的简化值。
几何体可以是任何几何体类型,尽管Douglas-Peucker算法实际上可能不会处理每种类型。 通过将其组件逐个提供给简化算法来处理几何集合,并将返回的几何图形作为结果放入几何集合中。
的
max_distance
参数是要除去的距离(在输入坐标的单位)顶点到其他段。
移除简化线串的此距离内的顶点。
根据Boost.Geometry,由于简化过程,几何可能会变得无效,并且该过程可能会创建自相交。
要检查结果的有效性,请将其传递给
ST_IsValid()
。
ST_Simplify()
处理其参数,如本节的介绍中所述,但有以下例外:
如果
max_distance
参数不是正数,或者是
NaN
,则发生
ER_WRONG_ARGUMENTS
错误。
mysql>SET @g = ST_GeomFromText('LINESTRING(0 0,0 1,1 1,1 2,2 2,2 3,3 3)');
mysql>SELECT ST_AsText(ST_Simplify(@g, 0.5));
+ --------------------------------- + | ST_AsText(ST_Simplify(@ g,0.5))| + --------------------------------- + | LINESTRING(0 0,0 1,1 1,2 3,3 3)| + --------------------------------- + MySQL的>SELECT ST_AsText(ST_Simplify(@g, 1.0));
+ --------------------------------- + | ST_AsText(ST_Simplify(@ g,1.0))| + --------------------------------- + | LINESTRING(0 0,3 3)| + --------------------------------- +
根据OGC规范验证几何。
几何可以在语法上格式良好(WKB值加SRID),但几何上无效。
例如,此多边形几何无效:
POLYGON((0 0, 0 0, 0 0, 0 0, 0
0))
ST_Validate()
返回几何体,如果它在语法上是格式良好的并且在几何上是有效的,
NULL
如果参数在语法上没有良好形成或几何有效或是
NULL
。
ST_Validate()
可用于过滤掉无效的几何数据,但需要付出代价。
对于需要更精确结果而不受无效数据污染的应用程序,这种惩罚可能是值得的。
如果geometry参数有效,则按原样返回,除非输入
Polygon
或
MultiPolygon
具有顺时针环,
否则
在检查有效性之前将这些环反转。
如果几何有效,则返回带有反转环的值。
唯一有效的空几何体以空几何集合值的形式表示。
ST_Validate()
在这种情况下,无需进一步检查即可直接返回
从MySQL 8.0.13开始,
ST_Validate()
按照本节的介绍中的描述处理其参数,但有以下例外:
如果几何体具有经度或纬度超出范围的地理SRS,则会发生错误:
如果任何经度参数不在范围(-180,180)内,
ER_LONGITUDE_OUT_OF_RANGE
则会发生错误。
如果任何纬度参数不在[-90,90]范围内,
ER_LATITUDE_OUT_OF_RANGE
则会发生错误。
显示的范围以度为单位。 由于浮点运算,精确的范围限制略有偏差。
在MySQL 8.0.13之前,
ST_Validate()
按照本节的介绍中的描述处理其参数,但有以下例外:
如果几何在语法上没有良好形式,则返回值为
NULL
。
一个
ER_GIS_INVALID_DATA
不会发生错误。
如果几何具有地理空间参考系统(SRS)的SRID值,
ER_NOT_IMPLEMENTED_FOR_GEOGRAPHIC_SRS
则会发生错误。
mysql>SET @ls1 = ST_GeomFromText('LINESTRING(0 0)');
mysql>SET @ls2 = ST_GeomFromText('LINESTRING(0 0, 1 1)');
mysql>SELECT ST_AsText(ST_Validate(@ls1));
+ ------------------------------ + | ST_AsText(ST_Validate(@ ls1))| + ------------------------------ + | NULL | + ------------------------------ + MySQL的>SELECT ST_AsText(ST_Validate(@ls2));
+ ------------------------------ + | ST_AsText(ST_Validate(@ ls2))| + ------------------------------ + | LINESTRING(0 0,1 1)| + ------------------------------ +
本节中描述的函数对JSON值执行操作。
有关
JSON
数据类型和其他示例的
讨论
,请参见
第11.6节“JSON数据类型”
。
对于采用JSON参数的函数,如果参数不是有效的JSON值,则会发生错误。
解析为JSON的参数表示为
json_doc
;
指示的参数
val
未被解析。
还提供了一组用于操作GeoJSON值的空间函数。 请参见 第12.16.11节“空间GeoJSON函数” 。
表12.21 JSON函数
名称 | 描述 |
---|---|
JSON_ARRAY() |
创建JSON数组 |
JSON_ARRAY_APPEND() |
将数据附加到JSON文档 |
JSON_ARRAY_INSERT() |
插入JSON数组 |
-> |
评估路径后从JSON列返回值; 相当于JSON_EXTRACT()。 |
JSON_CONTAINS() |
JSON文档是否包含路径中的特定对象 |
JSON_CONTAINS_PATH() |
JSON文档是否包含路径中的任何数据 |
JSON_DEPTH() |
JSON文档的最大深度 |
JSON_EXTRACT() |
从JSON文档返回数据 |
->> |
在评估路径并取消引用结果后,从JSON列返回值; 相当于JSON_UNQUOTE(JSON_EXTRACT())。 |
JSON_INSERT() |
将数据插入JSON文档 |
JSON_KEYS() |
来自JSON文档的键数组 |
JSON_LENGTH() |
JSON文档中的元素数量 |
JSON_MERGE()
(已弃用8.0.3)
|
合并JSON文档,保留重复键。 JSON_MERGE_PRESERVE()的弃用词不再使用 |
JSON_MERGE_PATCH() |
合并JSON文档,替换重复键的值 |
JSON_MERGE_PRESERVE() |
合并JSON文档,保留重复键 |
JSON_OBJECT() |
创建JSON对象 |
JSON_OVERLAPS() |
比较两个JSON文档,如果它们具有任何共同的键值对或数组元素,则返回TRUE(1),否则返回FALSE(0) |
JSON_PRETTY() |
以人类可读的格式打印JSON文档 |
JSON_QUOTE() |
引用JSON文档 |
JSON_REMOVE() |
从JSON文档中删除数据 |
JSON_REPLACE() |
替换JSON文档中的值 |
JSON_SCHEMA_VALID() |
根据JSON模式验证JSON文档; 如果文档针对模式进行验证,则返回TRUE / 1;否则返回FALSE / 0 |
JSON_SCHEMA_VALIDATION_REPORT() |
根据JSON模式验证JSON文档; 以JSON格式返回有关验证结果的报告,包括成功或失败以及失败原因 |
JSON_SEARCH() |
JSON文档中的值路径 |
JSON_SET() |
将数据插入JSON文档 |
JSON_STORAGE_FREE() |
在部分更新之后释放JSON列值的二进制表示内的空间 |
JSON_STORAGE_SIZE() |
用于存储JSON文档的二进制表示的空间 |
JSON_TABLE() |
将JSON表达式中的数据作为关系表返回 |
JSON_TYPE() |
JSON值的类型 |
JSON_UNQUOTE() |
取消引用JSON值 |
JSON_VALID() |
JSON值是否有效 |
MEMBER OF() |
如果第一个操作数匹配作为第二个操作数传递的JSON数组的任何元素,则返回true(1),否则返回false(0) |
MySQL支持两个聚合JSON函数
JSON_ARRAYAGG()
和
JSON_OBJECTAGG()
。
有关
这些的说明,
请参见
第12.20节“聚合(GROUP BY)函数”
。
MySQL还
使用该
函数
以易于阅读的格式
支持
JSON值的
“
漂亮打印
”
JSON_PRETTY()
。
您可以看到给定JSON值占用多少存储空间,
JSON_STORAGE_SIZE()
以及
JSON_STORAGE_FREE()
分别
使用
和
存储额外存储空间
。
有关这些函数的完整描述,请参见
第12.17.8节“JSON实用程序函数”
。
本节中列出的函数组成了组件元素的JSON值。
计算(可能为空)值列表并返回包含这些值的JSON数组。
MySQL的> SELECT JSON_ARRAY(1, "abc", NULL, TRUE, CURTIME());
+ --------------------------------------------- +
| JSON_ARRAY(1,“abc”,NULL,TRUE,CURTIME())|
+ --------------------------------------------- +
| [1,“abc”,null,true,“11:30:24.000000”] |
+ --------------------------------------------- +
JSON_OBJECT([
key
,
val
[,
key
,
val
] ...])
计算键值对(可能为空)并返回包含这些对的JSON对象。
如果任何键名称
NULL
或参数数量为奇数,
则会发生错误
。
MySQL的> SELECT JSON_OBJECT('id', 87, 'name', 'carrot');
+ ----------------------------------------- +
| JSON_OBJECT('id',87,'name','carrot')|
+ ----------------------------------------- +
| {“id”:87,“name”:“carrot”} |
+ ----------------------------------------- +
通过用双引号字符包装并转义内部引号和其他字符,然后将结果作为
utf8mb4
字符串
返回,将
字符串
引用为JSON值
。
NULL
如果参数是,则
返回
NULL
。
此函数通常用于生成有效的JSON字符串文字以包含在JSON文档中。
根据 表12.22“JSON_UNQUOTE()特殊字符转义序列”中 显示的转义序列,使用反斜杠转义某些特殊字符 。
MySQL的>SELECT JSON_QUOTE('null'), JSON_QUOTE('"null"');
+ -------------------- + ---------------------- + | JSON_QUOTE('null')| JSON_QUOTE('“null”')| + -------------------- + ---------------------- + | “null”| “\”null \“”| + -------------------- + ---------------------- + MySQL的>SELECT JSON_QUOTE('[1, 2, 3]');
+ ------------------------- + | JSON_QUOTE('[1,2,3]')| + ------------------------- + | “[1,2,3]”| + ------------------------- +
您还可以通过
JSON
使用
其他类型的值转换为类型来获取JSON值
;
有关更多信息,
请参阅
在JSON和非JSON值之间转换
。
CAST(
value
AS
JSON)
可以使用两个生成JSON值的聚合函数。
JSON_ARRAYAGG()
将结果集作为单个JSON数组
JSON_OBJECTAGG()
返回
,
并将结果集作为单个JSON对象返回。
有关更多信息,请参见
第12.20节“聚合(GROUP BY)函数”
。
本节中的函数对JSON值执行搜索或比较操作,以从中提取数据,报告数据是否存在于其中的位置,或报告其中数据的路径。
在
MEMBER OF()
操作者在本文中也记载。
JSON_CONTAINS(
target
,
candidate
[,
path
])
通过返回1或0来指示给定的
candidate
JSON文档是否包含在
target
JSON文档中,或者 - 如果提供了
path
参数 - 是否在目标内的特定路径中找到候选项。
返回
NULL
如果任何参数
NULL
,或者如果路径参数不识别目标文档的一部分。
如果发生错误
target
或
candidate
不是有效的JSON文档,或者如果
path
参数不是一个有效的路径表达式或包含一个
*
或
**
通配符。
要仅检查路径中是否存在任何数据,请
JSON_CONTAINS_PATH()
改用。
以下规则定义了遏制:
候选标量包含在目标标量中,当且仅当它们具有可比性且相等时。
如果它们具有相同的
JSON_TYPE()
类型,
则两个标量值是可比较的
,除了类型的值
INTEGER
并且
DECIMAL
也彼此相当。
当且仅当候选中的每个元素都包含在目标的某个元素中时,候选数组才包含在目标数组中。
当且仅当候选者包含在目标的某个元素中时,候选非阵列包含在目标数组中。
候选对象包含在目标对象中,当且仅当对于候选中的每个键时,在目标中存在具有相同名称的键,并且与候选键相关联的值包含在与目标键相关联的值中。
否则,候选值不包含在目标文档中。
mysql>SET @j = '{"a": 1, "b": 2, "c": {"d": 4}}';
mysql>SET @j2 = '1';
mysql>SELECT JSON_CONTAINS(@j, @j2, '$.a');
+ ------------------------------- + | JSON_CONTAINS(@ j,@ j2,'$ .a')| + ------------------------------- + | 1 | + ------------------------------- + MySQL的>SELECT JSON_CONTAINS(@j, @j2, '$.b');
+ ------------------------------- + | JSON_CONTAINS(@ j,@ j2,'$ .b')| + ------------------------------- + | 0 | + ------------------------------- + mysql>SET @j2 = '{"d": 4}';
mysql>SELECT JSON_CONTAINS(@j, @j2, '$.a');
+ ------------------------------- + | JSON_CONTAINS(@ j,@ j2,'$ .a')| + ------------------------------- + | 0 | + ------------------------------- + MySQL的>SELECT JSON_CONTAINS(@j, @j2, '$.c');
+ ------------------------------- + | JSON_CONTAINS(@ j,@ j2,'$ .c')| + ------------------------------- + | 1 | + ------------------------------- +
JSON_CONTAINS_PATH(
json_doc
,
one_or_all
,
path
[,
path
] ...)
返回0或1以指示JSON文档是否包含给定路径或路径的数据。
NULL
如果有任何参数,则
返回
NULL
。
如果
json_doc
参数不是有效的JSON文档,任何
path
参数不是有效的路径表达式,或者
one_or_all
不是
'one'
或
,
则会发生错误
'all'
。
要检查路径中的特定值,请
JSON_CONTAINS()
改用。
如果文档中不存在指定的路径,则返回值为0。
否则,返回值取决于
one_or_all
参数:
'one'
:如果文档中至少存在一个路径,则为1,否则为0。
'all'
:如果文档中存在所有路径,则为1,否则为0。
mysql>SET @j = '{"a": 1, "b": 2, "c": {"d": 4}}';
mysql>SELECT JSON_CONTAINS_PATH(@j, 'one', '$.a', '$.e');
+ --------------------------------------------- + | JSON_CONTAINS_PATH(@ j,'one','$ .a','$ .e')| + --------------------------------------------- + | 1 | + --------------------------------------------- + MySQL的>SELECT JSON_CONTAINS_PATH(@j, 'all', '$.a', '$.e');
+ --------------------------------------------- + | JSON_CONTAINS_PATH(@j,'all','$ .a','$ .e')| + --------------------------------------------- + | 0 | + --------------------------------------------- + MySQL的>SELECT JSON_CONTAINS_PATH(@j, 'one', '$.c.d');
+ ---------------------------------------- + | JSON_CONTAINS_PATH(@j,'one','$ .c.d')| + ---------------------------------------- + | 1 | + ---------------------------------------- + MySQL的>SELECT JSON_CONTAINS_PATH(@j, 'one', '$.a.d');
+ ---------------------------------------- + | JSON_CONTAINS_PATH(@ j,'one','$ .a.d')| + ---------------------------------------- + | 0 | + ---------------------------------------- +
JSON_EXTRACT(
json_doc
,
path
[,
path
] ...)
返回JSON文档中的数据,该文档从
path
参数
匹配的文档部分中选择
。
返回
NULL
如果任何参数
NULL
或没有路径找到文档中的一个值。
如果
json_doc
参数不是有效的JSON文档或任何
path
参数不是有效的路径表达式,
则会发生错误
。
返回值由
path
参数
匹配的所有值组成
。
如果这些参数可能返回多个值,则匹配的值将按照与生成它们的路径对应的顺序自动包装为数组。
否则,返回值是单个匹配的值。
MySQL的>SELECT JSON_EXTRACT('[10, 20, [30, 40]]', '$[1]');
+ -------------------------------------------- + | JSON_EXTRACT('[10,20,[30,40]]','$ [1]')| + -------------------------------------------- + | 20 | + -------------------------------------------- + MySQL的>SELECT JSON_EXTRACT('[10, 20, [30, 40]]', '$[1]', '$[0]');
+ ------------------------------------------------- --- + | JSON_EXTRACT('[10,20,[30,40]]','$ [1]','$ [0]')| + ------------------------------------------------- --- + | [20,10] | + ------------------------------------------------- --- + MySQL的>SELECT JSON_EXTRACT('[10, 20, [30, 40]]', '$[2][*]');
+ ----------------------------------------------- + | JSON_EXTRACT('[10,20,[30,40]]','$ [2] [*]')| + ----------------------------------------------- + | [30,40] | + ----------------------------------------------- +
MySQL支持
->
运算符作为此函数的简写,与2个参数一起使用,其中左侧是
JSON
列标识符(不是表达式),右侧是要在列中匹配的JSON路径。
当与两个参数一起使用时
,
->
运算符充当
JSON_EXTRACT()
函数
的别名,
左侧是列标识符,右侧是根据JSON文档评估的JSON路径(列值)。
您可以使用此类表达式代替SQL语句中出现的列标识符。
SELECT
这里显示
的两个
语句产生相同的输出:
的MySQL>SELECT c, JSON_EXTRACT(c, "$.id"), g
>FROM jemp
>WHERE JSON_EXTRACT(c, "$.id") > 1
>ORDER BY JSON_EXTRACT(c, "$.name");
+ ------------------------------- + ----------- + ----- - + | c | c - >“$。id”| g | + ------------------------------- + ----------- + ----- - + | {“id”:“3”,“name”:“Barney”} | “3”| 3 | | {“id”:“4”,“name”:“Betty”} | “4”| 4 | | {“id”:“2”,“name”:“Wilma”} | “2”| 2 | + ------------------------------- + ----------- + ----- - + 3组(0.00秒) 的MySQL>SELECT c, c->"$.id", g
>FROM jemp
>WHERE c->"$.id" > 1
>ORDER BY c->"$.name";
+ ------------------------------- + ----------- + ----- - + | c | c - >“$。id”| g | + ------------------------------- + ----------- + ----- - + | {“id”:“3”,“name”:“Barney”} | “3”| 3 | | {“id”:“4”,“name”:“Betty”} | “4”| 4 | | {“id”:“2”,“name”:“Wilma”} | “2”| 2 | + ------------------------------- + ----------- + ----- - + 3组(0.00秒)
此功能不限
SELECT
于此,如下所示:
MySQL的>ALTER TABLE jemp ADD COLUMN n INT;
查询正常,0行受影响(0.68秒) 记录:0重复:0警告:0 MySQL的>UPDATE jemp SET n=1 WHERE c->"$.id" = "4";
查询正常,1行受影响(0.04秒) 匹配的行数:1已更改:1警告:0 的MySQL>SELECT c, c->"$.id", g, n
>FROM jemp
>WHERE JSON_EXTRACT(c, "$.id") > 1
>ORDER BY c->"$.name";
+ ------------------------------- + ----------- + ----- - + ------ + | c | c - >“$。id”| g | n | + ------------------------------- + ----------- + ----- - + ------ + | {“id”:“3”,“name”:“Barney”} | “3”| 3 | NULL | | {“id”:“4”,“name”:“Betty”} | “4”| 4 | 1 | | {“id”:“2”,“name”:“Wilma”} | “2”| 2 | NULL | + ------------------------------- + ----------- + ----- - + ------ + 3组(0.00秒) MySQL的>DELETE FROM jemp WHERE c->"$.id" = "4";
查询正常,1行受影响(0.04秒) 的MySQL>SELECT c, c->"$.id", g, n
>FROM jemp
>WHERE JSON_EXTRACT(c, "$.id") > 1
>ORDER BY c->"$.name";
+ ------------------------------- + ----------- + ----- - + ------ + | c | c - >“$。id”| g | n | + ------------------------------- + ----------- + ----- - + ------ + | {“id”:“3”,“name”:“Barney”} | “3”| 3 | NULL | | {“id”:“2”,“name”:“Wilma”} | “2”| 2 | NULL | + ------------------------------- + ----------- + ----- - + ------ + 2行(0.00秒)
(有关 用于创建和填充刚刚显示的表的语句, 请参阅 索引生成的列以提供JSON列索引 。)
这也适用于JSON数组值,如下所示:
MySQL的>CREATE TABLE tj10 (a JSON, b INT);
查询OK,0行受影响(0.26秒) mysqlINSERT INTO tj10
>>VALUES ("[3,10,5,17,44]", 33), ("[3,10,5,17,[22,44,66]]", 0);
查询正常,1行受影响(0.04秒) MySQL的>SELECT a->"$[4]" FROM tj10;
+ -------------- + | a - >“$ [4]”| + -------------- + | 44 | | [22,44,66] | + -------------- + 2行(0.00秒) MySQL的>SELECT * FROM tj10 WHERE a->"$[0]" = 3;
+ ------------------------------ + ------ + | a | b | + ------------------------------ + ------ + | [3,10,5,17,44] | 33 | | [3,10,5,17,[22,44,66]] | 0 | + ------------------------------ + ------ + 2行(0.00秒)
支持嵌套数组。
使用的表达式
->
计算
NULL
好像在目标JSON文档中找不到匹配的键,如下所示:
MySQL的>SELECT * FROM tj10 WHERE a->"$[4][1]" IS NOT NULL;
+ ------------------------------ + ------ + | a | b | + ------------------------------ + ------ + | [3,10,5,17,[22,44,66]] | 0 | + ------------------------------ + ------ + MySQL的>SELECT a->"$[4][1]" FROM tj10;
+ -------------- + | a - >“$ [4] [1]”| + -------------- + | NULL | | 44 | + -------------- + 2行(0.00秒)
这与使用时的情况相同
JSON_EXTRACT()
:
MySQL的> SELECT JSON_EXTRACT(a, "$[4][1]") FROM tj10;
+ ---------------------------- +
| JSON_EXTRACT(a,“$ [4] [1]”)|
+ ---------------------------- +
| NULL |
| 44 |
+ ---------------------------- +
2行(0.00秒)
这是一个改进的,不引用的提取操作符。
而
->
操作者简单地提取的值时,
->>
在加法运算unquotes所提取的结果。
换句话说,给定
JSON
列值
column
和路径表达式
path
,以下三个表达式返回相同的值:
JSON_UNQUOTE(
column
->
path
)
column
->>path
该
->>
操作可用于任何
JSON_UNQUOTE(JSON_EXTRACT())
将被允许。
这包括(但不限于)
SELECT
列表,
WHERE
和
HAVING
条款,并
ORDER
BY
和
GROUP BY
条款。
接下来的几个语句演示
->>
了
mysql
客户端中
其他表达式的
一些
运算符等价
:
MySQL的>SELECT * FROM jemp WHERE g > 2;
+ ------------------------------- + ------ + | c | g | + ------------------------------- + ------ + | {“id”:“3”,“name”:“Barney”} | 3 | | {“id”:“4”,“name”:“Betty”} | 4 | + ------------------------------- + ------ + 2行(0.01秒) mysql>SELECT c->'$.name' AS name
- >FROM jemp WHERE g > 2;
+ ---------- + | 名字| + ---------- + | “巴尼”| | “贝蒂”| + ---------- + 2行(0.00秒) mysql>SELECT JSON_UNQUOTE(c->'$.name') AS name
- >FROM jemp WHERE g > 2;
+ -------- + | 名字| + -------- + | 巴尼| | 贝蒂| + -------- + 2行(0.00秒) mysql>SELECT c->>'$.name' AS name
- >FROM jemp WHERE g > 2;
+ -------- + | 名字| + -------- + | 巴尼| | 贝蒂| + -------- + 2行(0.00秒)
请参阅
索引生成的列以提供JSON列索引
,用于在
jemp
刚刚显示的示例集中
创建和填充
表
的SQL语句
。
此运算符也可以与JSON数组一起使用,如下所示:
MySQL的>CREATE TABLE tj10 (a JSON, b INT);
查询OK,0行受影响(0.26秒) mysql>INSERT INTO tj10 VALUES
- >('[3,10,5,"x",44]', 33),
- >('[3,10,5,17,[22,"y",66]]', 0);
查询OK,2行受影响(0.04秒) 记录:2个重复:0个警告:0 MySQL的>SELECT a->"$[3]", a->"$[4][1]" FROM tj10;
+ ----------- -------------- + + | a - >“$ [3]”| a - >“$ [4] [1]”| + ----------- -------------- + + | “x”| NULL | | 17 | “y”| + ----------- -------------- + + 2行(0.00秒) MySQL的>SELECT a->>"$[3]", a->>"$[4][1]" FROM tj10;
+ ------------ + --------------- + | a - >>“$ [3]”| a - >>“$ [4] [1]”| + ------------ + --------------- + | x | NULL | | 17 | y | + ------------ + --------------- + 2行(0.00秒)
与此同时
->
,
->>
运算符总是在输出中展开
EXPLAIN
,如下例所示:
mysql>EXPLAIN SELECT c->>'$.name' AS name
- >FROM jemp WHERE g > 2\G
*************************** 1。排******************** ******* id:1 select_type:SIMPLE 桌子:jemp 分区:NULL 类型:范围 possible_keys:i 关键:我 key_len:5 ref:NULL 行:2 过滤:100.00 额外:使用在哪里 1排,1警告(0.00秒) MySQL的>SHOW WARNINGS\G
*************************** 1。排******************** ******* 等级:注意 代码:1003 消息:/ *选择#1 * /选择 json_unquote(json_extract(`jtest` .jemp``c`,'$。name'))AS`name`来自 `jtest``jemp` where(`jtest` .jemp``g`> 2) 1排(0.00秒)
这类似于MySQL
->
在相同情况下
扩展
运算符的方式。
从JSON对象的顶级值返回键作为JSON数组,或者,如果
path
给出参数,则返回所选路径中的顶级键。
NULL
如果有任何参数
NULL
,则
返回
参数
,该
json_doc
参数不是对象,或者
path
,如果给定,则不返回对象。
如果
json_doc
参数不是有效的JSON文档或
path
参数不是有效的路径表达式或包含
*
或
**
通配符,
则会发生错误
。
如果所选对象为空,则结果数组为空。 如果顶级值具有嵌套的子对象,则返回值不包括来自这些子对象的键。
MySQL的>SELECT JSON_KEYS('{"a": 1, "b": {"c": 30}}');
+ --------------------------------------- + | JSON_KEYS('{“a”:1,“b”:{“c”:30}}')| + --------------------------------------- + | [“a”,“b”] | + --------------------------------------- + MySQL的>SELECT JSON_KEYS('{"a": 1, "b": {"c": 30}}', '$.b');
+ ---------------------------------------------- + | JSON_KEYS('{“a”:1,“b”:{“c”:30}}','$ .b')| + ---------------------------------------------- + | [“c”] | + ---------------------------------------------- +
JSON_OVERLAPS(
json_doc1
,
json_doc2
)
比较两个JSON文档。 如果两个文档具有任何共同的键值对或数组元素,则返回true(1)。 如果两个参数都是标量,则该函数执行简单的相等性测试。
该函数用作对应函数
JSON_CONTAINS()
,其要求搜索到的数组的所有元素都存在于搜索的数组中。因此,
JSON_CONTAINS()
在执行
AND
操作的同时对搜索键
JSON_OVERLAPS()
执行
OR
操作。
当两个比较两个数组时,
JSON_OVERLAPS()
如果它们共享一个或多个共同的数组元素
,则
返回true;如果不共享
,则
返回false:
MySQL的>SELECT JSON_OVERLAPS("[1,3,5,7]", "[2,5,7]");
+ --------------------------------------- + | JSON_OVERLAPS(“[1,3,5,7]”,“[2,5,7]”)| + --------------------------------------- + | 1 | + --------------------------------------- + 1排(0.00秒) MySQL的>SELECT JSON_OVERLAPS("[1,3,5,7]", "[2,6,7]");
+ --------------------------------------- + | JSON_OVERLAPS(“[1,3,5,7]”,“[2,6,7]”)| + --------------------------------------- + | 1 | + --------------------------------------- + 1排(0.00秒) MySQL的>SELECT JSON_OVERLAPS("[1,3,5,7]", "[2,6,8]");
+ --------------------------------------- + | JSON_OVERLAPS(“[1,3,5,7]”,“[2,6,8]”)| + --------------------------------------- + | 0 | + --------------------------------------- + 1排(0.00秒)
部分匹配被视为不匹配,如下所示:
MySQL的> SELECT JSON_OVERLAPS('[[1,2],[3,4],5]', '[1,[2,3],[4,5]]');
+ ------------------------------------------------- ---- +
| JSON_OVERLAPS('[[1,2],[3,4],5]','[1,[2,3],[4,5]]')|
+ ------------------------------------------------- ---- +
| 0 |
+ ------------------------------------------------- ---- +
1排(0.00秒)
比较对象时,如果它们至少有一个共同的键值对,则结果为真。
MySQL的>SELECT JSON_OVERLAPS('{"a":1,"b":10,"d":10}', '{"c":1,"e":10,"f":1,"d":10}');
+ ------------------------------------------------- ---------------------- + | JSON_OVERLAPS('{“a”:1,“b”:10,“d”:10}','{“c”:1,“e”:10,“f”:1,“d”:10} ')| + ------------------------------------------------- ---------------------- + | 1 | + ------------------------------------------------- ---------------------- + 1排(0.00秒) MySQL的>SELECT JSON_OVERLAPS('{"a":1,"b":10,"d":10}', '{"a":5,"e":10,"f":1,"d":20}');
+ ------------------------------------------------- ---------------------- + | JSON_OVERLAPS('{“a”:1,“b”:10,“d”:10}','{“a”:5,“e”:10,“f”:1,“d”:20} ')| + ------------------------------------------------- ---------------------- + | 0 | + ------------------------------------------------- ---------------------- + 1排(0.00秒)
如果使用两个标量作为函数的参数,则
JSON_OVERLAPS()
执行一个简单的相等测试:
MySQL的>SELECT JSON_OVERLAPS('5', '5');
+ ------------------------- + | JSON_OVERLAPS('5','5')| + ------------------------- + | 1 | + ------------------------- + 1排(0.00秒) MySQL的>SELECT JSON_OVERLAPS('5', '6');
+ ------------------------- + | JSON_OVERLAPS('5','6')| + ------------------------- + | 0 | + ------------------------- + 1排(0.00秒)
将标量与数组进行比较时,会
JSON_OVERLAPS()
尝试将标量视为数组元素。
在此示例中,第二个参数
6
被解释为
[6]
,如下所示:
MySQL的> SELECT JSON_OVERLAPS('[4,5,6,7]', '6');
+ --------------------------------- +
| JSON_OVERLAPS('[4,5,6,7]','6')|
+ --------------------------------- +
| 1 |
+ --------------------------------- +
1排(0.00秒)
该函数不执行类型转换:
MySQL的>SELECT JSON_OVERLAPS('[4,5,"6",7]', '6');
+ ----------------------------------- + | JSON_OVERLAPS('[4,5,“6”,7]','6')| + ----------------------------------- + | 0 | + ----------------------------------- + 1排(0.00秒) MySQL的>SELECT JSON_OVERLAPS('[4,5,6,7]', '"6"');
+ ----------------------------------- + | JSON_OVERLAPS('[4,5,6,7]','“6”')| + ----------------------------------- + | 0 | + ----------------------------------- + 1排(0.00秒)
JSON_OVERLAPS()
在MySQL 8.0.17中添加了。
JSON_SEARCH(
json_doc
,
one_or_all
,
search_str
[,
escape_char
[,
path
] ...])
返回JSON文档中给定字符串的路径。
NULL
如果任何
,或者
参数是
json_doc
,
则
返回
;
文件中
不
存在;
或者
没找到。
发生错误时,如果
参数不是一个有效的JSON文档,任何
参数不是一个有效的路径表达式,
是不
或
,或者
是不是一个常量表达式。
search_str
path
NULL
path
search_str
json_doc
path
one_or_all
'one'
'all'
escape_char
该
one_or_all
参数影响搜索,如下所示:
'one'
:搜索在第一个匹配后终止,并返回一个路径字符串。
未定义哪个匹配首先考虑。
'all'
:搜索返回所有匹配的路径字符串,以便不包含重复的路径。
如果有多个字符串,则将它们自动包装为数组。
数组元素的顺序未定义。
在
search_str
搜索字符串参数中,
%
和
_
字符用于
LIKE
运算符:
%
匹配任意数量的字符(包括零个字符),并且只
_
匹配一个字符。
要
在搜索字符串中
指定文字
%
或
_
字符,请在其前面加上转义字符。
默认值是
\
,如果
escape_char
参数丢失或
NULL
。
否则,
escape_char
必须是空或一个字符的常量。
有关匹配和转义字符行为的详细信息,请参阅的说明
LIKE
在
12.5.1节,“字符串比较函数”
。
对于转义字符处理,与
LIKE
行为
的区别
在于转义字符
JSON_SEARCH()
必须在编译时计算为常量,而不仅仅是在执行时。
例如,如果
JSON_SEARCH()
在预准备语句中使用
if
并且使用
escape_char
参数提供
?
参数,则参数值在执行时可能是常量,但不是在编译时。
MySQL的>SET @j = '["abc", [{"k": "10"}, "def"], {"x":"abc"}, {"y":"bcd"}]';
MySQL的>SELECT JSON_SEARCH(@j, 'one', 'abc');
+ ------------------------------- + | JSON_SEARCH(@j,'one','abc')| + ------------------------------- + | “$ [0]”| + ------------------------------- + MySQL的>SELECT JSON_SEARCH(@j, 'all', 'abc');
+ ------------------------------- + | JSON_SEARCH(@j,'all','abc')| + ------------------------------- + | [“$ [0]”,“$ [2] .x”] | + ------------------------------- + MySQL的>SELECT JSON_SEARCH(@j, 'all', 'ghi');
+ ------------------------------- + | JSON_SEARCH(@j,'all','ghi')| + ------------------------------- + | NULL | + ------------------------------- + MySQL的>SELECT JSON_SEARCH(@j, 'all', '10');
+ ------------------------------ + | JSON_SEARCH(@j,'all','10')| + ------------------------------ + | “$ [1] [0] .k”| + ------------------------------ + MySQL的>SELECT JSON_SEARCH(@j, 'all', '10', NULL, '$');
+ ----------------------------------------- + | JSON_SEARCH(@ j,'all','10',NULL,'$')| + ----------------------------------------- + | “$ [1] [0] .k”| + ----------------------------------------- + MySQL的>SELECT JSON_SEARCH(@j, 'all', '10', NULL, '$[*]');
+ -------------------------------------------- + | JSON_SEARCH(@j,'all','10',NULL,'$ [*]')| + -------------------------------------------- + | “$ [1] [0] .k”| + -------------------------------------------- + MySQL的>SELECT JSON_SEARCH(@j, 'all', '10', NULL, '$**.k');
+ --------------------------------------------- + | JSON_SEARCH(@j,'all','10',NULL,'$ **。k')| + --------------------------------------------- + | “$ [1] [0] .k”| + --------------------------------------------- + MySQL的>SELECT JSON_SEARCH(@j, 'all', '10', NULL, '$[*][0].k');
+ ------------------------------------------------- + | JSON_SEARCH(@ j,'all','10',NULL,'$ [*] [0] .k')| + ------------------------------------------------- + | “$ [1] [0] .k”| + ------------------------------------------------- + MySQL的>SELECT JSON_SEARCH(@j, 'all', '10', NULL, '$[1]');
+ -------------------------------------------- + | JSON_SEARCH(@j,'all','10',NULL,'$ [1]')| + -------------------------------------------- + | “$ [1] [0] .k”| + -------------------------------------------- + MySQL的>SELECT JSON_SEARCH(@j, 'all', '10', NULL, '$[1][0]');
+ ----------------------------------------------- + | JSON_SEARCH(@ j,'all','10',NULL,'$ [1] [0]')| + ----------------------------------------------- + | “$ [1] [0] .k”| + ----------------------------------------------- + MySQL的>SELECT JSON_SEARCH(@j, 'all', 'abc', NULL, '$[2]');
+ --------------------------------------------- + | JSON_SEARCH(@ j,'all','abc',NULL,'$ [2]')| + --------------------------------------------- + | “$ [2] .x”| + --------------------------------------------- + MySQL的>SELECT JSON_SEARCH(@j, 'all', '%a%');
+ ------------------------------- + | JSON_SEARCH(@j,'all','%a%')| + ------------------------------- + | [“$ [0]”,“$ [2] .x”] | + ------------------------------- + MySQL的>SELECT JSON_SEARCH(@j, 'all', '%b%');
+ ------------------------------- + | JSON_SEARCH(@j,'all','%b%')| + ------------------------------- + | [“$ [0]”,“$ [2] .x”,“$ [3] .y”] | + ------------------------------- + MySQL的>SELECT JSON_SEARCH(@j, 'all', '%b%', NULL, '$[0]');
+ --------------------------------------------- + | JSON_SEARCH(@j,'all','%b%',NULL,'$ [0]')| + --------------------------------------------- + | “$ [0]”| + --------------------------------------------- + MySQL的>SELECT JSON_SEARCH(@j, 'all', '%b%', NULL, '$[2]');
+ --------------------------------------------- + | JSON_SEARCH(@j,'all','%b%',NULL,'$ [2]')| + --------------------------------------------- + | “$ [2] .x”| + --------------------------------------------- + MySQL的>SELECT JSON_SEARCH(@j, 'all', '%b%', NULL, '$[1]');
+ --------------------------------------------- + | JSON_SEARCH(@j,'all','%b%',NULL,'$ [1]')| + --------------------------------------------- + | NULL | + --------------------------------------------- + MySQL的>SELECT JSON_SEARCH(@j, 'all', '%b%', '', '$[1]');
+ ------------------------------------------- + | JSON_SEARCH(@j,'all','%b%','','$ [1]')| + ------------------------------------------- + | NULL | + ------------------------------------------- + MySQL的>SELECT JSON_SEARCH(@j, 'all', '%b%', '', '$[3]');
+ ------------------------------------------- + | JSON_SEARCH(@j,'all','%b%','','$ [3]')| + ------------------------------------------- + | “$ [3] .y”| + ------------------------------------------- +
有关MySQL支持JSON的路径语法,包括有关通配符运营规则的详细信息
*
,并
**
请参阅
JSON路径语法
。
如果
value
是元素
json_array
,则
返回true(1)
,否则返回false(0)。
value
必须是标量或JSON文档;
如果它是标量,则运算符会尝试将其视为JSON数组的元素。
简单标量被视为数组值,如下所示:
MySQL的>SELECT 17 MEMBER OF('[23, "abc", 17, "ab", 10]');
+ ------------------------------------------- + | 17成员('[23,“abc”,17,“ab”,10]')| + ------------------------------------------- + | 1 | + ------------------------------------------- + 1排(0.00秒) MySQL的>SELECT 'ab' MEMBER OF('[23, "abc", 17, "ab", 10]');
+ --------------------------------------------- + | 'ab'成员('[23,“abc”,17,“ab”,10]')| + --------------------------------------------- + | 1 | + --------------------------------------------- + 1排(0.00秒)
数组元素值的部分匹配不匹配:
MySQL的> SELECT 7 MEMBER OF('[23, "abc", 17, "ab", 10]');
+ ------------------------------------------ +
| 7成员('[23,“abc”,17,“ab”,10]')|
+ ------------------------------------------ +
| 0 |
+ ------------------------------------------ +
1排(0.00秒)
MySQL的> SELECT 'a' MEMBER OF('[23, "abc", 17, "ab", 10]');
+ -------------------------------------------- +
| 'a'成员('[23,“abc”,17,“ab”,10]')|
+ -------------------------------------------- +
| 0 |
+ -------------------------------------------- +
1排(0.00秒)
不执行与字符串类型之间的转换:
mysql>SELECT
- >17 MEMBER OF('[23, "abc", "17", "ab", 10]'),
- >"17" MEMBER OF('[23, "abc", 17, "ab", 10]')\G
*************************** 1。排******************** ******* 17成员('[23,“abc”,“17”,“ab”,10]'):0 “17”成员('[23,“abc”,17,“ab”,10]'):0 1排(0.00秒)
要将此运算符与其本身为数组的值一起使用,必须将其显式转换为JSON数组。
你可以这样做
CAST(... AS JSON)
:
MySQL的> SELECT CAST('[4,5]' AS JSON) MEMBER OF('[[3,4],[4,5]]');
+ ------------------------------------------------- - +
| CAST('[4,5]'AS JSON)成员('[[3,4],[4,5]]')|
+ ------------------------------------------------- - +
| 1 |
+ ------------------------------------------------- - +
1排(0.00秒)
也可以使用
JSON_ARRAY()
函数
执行必要的强制转换
,如下所示:
MySQL的> SELECT JSON_ARRAY(4,5) MEMBER OF('[[3,4],[4,5]]');
+ -------------------------------------------- +
| JSON_ARRAY(4,5)成员('[[3,4],[4,5]]')|
+ -------------------------------------------- +
| 1 |
+ -------------------------------------------- +
1排(0.00秒)
用作要测试的值或出现在目标数组中的任何JSON对象必须使用
CAST(... AS JSON)
或
强制转换为正确的类型
JSON_OBJECT()
。
此外,包含JSON对象的目标数组本身必须使用
JSON_ARRAY
。
这在以下语句序列中得到证明:
MySQL的>SET @a = CAST('{"a":1}' AS JSON);
查询正常,0行受影响(0.00秒) MySQL的>SET @b = JSON_OBJECT("b", 2);
查询正常,0行受影响(0.00秒) MySQL的>SET @c = JSON_ARRAY(17, @b, "abc", @a, 23);
查询正常,0行受影响(0.00秒) MySQL的>SELECT @a MEMBER OF(@c), @b MEMBER OF(@c);
+ ------------------ + ------------------ + | @a成员(@c)| @b MEMBER OF(@c)| + ------------------ + ------------------ + | 1 | 1 | + ------------------ + ------------------ + 1排(0.00秒)
该
MEMBER OF()
操作符已添加到MySQL 8.0.17中。
本节中的函数修改JSON值并返回结果。
JSON_ARRAY_APPEND(
json_doc
,
path
,
val
[,
path
,
val
] ...)
将值附加到JSON文档中指定数组的末尾并返回结果。
NULL
如果有任何参数,则
返回
NULL
。
如果发生错误
json_doc
的参数是不是一个有效的JSON文档或任何
path
参数是不是有效的路径表达式或包含一个
*
或
**
通配符。
路径值对从左到右进行评估。 通过评估一对产生的文档成为评估下一对的新值。
如果路径选择标量或对象值,则该值将在数组中自动包装,并将新值添加到该数组中。 路径未标识JSON文档中的任何值的对将被忽略。
mysql>SET @j = '["a", ["b", "c"], "d"]';
mysql>SELECT JSON_ARRAY_APPEND(@j, '$[1]', 1);
+ ---------------------------------- + | JSON_ARRAY_APPEND(@ j,'$ [1]',1)| + ---------------------------------- + | [“a”,[“b”,“c”,1],“d”] | + ---------------------------------- + MySQL的>SELECT JSON_ARRAY_APPEND(@j, '$[0]', 2);
+ ---------------------------------- + | JSON_ARRAY_APPEND(@ j,'$ [0]',2)| + ---------------------------------- + | [[“a”,2],[“b”,“c”],“d”] | + ---------------------------------- + MySQL的>SELECT JSON_ARRAY_APPEND(@j, '$[1][0]', 3);
+ ------------------------------- + | JSON_ARRAY_APPEND(@ j,'$ [1] [0]',3)| + ------------------------------- + | [“a”,[[“b”,3],“c”],“d”] | + ------------------------------- + mysql>SET @j = '{"a": 1, "b": [2, 3], "c": 4}';
mysql>SELECT JSON_ARRAY_APPEND(@j, '$.b', 'x');
+ ------------------------------------ + | JSON_ARRAY_APPEND(@ j,'$ .b','x')| + ------------------------------------ + | {“a”:1,“b”:[2,3,“x”],“c”:4} | + ------------------------------------ + MySQL的>SELECT JSON_ARRAY_APPEND(@j, '$.c', 'y');
+ -------------------------------------- + | JSON_ARRAY_APPEND(@ j,'$ .c','y')| + -------------------------------------- + | {“a”:1,“b”:[2,3],“c”:[4,“y”]} | + -------------------------------------- + mysql>SET @j = '{"a": 1}';
mysql>SELECT JSON_ARRAY_APPEND(@j, '$', 'z');
+ --------------------------------- + | JSON_ARRAY_APPEND(@ j,'$','z')| + --------------------------------- + | [{“a”:1},“z”] | + --------------------------------- +
在MySQL 5.7中,这个函数被命名了
JSON_APPEND()
。
MySQL 8.0不再支持该名称。
JSON_ARRAY_INSERT(
json_doc
,
path
,
val
[,
path
,
val
] ...)
更新JSON文档,插入文档中的数组并返回修改后的文档。
NULL
如果有任何参数,则
返回
NULL
。
如果发生错误
json_doc
的参数是不是一个有效的JSON文档或任何
path
参数是不是有效的路径表达式或包含一个
*
或
**
通配符或不与一个数组元素标识符结束。
路径值对从左到右进行评估。 通过评估一对产生的文档成为评估下一对的新值。
路径未标识JSON文档中的任何数组的对将被忽略。 如果路径标识数组元素,则在该元素位置插入相应的值,将任何后续值移到右侧。 如果路径标识超出数组末尾的数组位置,则该值将插入数组的末尾。
mysql>SET @j = '["a", {"b": [1, 2]}, [3, 4]]';
mysql>SELECT JSON_ARRAY_INSERT(@j, '$[1]', 'x');
+ ------------------------------------ + | JSON_ARRAY_INSERT(@ j,'$ [1]','x')| + ------------------------------------ + | [“a”,“x”,{“b”:[1,2]},[3,4]] | + ------------------------------------ + MySQL的>SELECT JSON_ARRAY_INSERT(@j, '$[100]', 'x');
+ -------------------------------------- + | JSON_ARRAY_INSERT(@ j,'$ [100]','x')| + -------------------------------------- + | [“a”,{“b”:[1,2]},[3,4],“x”] | + -------------------------------------- + MySQL的>SELECT JSON_ARRAY_INSERT(@j, '$[1].b[0]', 'x');
+ ----------------------------------------- + | JSON_ARRAY_INSERT(@ j,'$ [1] .b [0]','x')| + ----------------------------------------- + | [“a”,{“b”:[“x”,1,2]},[3,4]] | + ----------------------------------------- + MySQL的>SELECT JSON_ARRAY_INSERT(@j, '$[2][1]', 'y');
+ --------------------------------------- + | JSON_ARRAY_INSERT(@ j,'$ [2] [1]','y')| + --------------------------------------- + | [“a”,{“b”:[1,2]},[3,“y”,4]] | + --------------------------------------- + MySQL的>SELECT JSON_ARRAY_INSERT(@j, '$[0]', 'x', '$[2][1]', 'y');
+ ------------------------------------------------- --- + | JSON_ARRAY_INSERT(@ j,'$ [0]','x','$ [2] [1]','y')| + ------------------------------------------------- --- + | [“x”,“a”,{“b”:[1,2]},[3,4]] | + ------------------------------------------------- --- +
较早的修改会影响数组中以下元素的位置,因此同一
JSON_ARRAY_INSERT()
调用
中的后续路径
应考虑到这一点。
在最后一个示例中,第二个路径不插入任何内容,因为路径在第一次插入后不再匹配任何内容。
JSON_INSERT(
json_doc
,
path
,
val
[,
path
,
val
] ...)
将数据插入JSON文档并返回结果。
NULL
如果有任何参数,则
返回
NULL
。
如果发生错误
json_doc
的参数是不是一个有效的JSON文档或任何
path
参数是不是有效的路径表达式或包含一个
*
或
**
通配符。
路径值对从左到右进行评估。 通过评估一对产生的文档成为评估下一对的新值。
将忽略文档中现有路径的路径值对,并且不会覆盖现有文档值。 如果路径标识了以下类型的值之一,则文档中不存在路径的路径值对会将值添加到文档中:
不存在于现有对象中的成员。 该成员将添加到对象并与新值关联。
位于现有数组末尾的位置。 使用新值扩展数组。 如果现有值不是数组,则将其作为数组自动包装,然后使用新值进行扩展。
否则,将忽略文档中不存在路径的路径 - 值对,但不起作用。
为了进行比较
JSON_INSERT()
,
JSON_REPLACE()
以及
JSON_SET()
,看到的讨论
JSON_SET()
。
mysql>SET @j = '{ "a": 1, "b": [2, 3]}';
mysql>SELECT JSON_INSERT(@j, '$.a', 10, '$.c', '[true, false]');
+ ------------------------------------------------- --- + | JSON_INSERT(@ j,'$ .a',10,'$ .c','[true,false]')| + ------------------------------------------------- --- + | {“a”:1,“b”:[2,3],“c”:“[true,false]”} | + ------------------------------------------------- --- +
结果中列出的第三个也是最后一个值是带引号的字符串,而不是像第二个那样的数组(在输出中没有引用); 不会将值转换为JSON类型。 要将数组作为数组插入,必须显式执行此类强制转换,如下所示:
MySQL的> SELECT JSON_INSERT(@j, '$.a', 10, '$.c', CAST('[true, false]' AS JSON));
+ ------------------------------------------------- ----------------- +
| JSON_INSERT(@ j,'$ .a',10,'$ .c',CAST('[true,false]'AS JSON))|
+ ------------------------------------------------- ----------------- +
| {“a”:1,“b”:[2,3],“c”:[true,false]} |
+ ------------------------------------------------- ----------------- +
1排(0.00秒)
JSON_MERGE(
json_doc
,
json_doc
[,
json_doc
] ...)
合并两个或多个JSON文档。
同义词
JSON_MERGE_PRESERVE()
;
在MySQL 8.0.3中已弃用,并且在将来的版本中将被删除。
MySQL的>SELECT JSON_MERGE('[1, 2]', '[true, false]');
+ --------------------------------------- + | JSON_MERGE('[1,2]','[true,false]')| + --------------------------------------- + | [1,2,true,false] | + --------------------------------------- + 1排,1警告(0.00秒) MySQL的>SHOW WARNINGS\G
*************************** 1。排******************** ******* 等级:警告 代码:1287 消息:'JSON_MERGE'已弃用,将在以后的版本中删除。\ 请改用JSON_MERGE_PRESERVE / JSON_MERGE_PATCH 1排(0.00秒)
有关其他示例,请参阅相关条目
JSON_MERGE_PRESERVE()
。
JSON_MERGE_PATCH(
json_doc
,
json_doc
[,
json_doc
] ...)
执行 符合 RFC 7396 的两个或多个JSON文档的合并,并返回合并的结果,而不保留具有重复键的成员。 如果至少有一个作为参数传递给此函数的文档无效,则引发错误。
有关此函数与之间差异的解释和示例
JSON_MERGE_PRESERVE()
,请参阅与
JSON_MERGE_PRESERVE()相比较的JSON_MERGE_PATCH()
。
JSON_MERGE_PATCH()
执行合并如下:
如果第一个参数不是对象,则合并的结果与将空对象与第二个参数合并的结果相同。
如果第二个参数不是对象,则合并的结果是第二个参数。
如果两个参数都是对象,则合并的结果是具有以下成员的对象:
第一个对象的所有成员没有在第二个对象中具有相同键的相应成员。
第二个对象的所有成员在第一个对象中没有对应的键,其值不是JSON
null
文字。
具有在第一个和第二个对象中存在的键的所有成员,并且其在第二个对象中的值不是JSON
null
文字。
这些成员的值是以递归方式将第一个对象中的值与第二个对象中的值合并的结果。
有关其他信息,请参阅 JSON值的规范化,合并和自动包装 。
MySQL的>SELECT JSON_MERGE_PATCH('[1, 2]', '[true, false]');
+ --------------------------------------------- + | JSON_MERGE_PATCH('[1,2]','[true,false]')| + --------------------------------------------- + | [true,false] | + --------------------------------------------- + MySQL的>SELECT JSON_MERGE_PATCH('{"name": "x"}', '{"id": 47}');
+ ------------------------------------------------- + | JSON_MERGE_PATCH('{“name”:“x”}','{“id”:47}')| + ------------------------------------------------- + | {“id”:47,“name”:“x”} | + ------------------------------------------------- + MySQL的>SELECT JSON_MERGE_PATCH('1', 'true');
+ ------------------------------- + | JSON_MERGE_PATCH('1','true')| + ------------------------------- + | 是的| + ------------------------------- + MySQL的>SELECT JSON_MERGE_PATCH('[1, 2]', '{"id": 47}');
+ ------------------------------------------ + | JSON_MERGE_PATCH('[1,2]','{“id”:47}')| + ------------------------------------------ + | {“id”:47} | + ------------------------------------------ + mysqlSELECT JSON_MERGE_PATCH('{ "a": 1, "b":2 }',
>>'{ "a": 3, "c":4 }');
+ ------------------------------------------------- ---------- + | JSON_MERGE_PATCH('{“a”:1,“b”:2}','{“a”:3,“c”:4}')| + ------------------------------------------------- ---------- + | {“a”:3,“b”:2,“c”:4} | + ------------------------------------------------- ---------- + mysqlSELECT JSON_MERGE_PATCH('{ "a": 1, "b":2 }','{ "a": 3, "c":4 }',
>>'{ "a": 5, "d":6 }');
+ ------------------------------------------------- ------------------------------ + | JSON_MERGE_PATCH('{“a”:1,“b”:2}','{“a”:3,“c”:4}','{“a”:5,“d”:6}') | + ------------------------------------------------- ------------------------------ + | {“a”:5,“b”:2,“c”:4,“d”:6} | + ------------------------------------------------- ------------------------------ +
您可以使用此函数通过
null
在seond参数中
指定
相同成员的值
来删除成员
,如下所示:
MySQL的> SELECT JSON_MERGE_PATCH('{"a":1, "b":2}', '{"b":null}');
+ ------------------------------------------------- - +
| JSON_MERGE_PATCH('{“a”:1,“b”:2}','{“b”:null}')|
+ ------------------------------------------------- - +
| {“a”:1} |
+ ------------------------------------------------- - +
这个例子表明该函数以递归方式运行; 也就是说,成员的值不仅限于标量,而是它们本身可以是JSON文档:
MySQL的> SELECT JSON_MERGE_PATCH('{"a":{"x":1}}', '{"a":{"y":2}}');
+ ------------------------------------------------- --- +
| JSON_MERGE_PATCH('{“a”:{“x”:1}}','{“a”:{“y”:2}}')|
+ ------------------------------------------------- --- +
| {“a”:{“x”:1,“y”:2}} |
+ ------------------------------------------------- --- +
JSON_MERGE_PATCH()
MySQL 8.0.3及更高版本支持。
JSON_MERGE_PATCH()与JSON_MERGE_PRESERVE()进行比较。
的行为
JSON_MERGE_PATCH()
是一样的是
JSON_MERGE_PRESERVE()
,有以下两种情况例外:
JSON_MERGE_PATCH()
使用第二个对象中的匹配键删除第一个对象中的任何成员,前提是与第二个对象中的键关联的值不是JSON
null
。
如果第二个对象的成员具有与第一个对象中的成员匹配的键,则使用第二个对象中
的值
JSON_MERGE_PATCH()
替换
第一个对象中的值,而
JSON_MERGE_PRESERVE()
将
第二个值
附加
到第一个值。
此示例将相同的3个JSON对象(每个对象具有匹配的键
"a"
)与这两个函数中的
每一个进行比较的结果进行比较
:
MySQL的>SET @x = '{ "a": 1, "b": 2 }',
>@y = '{ "a": 3, "c": 4 }',
>@z = '{ "a": 5, "d": 6 }';
mysql>SELECT JSON_MERGE_PATCH(@x, @y, @z) AS Patch,
- >JSON_MERGE_PRESERVE(@x, @y, @z) AS Preserve\G
*************************** 1。排******************** ******* 补丁:{“a”:5,“b”:2,“c”:4,“d”:6} 保留:{“a”:[1,3,5],“b”:2,“c”:4,“d”:6}
JSON_MERGE_PRESERVE(
json_doc
,
json_doc
[,
json_doc
] ...)
合并两个或多个JSON文档并返回合并的结果。
NULL
如果有任何参数,则
返回
NULL
。
如果任何参数不是有效的JSON文档,则会发生错误。
合并根据以下规则进行。 有关其他信息,请参阅 JSON值的规范化,合并和自动包装 。
相邻阵列合并为单个阵列。
相邻对象合并为单个对象。
标量值作为数组自动包装并合并为数组。
通过将对象自动包装为数组并合并两个数组来合并相邻的数组和对象。
MySQL的>SELECT JSON_MERGE_PRESERVE('[1, 2]', '[true, false]');
+ ------------------------------------------------ + | JSON_MERGE_PRESERVE('[1,2]','[true,false]')| + ------------------------------------------------ + | [1,2,true,false] | + ------------------------------------------------ + MySQL的>SELECT JSON_MERGE_PRESERVE('{"name": "x"}', '{"id": 47}');
+ ------------------------------------------------- --- + | JSON_MERGE_PRESERVE('{“name”:“x”}','{“id”:47}')| + ------------------------------------------------- --- + | {“id”:47,“name”:“x”} | + ------------------------------------------------- --- + MySQL的>SELECT JSON_MERGE_PRESERVE('1', 'true');
+ ---------------------------------- + | JSON_MERGE_PRESERVE('1','true')| + ---------------------------------- + | [1,true] | + ---------------------------------- + MySQL的>SELECT JSON_MERGE_PRESERVE('[1, 2]', '{"id": 47}');
+ --------------------------------------------- + | JSON_MERGE_PRESERVE('[1,2]','{“id”:47}')| + --------------------------------------------- + | [1,2,{“id”:47}] | + --------------------------------------------- + mysqlSELECT JSON_MERGE_PRESERVE('{ "a": 1, "b": 2 }',
>>'{ "a": 3, "c": 4 }');
+ ------------------------------------------------- ------------- + | JSON_MERGE_PRESERVE('{“a”:1,“b”:2}','{“a”:3,“c”:4}')| + ------------------------------------------------- ------------- + | {“a”:[1,3],“b”:2,“c”:4} | + ------------------------------------------------- ------------- + mysqlSELECT JSON_MERGE_PRESERVE('{ "a": 1, "b": 2 }','{ "a": 3, "c": 4 }',
>>'{ "a": 5, "d": 6 }');
+ ------------------------------------------------- --------------------------------- + | JSON_MERGE_PRESERVE('{“a”:1,“b”:2}','{“a”:3,“c”:4}','{“a”:5,“d”:6}') | + ------------------------------------------------- --------------------------------- + | {“a”:[1,3,5],“b”:2,“c”:4,“d”:6} | + ------------------------------------------------- --------------------------------- +
此功能在MySQL 8.0.3中添加为同义词
JSON_MERGE()
。
该
JSON_MERGE()
函数现已弃用,并且将在MySQL的未来版本中删除。
该功能与
JSON_MERGE_PATCH()
重要方面
相似但不同
;
有关详细信息,
请参阅
JSON_MERGE_PATCH()与JSON_MERGE_PRESERVE()
进行比较。
JSON_REMOVE(
json_doc
,
path
[,
path
] ...)
从JSON文档中删除数据并返回结果。
NULL
如果有任何参数,则
返回
NULL
。
如果
json_doc
参数不是有效的JSON文档或任何
path
参数不是有效的路径表达式或者是
$
或包含
*
或
**
通配符,
则会发生错误
。
该
path
参数进行评估从左到右。
通过评估一条路径生成的文档将成为评估下一条路径的新值。
如果文档中不存在要删除的元素,则不是错误; 在这种情况下,路径不会影响文档。
mysql>SET @j = '["a", ["b", "c"], "d"]';
mysql>SELECT JSON_REMOVE(@j, '$[1]');
+ ------------------------- + | JSON_REMOVE(@ j,'$ [1]')| + ------------------------- + | [“a”,“d”] | + ------------------------- +
JSON_REPLACE(
json_doc
,
path
,
val
[,
path
,
val
] ...)
替换JSON文档中的现有值并返回结果。
NULL
如果有任何参数,则
返回
NULL
。
如果发生错误
json_doc
的参数是不是一个有效的JSON文档或任何
path
参数是不是有效的路径表达式或包含一个
*
或
**
通配符。
路径值对从左到右进行评估。 通过评估一对产生的文档成为评估下一对的新值。
文档中现有路径的路径值对使用新值覆盖现有文档值。 文档中不存在路径的路径 - 值对将被忽略,并且不起作用。
在MySQL 8.0.4中,优化器可以执行列的部分就地更新,
JSON
而不是删除旧文档并将新文档完整地写入列。
可以对使用该
JSON_REPLACE()
函数
的更新语句执行此优化,
并满足
JSON值的部分更新中
概述的条件
。
为了进行比较
JSON_INSERT()
,
JSON_REPLACE()
以及
JSON_SET()
,看到的讨论
JSON_SET()
。
mysql>SET @j = '{ "a": 1, "b": [2, 3]}';
mysql>SELECT JSON_REPLACE(@j, '$.a', 10, '$.c', '[true, false]');
+ ------------------------------------------------- ---- + | JSON_REPLACE(@j,'$ .a',10,'$ .c','[true,false]')| + ------------------------------------------------- ---- + | {“a”:10,“b”:[2,3]} | + ------------------------------------------------- ---- +
JSON_SET(
json_doc
,
path
,
val
[,
path
,
val
] ...)
在JSON文档中插入或更新数据并返回结果。
返回
NULL
如果任何参数是
NULL
或
path
,如果给,不定位的对象。
如果发生错误
json_doc
的参数是不是一个有效的JSON文档或任何
path
参数是不是有效的路径表达式或包含一个
*
或
**
通配符。
路径值对从左到右进行评估。 通过评估一对产生的文档成为评估下一对的新值。
文档中现有路径的路径值对使用新值覆盖现有文档值。 如果路径标识了以下类型的值之一,则文档中不存在路径的路径值对会将值添加到文档中:
不存在于现有对象中的成员。 该成员将添加到对象并与新值关联。
位于现有数组末尾的位置。 使用新值扩展数组。 如果现有值不是数组,则将其作为数组自动包装,然后使用新值进行扩展。
否则,将忽略文档中不存在路径的路径 - 值对,但不起作用。
在MySQL 8.0.4中,优化器可以执行列的部分就地更新,
JSON
而不是删除旧文档并将新文档完整地写入列。
可以对使用该
JSON_SET()
函数
的更新语句执行此优化,
并满足
JSON值的部分更新中
概述的条件
。
的
JSON_SET()
,
JSON_INSERT()
和
JSON_REPLACE()
功能的关系:
JSON_SET()
替换现有值并添加不存在的值。
JSON_INSERT()
插入值而不替换现有值。
JSON_REPLACE()
仅
替换
现有值。
以下示例说明了这些差异,使用了document(
$.a
)
中存在的一个路径
和另一个
不存在的路径
(
$.c
):
mysql>SET @j = '{ "a": 1, "b": [2, 3]}';
mysql>SELECT JSON_SET(@j, '$.a', 10, '$.c', '[true, false]');
+ ------------------------------------------------- + | JSON_SET(@ j,'$ .a',10,'$ .c','[true,false]')| + ------------------------------------------------- + | {“a”:10,“b”:[2,3],“c”:“[true,false]”} | + ------------------------------------------------- + MySQL的>SELECT JSON_INSERT(@j, '$.a', 10, '$.c', '[true, false]');
+ ------------------------------------------------- --- + | JSON_INSERT(@ j,'$ .a',10,'$ .c','[true,false]')| + ------------------------------------------------- --- + | {“a”:1,“b”:[2,3],“c”:“[true,false]”} | + ------------------------------------------------- --- + MySQL的>SELECT JSON_REPLACE(@j, '$.a', 10, '$.c', '[true, false]');
+ ------------------------------------------------- ---- + | JSON_REPLACE(@j,'$ .a',10,'$ .c','[true,false]')| + ------------------------------------------------- ---- + | {“a”:10,“b”:[2,3]} | + ------------------------------------------------- ---- +
取消引用JSON值并将结果作为
utf8mb4
字符串
返回
。
NULL
如果参数是,则
返回
NULL
。
如果值以双引号开头和结尾但不是有效的JSON字符串文字,则会发生错误。
在字符串中,除非
NO_BACKSLASH_ESCAPES
启用SQL模式,
否则某些序列具有特殊含义
。
这些序列中的每一个都以反斜杠(
\
)
开头
,称为
转义字符
。
MySQL识别
表12.22“JSON_UNQUOTE()特殊字符转义序列”中显示的转义序列
。
对于所有其他转义序列,将忽略反斜杠。
也就是说,转义字符被解释为好像它没有被转义。
例如,
\x
就是这样
x
。
这些序列区分大小写。
例如,
\b
被解释为退格,但
\B
被解释为
B
。
这里显示了使用此函数的两个简单示例:
mysql>SET @j = '"abc"';
mysql>SELECT @j, JSON_UNQUOTE(@j);
+ ------- + ------------------ + | @j | JSON_UNQUOTE(@j)| + ------- + ------------------ + | “abc”| abc | + ------- + ------------------ + mysql>SET @j = '[1, 2, 3]';
mysql>SELECT @j, JSON_UNQUOTE(@j);
+ ----------- + ------------------ + | @j | JSON_UNQUOTE(@j)| + ----------- + ------------------ + | [1,2,3] | [1,2,3] | + ----------- + ------------------ +
以下示例显示了如何
JSON_UNQUOTE
在
NO_BACKSLASH_ESCAPES
禁用和启用时
转义句柄
:
MySQL的>SELECT @@sql_mode;
+ ------------ + | @@ sql_mode | + ------------ + | | + ------------ + MySQL的>SELECT JSON_UNQUOTE('"\\t\\u0032"');
+ ------------------------------ + | JSON_UNQUOTE('“\\ t \\ u0032”')| + ------------------------------ + | 2 | + ------------------------------ + mysql>SET @@sql_mode = 'NO_BACKSLASH_ESCAPES';
mysql>SELECT JSON_UNQUOTE('"\\t\\u0032"');
+ ------------------------------ + | JSON_UNQUOTE('“\\ t \\ u0032”')| + ------------------------------ + | \ t \ u0032 | + ------------------------------ + MySQL的>SELECT JSON_UNQUOTE('"\t\u0032"');
+ ---------------------------- + | JSON_UNQUOTE('“\ t \ u0032”')| + ---------------------------- + | 2 | + ---------------------------- +
本节中的函数返回JSON值的属性。
返回JSON文档的最大深度。
NULL
如果参数是,则
返回
NULL
。
如果参数不是有效的JSON文档,则会发生错误。
空数组,空对象或标量值具有深度1.仅包含深度为1的元素的非空数组或仅包含深度为1的成员值的非空对象具有深度2.否则,JSON文档的深度大于2。
MySQL的>SELECT JSON_DEPTH('{}'), JSON_DEPTH('[]'), JSON_DEPTH('true');
+ ------------------ + ------------------ + ----------- --------- + | JSON_DEPTH('{}')| JSON_DEPTH('[]')| JSON_DEPTH('true')| + ------------------ + ------------------ + ----------- --------- + | 1 | 1 | 1 | + ------------------ + ------------------ + ----------- --------- + MySQL的>SELECT JSON_DEPTH('[10, 20]'), JSON_DEPTH('[[], {}]');
+ ------------------------ + ------------------------ + | JSON_DEPTH('[10,20]')| JSON_DEPTH('[[],{}]')| + ------------------------ + ------------------------ + | 2 | 2 | + ------------------------ + ------------------------ + MySQL的>SELECT JSON_DEPTH('[10, {"a": 20}]');
+ ------------------------------- + | JSON_DEPTH('[10,{“a”:20}]')| + ------------------------------- + | 3 | + ------------------------------- +
返回JSON文档的长度,或者,如果
path
给出参数
,则返回
由路径标识的文档中的值的长度。
返回
NULL
如果任何参数
NULL
或
path
参数不文档中确定的值。
如果
json_doc
参数不是有效的JSON文档或
path
参数不是有效的路径表达式或包含
*
或
**
通配符,
则会发生错误
。
文件的长度确定如下:
标量的长度为1。
数组的长度是数组元素的数量。
对象的长度是对象成员的数量。
长度不计算嵌套数组或对象的长度。
MySQL的>SELECT JSON_LENGTH('[1, 2, {"a": 3}]');
+ --------------------------------- + | JSON_LENGTH('[1,2,{“a”:3}]')| + --------------------------------- + | 3 | + --------------------------------- + MySQL的>SELECT JSON_LENGTH('{"a": 1, "b": {"c": 30}}');
+ ----------------------------------------- + | JSON_LENGTH('{“a”:1,“b”:{“c”:30}}')| + ----------------------------------------- + | 2 | + ----------------------------------------- + MySQL的>SELECT JSON_LENGTH('{"a": 1, "b": {"c": 30}}', '$.b');
+ ------------------------------------------------ + | JSON_LENGTH('{“a”:1,“b”:{“c”:30}}','$ .b')| + ------------------------------------------------ + | 1 | + ------------------------------------------------ +
返回
utf8mb4
表示JSON值类型的字符串。
这可以是对象,数组或标量类型,如下所示:
mysql>SET @j = '{"a": [10, true]}';
mysql>SELECT JSON_TYPE(@j);
+ --------------- + | JSON_TYPE(@j)| + --------------- + | 对象| + --------------- + MySQL的>SELECT JSON_TYPE(JSON_EXTRACT(@j, '$.a'));
+ ------------------------------------ + | JSON_TYPE(JSON_EXTRACT(@ j,'$ .a'))| + ------------------------------------ + | ARRAY | + ------------------------------------ + MySQL的>SELECT JSON_TYPE(JSON_EXTRACT(@j, '$.a[0]'));
+ --------------------------------------- + | JSON_TYPE(JSON_EXTRACT(@ j,'$ .a [0]'))| + --------------------------------------- + | INTEGER | + --------------------------------------- + MySQL的>SELECT JSON_TYPE(JSON_EXTRACT(@j, '$.a[1]'));
+ --------------------------------------- + | JSON_TYPE(JSON_EXTRACT(@ j,'$ .a [1]'))| + --------------------------------------- + | BOOLEAN | + --------------------------------------- +
JSON_TYPE()
返回
NULL
如果参数为
NULL
:
MySQL的> SELECT JSON_TYPE(NULL);
+ ----------------- +
| JSON_TYPE(NULL)|
+ ----------------- +
| NULL |
+ ----------------- +
如果参数不是有效的JSON值,则会发生错误:
MySQL的> SELECT JSON_TYPE(1);
ERROR 3146(22032):参数1中JSON数据的数据类型无效
使用json_type; 需要JSON字符串或JSON类型。
对于
NULL
非错误结果,以下列表描述了可能的
JSON_TYPE()
返回值:
纯JSON类型:
OBJECT
:JSON对象
ARRAY
:JSON数组
BOOLEAN
:JSON真假文字
NULL
:JSON null文字
数字类型:
时间类型:
字符串类型:
二进制类型:
所有其他类型:
OPAQUE
(原始位)
返回0或1以指示值是否为有效JSON。
NULL
如果参数是,则
返回
NULL
。
MySQL的>SELECT JSON_VALID('{"a": 1}');
+ ------------------------ + | JSON_VALID('{“a”:1}')| + ------------------------ + | 1 | + ------------------------ + MySQL的>SELECT JSON_VALID('hello'), JSON_VALID('"hello"');
+ --------------------- + ----------------------- + | JSON_VALID('你好')| JSON_VALID('“hello”')| + --------------------- + ----------------------- + | 0 | 1 | + --------------------- + ----------------------- +
本节包含有关将JSON数据转换为表格数据的JSON函数的信息。
在MySQL 8.0.4及更高版本中,
JSON_TABLE()
支持
一个这样的功能
。
JSON_TABLE(
expr
,
path
COLUMNS
(column_list
) [AS]
alias
)
从JSON文档中提取数据并将其作为具有指定列的关系表返回。 此函数的完整语法如下所示:
JSON_TABLE(expr
,path
COLUMNS(column_list
) )[AS]alias
column_list
:column
[,column
] [,...]column
:name
为了ORDINALITY | 路径[ ] [ ]name
type
string path
on_error
on_empty
| EXISTS PATH | NESTED [PATH] COLUMNS()name
type
string path
path
column_list
on_error
: {NULL | 错误|json_string
错误的默认值on_empty
: {NULL | 错误| 空缺的DEFAULTjson_string
}
expr
:这是一个返回JSON数据的表达式。
这可以是constant(
'{"a":1}'
),列(
在
子句
之前指定的
t1.json_data
给定表
)或函数调用(
)。
t1
JSON_TABLE()
FROM
JSON_EXTRACT(t1,jsn_data,'$.post.comments')
path
:JSON路径表达式,应用于数据源。
我们将匹配路径的JSON值称为
行源
;
这用于生成一行关系数据。
该
COLUMNS
子句计算行源,在行源中查找特定的JSON值,并将这些JSON值作为SQL值返回到一行关系数据的各列中。
这
alias
是必需的。
表别名的通常规则适用(请参见
第9.2节“模式对象名称”
)。
JSON_TABLE()
支持四种类型的列,如下面的列表所述:
:此类型枚举
name
FOR
ORDINALITYCOLUMNS
子句中的
行
;
命名列
name
是一个类型为的计数器
UNSIGNED INT
,其初始值为1.这相当于
AUTO_INCREMENT
在
CREATE TABLE
语句中
指定列
,并且可用于区分
NESTED
[PATH]
子句
生成的多行的父行
。
:此类型的列用于提取指定的值
name
type
PATH
string_path
[on_error
]
[on_empty
]string_path
。
type
是一种MySQL数据类型。
JSON_TABLE()
使用应用于MySQL中的JSON数据的常规自动类型转换,将数据提取为JSON,然后将其强制转换为列类型。
确切的行为取决于列类型:如果列类型是SQL类型,则只能在列中保存标量值。
保存对象或数组会触发该
on error
子句;
在从保存为JSON的值到表列的强制执行期间发生错误时也会发生这种情况,例如尝试保存字符串
'asd'
到整数列。
缺失值会触发
on_empty
子句。
optional
on_error
子句确定
JSON_TABLE()
保存对象或数组时的作用:
NULL ON ERROR
:列设置为
NULL
;
这是默认行为。
如果在类型强制期间发生错误,则会引发警告。
ERROR ON ERROR
:抛出错误。
DEFAULT
:
json
string
ON ERRORjson_string
解析为JSON(假设它是有效的)并存储而不是对象或数组。
如果错误是由类型强制引起的,则抛出警告。
列类型规则也适用于默认值。
当截断保存到列的值(例如在
DECIMAL(10,1)
列中
保存3.14159)时
,将独立于任何
ON
ERROR
选项
发出警告
。
在单个语句中截断多个值时,警告仅发出一次。
optional
on empty
子句确定
JSON_TABLE()
在数据丢失的情况下(取决于类型)。
当子句中的列
NESTED
PATH
没有匹配且
NULL
为其生成补充行时,也会
在
子句中
的列上触发此子句
。
on empty
采用以下值之一:
NULL ON EMPTY
:列设置为
NULL
;
这是默认行为。
ERROR ON EMPTY
:抛出错误。
DEFAULT
:提供
json_string
ON
EMPTYjson_string
的解析为JSON,只要它有效,并存储而不是缺少值。
列类型规则也适用于默认值。
此查询演示了使用
ON
ERROR
和
ON EMPTY
选项。
对应的行
{"b":1}
对于路径是空的
"$.a"
,并且尝试保存
[1,2]
为标量会产生错误;
这些行在显示的输出中突出显示。
mysql>SELECT *
- >FROM
- >JSON_TABLE(
- >'[{"a":"3"},{"a":2},{"b":1},{"a":0},{"a":[1,2]}]',
- >"$[*]"
- >COLUMNS(
- >rowid FOR ORDINALITY,
- >ac VARCHAR(100) PATH "$.a" DEFAULT '999' ON ERROR DEFAULT '111' ON EMPTY,
- >aj JSON PATH "$.a" DEFAULT '{"x": 333}' ON EMPTY,
- >bx INT EXISTS PATH "$.b"
- >)
- >) AS tt;
+ ------- + ------ + ------------ + ------ + | rowid | ac | aj | bx | + ------- + ------ + ------------ + ------ + | 1 | 3 | “3”| 0 | | 2 | 2 | 2 | 0 | | 3 | 111 | {“x”:333} | 1 | | 4 | 0 | 0 | 0 | | 5 | 999 | [1,2] | 0 | + ------- + ------ + ------------ + ------ + 5行(0.00秒)
:如果在指定的位置存在任何数据,则此列返回1,否则返回
name
type
EXISTS PATH
path
path
0。
type
可以是任何有效的MySQL数据类型,但通常应指定为多种类型
INT
。
NESTED [PATH]
:这将JSON数据中的嵌套对象或数组与父对象或数组中的JSON值一起展平为单行。
使用多个
path
COLUMNS
(column_list
)PATH
选项可以将JSON值从多个嵌套级别投影到单个行中。
它
path
是相对于父路径行路径
JSON_TABLE()
,或者
NESTED [PATH]
是嵌套路径中
父子
句的路径。
列名遵循管理表列名称的通常规则和限制。 请参见 第9.2节“架构对象名称” 。
检查所有JSON和JSON路径表达式的有效性; 任何一种类型的无效表达式都会导致错误。
path
前面
COLUMNS
关键字的
每个匹配都
映射到结果表中的单个行。
例如,以下查询给出了此处显示的结果:
mysql>SELECT *
- >FROM
- >JSON_TABLE(
- >'[{"x":2,"y":"8"},{"x":"3","y":"7"},{"x":"4","y":6}]',
- >"$[*]" COLUMNS(
- >xval VARCHAR(100) PATH "$.x",
- >yval VARCHAR(100) PATH "$.y"
- >)
- >) AS jt1;
+ ------ + ------ + | xval | yval | + ------ + ------ + | 2 | 8 | | 3 | 7 | | 4 | 6 | + ------ + ------ +
表达式
"$[*]"
匹配数组的每个元素。
您可以通过修改路径来过滤结果中的行。
例如,使用
"$[1]"
限制提取到用作源的JSON数组的第二个元素,如下所示:
mysql>SELECT *
- >FROM
- >JSON_TABLE(
- >'[{"x":2,"y":"8"},{"x":"3","y":"7"},{"x":"4","y":6}]',
- >"$[1]" COLUMNS(
- >xval VARCHAR(100) PATH "$.x",
- >yval VARCHAR(100) PATH "$.y"
- >)
- >) AS jt1;
+ ------ + ------ + | xval | yval | + ------ + ------ + | 3 | 7 | + ------ + ------ +
在列定义中,
"$"
将整个匹配传递给列;
"$.x"
并且
"$.y"
仅传递与该键
匹配
的值
x
和
y
该匹配内
的值
。
有关更多信息,请参阅
JSON路径语法
。
NESTED PATH
(或简单地
NESTED
;
PATH
是可选的)为
COLUMNS
它所属
的
子句中的
每个匹配生成一组记录
。
如果没有匹配项,则嵌套路径的所有列都将设置为
NULL
。
这实现了最顶层子句和
NESTED [PATH]
。
之间的外连接
。
可以通过在
WHERE
子句中
应用合适的条件来模拟内部联接
,如下所示:
mysql>SELECT *
- >FROM
- >JSON_TABLE(
- >'[ {"a": 1, "b": [11,111]}, {"a": 2, "b": [22,222]}, {"a":3}]',
- >'$[*]' COLUMNS(
- >a INT PATH '$.a',
- >NESTED PATH '$.b[*]' COLUMNS (b INT PATH '$')
- >)
- >) AS jt
- >WHERE b IS NOT NULL;
+ ------ + ------ + | a | b | + ------ + ------ + | 1 | 11 | | 1 | 111 | | 2 | 22 | | 2 | 222 | + ------ + ------ +
兄弟姐妹嵌套路径 - 即
NESTED [PATH]
同一
COLUMNS
子句
中的
两个或多个实例
- 一个接一个地处理,一次一个。
当一个嵌套路径生成记录时,任何兄弟嵌套路径表达式的列都将设置为
NULL
。
这意味着单个包含
COLUMNS
子句中
单个匹配的记录总数
是总和,而不是
NESTED
[PATH]
修饰符
生成的所有记录的乘积
,如下所示:
mysql>SELECT *
- >FROM
- >JSON_TABLE(
- >'[{"a": 1, "b": [11,111]}, {"a": 2, "b": [22,222]}]',
- >'$[*]' COLUMNS(
- >a INT PATH '$.a',
- >NESTED PATH '$.b[*]' COLUMNS (b1 INT PATH '$'),
- >NESTED PATH '$.b[*]' COLUMNS (b2 INT PATH '$')
- >)
- >) AS jt;
+ ------ + ------ + ------ + | a | b1 | b2 | + ------ + ------ + ------ + | 1 | 11 | NULL | | 1 | 111 | NULL | | 1 | NULL | 11 | | 1 | NULL | 111 | | 2 | 22 | NULL | | 2 | 222 | NULL | | 2 | NULL | 22 | | 2 | NULL | 222 | + ------ + ------ + ------ +
甲
FOR ORDINALITY
列列举由所产生的记录
COLUMNS
条款,并且可以用来区分一个嵌套路径的父记录,特别是如果在父记录值是相同的,因为在这里可以看到:
mysql>SELECT *
- >FROM
- >JSON_TABLE(
- >'[{"a": "a_val",
'>"b": [{"c": "c_val", "l": [1,2]}]},
'>{"a": "a_val",
'>"b": [{"c": "c_val","l": [11]}, {"c": "c_val", "l": [22]}]}]',
- >'$[*]' COLUMNS(
- >top_ord FOR ORDINALITY,
- >apath VARCHAR(10) PATH '$.a',
- >NESTED PATH '$.b[*]' COLUMNS (
- >bpath VARCHAR(10) PATH '$.c',
- >ord FOR ORDINALITY,
- >NESTED PATH '$.l[*]' COLUMNS (lpath varchar(10) PATH '$')
- >)
- >)
- >) as jt;
+ --------- + --------- + --------- + ------ + ------- + | top_ord | apath | bpath | ord | lpath | + --------- + --------- + --------- + ------ + ------- + | 1 | a_val | c_val | 1 | 1 | | 1 | a_val | c_val | 1 | 2 | | 2 | a_val | c_val | 1 | 11 | | 2 | a_val | c_val | 2 | 22 | + --------- + --------- + --------- + ------ + ------- +
源文档包含两个元素的数组;
这些元素中的每一个都产生两行。
整个结果集
的值
apath
和
值
bpath
相同;
这意味着它们不能用于确定
lpath
值是来自相同或不同的父母。
ord
列
的值
保持与
top_ord
等于1
的记录集
相同,因此这两个值来自单个对象。
其余两个值来自不同的对象,因为它们在
ord
列中
具有不同的值
。
从MySQL 8.0.17开始,MySQL支持针对符合
JSON Schema规范草案4的
JSON模式验证JSON文档
。
这可以使用本节中详述的任一函数来完成,这两个函数都包含两个参数,一个JSON模式和一个根据模式验证的JSON文档。
JSON_SCHEMA_VALID()
如果文档对模式进行验证,则返回true;如果不是,则返回false;否则返回false。
JSON_SCHEMA_VALIDATION_REPORT()
提供有关验证的JSON格式的报告。
两个函数都处理null或无效输入,如下所示:
如果至少有一个参数是
NULL
,则函数返回
NULL
。
如果至少有一个参数不是有效的JSON,则该函数会引发错误(
ER_INVALID_TYPE_FOR_JSON
)
此外,如果架构不是有效的JSON对象,则函数返回
ER_INVALID_JSON_TYPE
。
MySQL支持
required
JSON模式中
的
属性以强制包含必需的属性(请参阅函数说明中的示例)。
MySQL不支持JSON模式中的外部资源;
使用
$ref
关键字导致
JSON_SCHEMA_VALID()
失败
ER_NOT_SUPPORTED_YET
。
MySQL支持JSON模式中的正则表达式模式,它支持但默默地忽略无效模式(请参阅
JSON_SCHEMA_VALID()
示例
的说明
)。
以下列表详细介绍了这些功能:
JSON_SCHEMA_VALID(
schema
,document
)
根据JSON验证
document
JSON
schema
。
两者
schema
和
document
是必需的。
架构必须是有效的JSON对象;
该文档必须是有效的JSON文档。
只要满足这些条件:如果文档针对模式进行验证,则函数返回true(1);
否则,返回false(0)。
在此示例中,我们将用户变量设置
@schema
为地理坐标的aa JSON模式
@document
的值,将
另一个
变量设置为
包含一个此类坐标的JSON文档的值。
然后,我们
通过使用它们作为参数来
@document
验证验证
:
@schema
JSON_SCHEMA_VALID()
mysql>SET @schema = '{
'>"id": "http://json-schema.org/geo",
'>"$schema": "http://json-schema.org/draft-04/schema#",
'>"description": "A geographical coordinate",
'>"type": "object",
'>"properties": {
'>"latitude": {
'>"type": "number",
'>"minimum": -90,
'>"maximum": 90
'>},
'>"longitude": {
'>"type": "number",
'>"minimum": -180,
'>"maximum": 180
'>}
'>},
'>"required": ["latitude", "longitude"]
'>}';
查询OK,0行受影响(0.01秒) mysql>SET @document = '{
'>"latitude": 63.444697,
'>"longitude": 10.445118
'>}';
查询正常,0行受影响(0.00秒) MySQL的>SELECT JSON_SCHEMA_VALID(@schema, @document);
+ --------------------------------------- + | JSON_SCHEMA_VALID(@schema,@ document)| + --------------------------------------- + | 1 | + --------------------------------------- + 1排(0.00秒)
由于
@schema
包含
required
属性,我们可以将其设置
@document
为有效但不包含必需属性的值,然后对其进行测试
@schema
,如下所示:
MySQL的>SET @document = '{}';
查询正常,0行受影响(0.00秒) MySQL的>SELECT JSON_SCHEMA_VALID(@schema, @document);
+ --------------------------------------- + | JSON_SCHEMA_VALID(@schema,@ document)| + --------------------------------------- + | 0 | + --------------------------------------- + 1排(0.00秒)
如果我们现在将值设置为
@schema
相同的JSON模式但没有该
required
属性,则
@document
验证因为它是有效的JSON对象,即使它不包含任何属性,如下所示:
mysql>SET @schema = '{
'>"id": "http://json-schema.org/geo",
'>"$schema": "http://json-schema.org/draft-04/schema#",
'>"description": "A geographical coordinate",
'>"type": "object",
'>"properties": {
'>"latitude": {
'>"type": "number",
'>"minimum": -90,
'>"maximum": 90
'>},
'>"longitude": {
'>"type": "number",
'>"minimum": -180,
'>"maximum": 180
'>}
'>}
'>}';
查询正常,0行受影响(0.00秒) MySQL的>SELECT JSON_SCHEMA_VALID(@schema, @document);
+ --------------------------------------- + | JSON_SCHEMA_VALID(@schema,@ document)| + --------------------------------------- + | 1 | + --------------------------------------- + 1排(0.00秒)
JSON Schema支持为字符串指定正则表达式模式,但MySQL使用的实现默默地忽略了无效模式。
这意味着
JSON_SCHEMA_VALID()
即使正则表达式模式无效,
也
可以返回true,如下所示:
MySQL的> SELECT JSON_SCHEMA_VALID('{"type":"string","pattern":"("}', '"abc"');
+ ------------------------------------------------- -------------- +
| JSON_SCHEMA_VALID('{“type”:“string”,“pattern”:“(”}','“abc”')|
+ ------------------------------------------------- -------------- +
| 1 |
+ ------------------------------------------------- -------------- +
1排(0.04秒)
JSON_SCHEMA_VALIDATION_REPORT(
schema
,document
)
根据JSON验证
document
JSON
schema
。
这两个
schema
和
document
是必需的。
与JSON_VALID_SCHEMA()一样,模式必须是有效的JSON对象,并且文档必须是有效的JSON文档。
如果满足这些条件,则该函数将返回关于验证结果的报告(作为JSON文档)。
如果根据JSON模式认为JSON文档有效,则该函数返回一个JSON对象,其中一个属性
valid
的值为“true”。
如果JSON文档未通过验证,则该函数返回一个JSON对象,其中包含此处列出的属性:
valid
:对于失败的模式验证,始终为“false”
reason
:包含失败原因的人类可读字符串
schema-location
:JSON指针URI片段标识符,指示验证失败的JSON模式中的位置(请参阅此列表后面的注释)
document-location
:JSON指针URI片段标识符,指示验证失败的JSON文档中的位置(请参阅此列表后面的注释)
schema-failed-keyword
:一个字符串,其中包含违反JSON模式中的关键字或属性的名称
JSON指针URI片段标识符在
RFC 6901 - JavaScript Object Notation(JSON)指针中定义
。
(这些是
不
一样由所使用的JSON路径表示法
JSON_EXTRACT()
和其他MySQL JSON功能)。在这种表示法中,
#
表示整个文档,和
#/myprop
表示包括在命名顶层属性的文档的所述部分
myprop
。
有关详细信息,请参阅刚才引用的规范和本节后面的示例。
在此示例中,我们将用户变量设置
@schema
为地理坐标的aa JSON模式
@document
的值,将
另一个
变量设置为
包含一个此类坐标的JSON文档的值。
然后,我们
通过使用它们作为参数来
@document
验证验证
:
@schema
JSON_SCHEMA_VALIDATION_REORT()
mysql>SET @schema = '{
'>"id": "http://json-schema.org/geo",
'>"$schema": "http://json-schema.org/draft-04/schema#",
'>"description": "A geographical coordinate",
'>"type": "object",
'>"properties": {
'>"latitude": {
'>"type": "number",
'>"minimum": -90,
'>"maximum": 90
'>},
'>"longitude": {
'>"type": "number",
'>"minimum": -180,
'>"maximum": 180
'>}
'>},
'>"required": ["latitude", "longitude"]
'>}';
查询OK,0行受影响(0.01秒) mysql>SET @document = '{
'>"latitude": 63.444697,
'>"longitude": 10.445118
'>}';
查询正常,0行受影响(0.00秒) MySQL的>SELECT JSON_SCHEMA_VALIDATION_REPORT(@schema, @document);
+ ------------------------------------------------- - + | JSON_SCHEMA_VALIDATION_REPORT(@schema,@ document)| + ------------------------------------------------- - + | {“valid”:true} | + ------------------------------------------------- - + 1排(0.00秒)
现在我们设置
@document
它为它的一个属性指定一个非法值,如下所示:
mysql>SET @document = '{
'>"latitude": 63.444697,
'>"longitude": 310.445118
'>}';
@document
在测试时,
验证
现在失败
JSON_SCHEMA_VALIDATION_REPORT()
。
函数调用的输出包含有关失败的详细信息(函数包含
JSON_PRETTY()
以提供更好的格式化),如下所示:
MySQL的> SELECT JSON_PRETTY(JSON_SCHEMA_VALIDATION_REPORT(@schema, @document))\G
*************************** 1。排******************** *******
JSON_PRETTY(JSON_SCHEMA_VALIDATION_REPORT(@schema,@ document)):{
“有效”:错误,
“原因”:“JSON文档位置'#/经度'在JSON架构位置'#/ properties / longitude''的要求'最大'失败”,
“schema-location”:“#/ properties / longitude”,
“文件位置”:“#/经度”,
“schema-failed-keyword”:“maximum”
}
1排(0.00秒)
由于
@schema
包含
required
属性,我们可以设置
@document
为有效但不包含所需属性的值,然后对其进行测试
@schema
。
输出
JSON_SCHEMA_VALIDATION_REPORT()
显示验证因缺少必需元素而失败,如下所示:
MySQL的>SET @document = '{}';
查询正常,0行受影响(0.00秒) MySQL的>SELECT JSON_PRETTY(JSON_SCHEMA_VALIDATION_REPORT(@schema, @document))\G
*************************** 1。排******************** ******* JSON_PRETTY(JSON_SCHEMA_VALIDATION_REPORT(@schema,@ document)):{ “有效”:错误, “reason”:“JSON Schema位置'#'”中的JSON文档位置'#'需要'''', “schema-location”:“#”, “文档位置”:“#”, “schema-failed-keyword”:“required” } 1排(0.00秒)
如果我们现在将值设置为
@schema
相同的JSON模式但没有该
required
属性,则
@document
验证因为它是有效的JSON对象,即使它不包含任何属性,如下所示:
mysql>SET @schema = '{
'>"id": "http://json-schema.org/geo",
'>"$schema": "http://json-schema.org/draft-04/schema#",
'>"description": "A geographical coordinate",
'>"type": "object",
'>"properties": {
'>"latitude": {
'>"type": "number",
'>"minimum": -90,
'>"maximum": 90
'>},
'>"longitude": {
'>"type": "number",
'>"minimum": -180,
'>"maximum": 180
'>}
'>}
'>}';
查询正常,0行受影响(0.00秒) MySQL的>SELECT JSON_SCHEMA_VALIDATION_REPORT(@schema, @document);
+ ------------------------------------------------- - + | JSON_SCHEMA_VALIDATION_REPORT(@schema,@ document)| + ------------------------------------------------- - + | {“valid”:true} | + ------------------------------------------------- - + 1排(0.00秒)
本节介绍了作用于JSON值的实用程序函数,或者可以解析为JSON值的字符串。
JSON_PRETTY()
以易于阅读的格式打印出JSON值。
JSON_STORAGE_SIZE()
并
JSON_STORAGE_FREE()
分别显示给定JSON值使用的存储空间量以及
JSON
部分更新后列中
剩余的空间量
。
提供类似于PHP和其他语言和数据库系统中实现的JSON值的漂亮打印。
提供的值必须是JSON值或JSON值的有效字符串表示形式。
此值中存在的外部空格和换行符对输出没有影响。
对于
NULL
值,函数返回
NULL
。
如果该值不是JSON文档,或者无法将其解析为一个,则该函数将失败并显示错误。
此函数的输出格式符合以下规则:
每个数组元素或对象成员显示在单独的行上,与其父级相比,缩进一个额外的级别。
每个级别的缩进都添加了两个前导空格。
在分隔两个元素或成员的换行符之前打印分隔各个数组元素或对象成员的逗号。
对象成员的键和值由冒号后跟空格('
:
')
分隔
。
空行或数组打印在一行上。 打开和关闭支架之间没有打印空间。
字符串标量和键名中的特殊字符使用
JSON_QUOTE()
函数
使用的相同规则进行转义
。
MySQL的>SELECT JSON_PRETTY('123'); # scalar
+ -------------------- + | JSON_PRETTY('123')| + -------------------- + | 123 | + -------------------- + MySQL的>SELECT JSON_PRETTY("[1,3,5]"); # array
+ ------------------------ + | JSON_PRETTY(“[1,3,5]”)| + ------------------------ + | [ 1, 3, 五 ] | + ------------------------ + MySQL的>SELECT JSON_PRETTY('{"a":"10","b":"15","x":"25"}'); # object
+ --------------------------------------------- + | JSON_PRETTY('{“a”:“10”,“b”:“15”,“x”:“25”}')| + --------------------------------------------- + | { “a”:“10”, “b”:“15”, “x”:“25” } | + --------------------------------------------- + mysql>SELECT JSON_PRETTY('["a",1,{"key1":
'>"value1"},"5", "77" ,
'>{"key2":["value3","valueX",
'>"valueY"]},"j", "2" ]')\G # nested arrays and objects
*************************** 1。排******************** ******* JSON_PRETTY('[ “一”,1,{ “KEY1”: “value1”},“5”,“77”, { “KEY2”:[ “值3”, “valuex”, “valuey”]},“j”,“2”]'):[ “一个”, 1, { “key1”:“value1” }, “5”, “77”, { “key2”:[ “值3” “valuex” “VALUE年” ] }, “J”, “2” ]
对于
JSON
列值,该功能显示多少存储空间,在其二进制表示被释放它是使用到位更新后
JSON_SET()
,
JSON_REPLACE()
或
JSON_REMOVE()
。
参数也可以是一个有效的JSON文档或一个字符串,可以将其解析为一个文字值或用户变量的值 -
在这种情况下函数返回0.如果是,则返回正的非零值argument是一个
JSON
已经如前所述更新
的
列值,因此它的二进制表示占用的空间比更新之前的空间少。
为一个
JSON
已更新的列,使其二进制表示与之前相同或更大,或者如果更新无法利用部分更新,则返回0;
NULL
如果参数是,
则返回
NULL
。
如果
json_val
不是
NULL
,既不是有效的JSON文档也不能成功解析为一个,则会产生错误。
在此示例中,我们创建一个包含
JSON
列
的表
,然后插入包含JSON对象的行:
MySQL的>CREATE TABLE jtable (jcol JSON);
查询OK,0行受影响(0.38秒) mysql>INSERT INTO jtable VALUES
- >('{"a": 10, "b": "wxyz", "c": "[true, false]"}');
查询正常,1行受影响(0.04秒) MySQL的>SELECT * FROM jtable;
+ ---------------------------------------------- + | jcol | + ---------------------------------------------- + | {“a”:10,“b”:“wxyz”,“c”:“[true,false]”} | + ---------------------------------------------- + 1排(0.00秒)
现在我们使用更新列值
JSON_SET()
来执行部分更新;
在这种情况下,我们将
c
键(数组
[true,
false]
)
指向的值替换为
占用较少空间(整数
1
)的值:
mysql>UPDATE jtable
- >SET jcol = JSON_SET(jcol, "$.a", 10, "$.b", "wxyz", "$.c", 1);
查询正常,1行受影响(0.03秒) 匹配的行数:1已更改:1警告:0 MySQL的>SELECT * FROM jtable;
+ -------------------------------- + | jcol | + -------------------------------- + | {“a”:10,“b”:“wxyz”,“c”:1} | + -------------------------------- + 1排(0.00秒) MySQL的>SELECT JSON_STORAGE_FREE(jcol) FROM jtable;
+ ------------------------- + | JSON_STORAGE_FREE(jcol)| + ------------------------- + | 14 | + ------------------------- + 1排(0.00秒)
连续部分更新对此可用空间的影响是累积的,如此示例所示,
JSON_SET()
用于减少具有键的值占用的空间
b
(并且不进行其他更改):
mysql>UPDATE jtable
- >SET jcol = JSON_SET(jcol, "$.a", 10, "$.b", "wx", "$.c", 1);
查询正常,1行受影响(0.03秒) 匹配的行数:1已更改:1警告:0 MySQL的>SELECT JSON_STORAGE_FREE(jcol) FROM jtable;
+ ------------------------- + | JSON_STORAGE_FREE(jcol)| + ------------------------- + | 16 | + ------------------------- + 1排(0.00秒)
不使用
JSON_SET()
,
更新列
JSON_REPLACE()
,或
JSON_REMOVE()
意味着优化器无法就地执行更新;
在这种情况下,
JSON_STORAGE_FREE()
返回0,如下所示:
MySQL的>UPDATE jtable SET jcol = '{"a": 10, "b": 1}';
查询OK,1行受影响(0.05秒) 匹配的行数:1已更改:1警告:0 MySQL的>SELECT JSON_STORAGE_FREE(jcol) FROM jtable;
+ ------------------------- + | JSON_STORAGE_FREE(jcol)| + ------------------------- + | 0 | + ------------------------- + 1排(0.00秒)
只能对列值执行JSON文档的部分更新。
对于存储JSON值的用户变量,即使使用
JSON_SET()
以下命令
执行更新,也始终完全替换该值
:
MySQL的>SET @j = '{"a": 10, "b": "wxyz", "c": "[true, false]"}';
查询正常,0行受影响(0.00秒) MySQL的>SET @j = JSON_SET(@j, '$.a', 10, '$.b', 'wxyz', '$.c', '1');
查询正常,0行受影响(0.00秒) MySQL的>SELECT @j, JSON_STORAGE_FREE(@j) AS Free;
+ ---------------------------------- + ------ + | @j | 免费| + ---------------------------------- + ------ + | {“a”:10,“b”:“wxyz”,“c”:“1”} | 0 | + ---------------------------------- + ------ + 1排(0.00秒)
对于JSON文字,此函数始终返回0:
MySQL的> SELECT JSON_STORAGE_FREE('{"a": 10, "b": "wxyz", "c": "1"}') AS Free;
+ ------ +
| 免费|
+ ------ +
| 0 |
+ ------ +
1排(0.00秒)
此函数返回用于存储JSON文档的二进制表示的字节数。
当参数是一
JSON
列时,这是用于存储JSON文档的空间,因为它插入到列中,之后可能已对其执行任何部分更新。
json_val
必须是有效的JSON文档或可以解析为一个的字符串。
在它是字符串的情况下,该函数返回JSON二进制表示形式中的存储空间量,该表示形式是通过将字符串解析为JSON并将其转换为二进制而创建的。
NULL
如果参数是
,则返回
NULL
。
如果
json_val
不是
NULL
,或者不能 - 或者不能成功解析为JSON文档,则会
导致错误
。
为了说明此函数在与
JSON
列作为参数
一起使用时的行为
,我们创建一个名为
jtable
包含
JSON
列
的表
jcol
,将JSON值插入表中,然后获取此列使用的存储空间
JSON_STORAGE_SIZE()
,如下所示:
MySQL的>CREATE TABLE jtable (jcol JSON);
查询OK,0行受影响(0.42秒) mysql>INSERT INTO jtable VALUES
- >('{"a": 1000, "b": "wxyz", "c": "[1, 3, 5, 7]"}');
查询正常,1行受影响(0.04秒) mysql>SELECT
- >jcol,
- >JSON_STORAGE_SIZE(jcol) AS Size,
- >JSON_STORAGE_FREE(jcol) AS Free
- >FROM jtable;
+ ----------------------------------------------- + - ----- + ------ + | jcol | 尺寸| 免费| + ----------------------------------------------- + - ----- + ------ + | {“a”:1000,“b”:“wxyz”,“c”:“[1,3,5,7]”} | 47 | 0 | + ----------------------------------------------- + - ----- + ------ + 1排(0.00秒)
根据输出
JSON_STORAGE_SIZE()
,插入到列中的JSON文档占用47个字节。
我们还检查了以前使用该列的任何部分更新释放的空间量
JSON_STORAGE_FREE()
;
由于尚未执行任何更新,因此预期为0。
接下来,我们
UPDATE
在表上
执行一个
应该导致存储的文档的部分更新
jcol
,然后测试结果,如下所示:
mysql>UPDATE jtable SET jcol =
- >JSON_SET(jcol, "$.b", "a");
查询正常,1行受影响(0.04秒) 匹配的行数:1已更改:1警告:0 mysql>SELECT
- >jcol,
- >JSON_STORAGE_SIZE(jcol) AS Size,
- >JSON_STORAGE_FREE(jcol) AS Free
- >FROM jtable;
+ -------------------------------------------- + ---- - + ------ + | jcol | 尺寸| 免费| + -------------------------------------------- + ---- - + ------ + | {“a”:1000,“b”:“a”,“c”:“[1,3,5,7]”} | 47 | 3 | + -------------------------------------------- + ---- - + ------ + 1排(0.00秒)
JSON_STORAGE_FREE()
上一个查询
返回的值
表示执行了JSON文档的部分更新,并释放了用于存储它的3个字节的空间。
返回的结果由
JSON_STORAGE_SIZE()
部分更新保持不变。
部分更新使用支持更新
JSON_SET()
,
JSON_REPLACE()
或
JSON_REMOVE()
。
JSON
不能部分更新
值到
列
的直接分配
;
在进行此类更新后,
JSON_STORAGE_SIZE()
始终显示用于新设置值的存储:
mysql>UPDATE jtable
mysql>SET jcol = '{"a": 4.55, "b": "wxyz", "c": "[true, false]"}';
查询正常,1行受影响(0.04秒) 匹配的行数:1已更改:1警告:0 mysql>SELECT
- >jcol,
- >JSON_STORAGE_SIZE(jcol) AS Size,
- >JSON_STORAGE_FREE(jcol) AS Free
- >FROM jtable;
+ ------------------------------------------------ + ------ + ------ + | jcol | 尺寸| 免费| + ------------------------------------------------ + ------ + ------ + | {“a”:4.55,“b”:“wxyz”,“c”:“[true,false]”} | 56 | 0 | + ------------------------------------------------ + ------ + ------ + 1排(0.00秒)
无法部分更新JSON用户变量。 这意味着此函数始终显示当前用于在用户变量中存储JSON文档的空间:
MySQL的>SET @j = '[100, "sakila", [1, 3, 5], 425.05]';
查询正常,0行受影响(0.00秒) MySQL的>SELECT @j, JSON_STORAGE_SIZE(@j) AS Size;
+ ------------------------------------ + ------ + | @j | 尺寸| + ------------------------------------ + ------ + | [100,“sakila”,[1,3,5],425.05] | 45 | + ------------------------------------ + ------ + 1排(0.00秒) MySQL的>SET @j = JSON_SET(@j, '$[1]', "json");
查询正常,0行受影响(0.00秒) MySQL的>SELECT @j, JSON_STORAGE_SIZE(@j) AS Size;
+ ---------------------------------- + ------ + | @j | 尺寸| + ---------------------------------- + ------ + | [100,“json”,[1,3,5],425.05] | 43 | + ---------------------------------- + ------ + 1排(0.00秒) MySQL的>SET @j = JSON_SET(@j, '$[2][0]', JSON_ARRAY(10, 20, 30));
查询正常,0行受影响(0.00秒) MySQL的>SELECT @j, JSON_STORAGE_SIZE(@j) AS Size;
+ --------------------------------------------- + --- --- + | @j | 尺寸| + --------------------------------------------- + --- --- + | [100,“json”,[[10,20,30],3,5],425.05] | 56 | + --------------------------------------------- + --- --- + 1排(0.00秒)
对于JSON文字,此函数始终返回当前使用的存储空间:
mysql>SELECT
- >JSON_STORAGE_SIZE('[100, "sakila", [1, 3, 5], 425.05]') AS A,
- >JSON_STORAGE_SIZE('{"a": 1000, "b": "a", "c": "[1, 3, 5, 7]"}') AS B,
- >JSON_STORAGE_SIZE('{"a": 1000, "b": "wxyz", "c": "[1, 3, 5, 7]"}') AS C,
- >JSON_STORAGE_SIZE('[100, "json", [[10, 20, 30], 3, 5], 425.05]') AS D;
+ ---- + ---- + ---- + ---- + | A | B | C | D | + ---- + ---- + ---- + ---- + | 45 | 44 | 47 | 56 | + ---- + ---- + ---- + ---- + 1排(0.00秒)
本节中描述的功能与基于GTID的复制一起使用。 重要的是要记住,所有这些函数都将GTID集的字符串表示作为参数。 因此,与它们一起使用时,必须始终引用GTID集。 有关 更多信息, 请参阅 GTID集 。
两个GTID集合的联合只是它们作为字符串的表示,用插入的逗号连接在一起。 换句话说,您可以定义一个非常简单的函数来获取两个GTID集的并集,类似于此处创建的:
创建功能GTID_UNION(g1 TEXT,g2 TEXT) 返回文本确定性 返回CONCAT(g1,',',g2);
有关GTID以及如何在实践中使用这些GTID功能的更多信息,请参见 第17.1.3节“使用全局事务标识符进行复制” 。
表12.23 GTID功能
名称 | 描述 |
---|---|
GTID_SUBSET() |
如果子集中的所有GTID也已设置,则返回true;否则返回true。 否则是假的。 |
GTID_SUBTRACT() |
返回集合中不在子集中的所有GTID。 |
WAIT_FOR_EXECUTED_GTID_SET() |
等到给定的GTID在slave上执行。 |
WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS() |
等到给定的GTID在slave上执行。 |
由于两套全局事务标识符
set1
和
set2
,如果所有GTIDs返回true
set1
也是
set2
。
否则返回false。
与此函数一起使用的GTID集表示为字符串,如以下示例所示:
mysql>SELECT GTID_SUBSET('3E11FA47-71CA-11E1-9E33-C80AA9429562:23',
- >'3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57')\G
*************************** 1。排******************** ******* GTID_SUBSET( '3E11FA47-71CA-11E1-9E33-C80AA9429562:23' '3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57'):1 1排(0.00秒) mysql>SELECT GTID_SUBSET('3E11FA47-71CA-11E1-9E33-C80AA9429562:23-25',
- >'3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57')\G
*************************** 1。排******************** ******* GTID_SUBSET( '3E11FA47-71CA-11E1-9E33-C80AA9429562:23-25', '3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57'):1 1排(0.00秒) mysql>SELECT GTID_SUBSET('3E11FA47-71CA-11E1-9E33-C80AA9429562:20-25',
- >'3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57')\G
*************************** 1。排******************** ******* GTID_SUBSET( '3E11FA47-71CA-11E1-9E33-C80AA9429562:20-25', '3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57'):0 1排(0.00秒)
由于两套全局事务标识符
set1
和
set2
,只返回那些GTIDs
set1
不在
set2
。
与此函数一起使用的所有GTID集都表示为字符串,必须引用,如下例所示:
mysql>SELECT GTID_SUBTRACT('3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57',
- >'3E11FA47-71CA-11E1-9E33-C80AA9429562:21')\G
*************************** 1。排******************** ******* GTID_SUBTRACT( '3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57', '3E11FA47-71CA-11E1-9E33-C80AA9429562:21'):3e11fa47-71ca-11e1-9e33-c80aa9429562:22-57 1排(0.00秒) mysql>SELECT GTID_SUBTRACT('3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57',
- >'3E11FA47-71CA-11E1-9E33-C80AA9429562:20-25')\G
*************************** 1。排******************** ******* GTID_SUBTRACT( '3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57', '3E11FA47-71CA-11E1-9E33-C80AA9429562:20-25'):3e11fa47-71ca-11e1-9e33-c80aa9429562:26-57 1排(0.00秒) mysql>SELECT GTID_SUBTRACT('3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57',
- >'3E11FA47-71CA-11E1-9E33-C80AA9429562:23-24')\G
*************************** 1。排******************** ******* GTID_SUBTRACT( '3E11FA47-71CA-11E1-9E33-C80AA9429562:21-57', '3E11FA47-71CA-11E1-9E33-C80AA9429562:23-24'):3e11fa47-71ca-11e1-9e33-c80aa9429562:21-22:25-57 1排(0.01秒)
WAIT_FOR_EXECUTED_GTID_SET(
gtid_set
[,
timeout
])
等到服务器应用了包含全局事务标识符的所有事务
gtid_set
;
也就是说,直到条件GTID_SUBSET(
gtid_subset
,
@@GLOBAL.gtid_executed
)成立。
有关
GTID集的定义,
请参见
第17.1.3.1节“GTID格式和存储”
。
如果指定了超时,并且
timeout
在应用GTID集中的所有事务之前经过了几秒钟,则该功能将停止等待。
timeout
是可选的,默认超时为0秒,在这种情况下,函数始终等待,直到应用了GTID集中的所有事务。
WAIT_FOR_EXECUTED_GTID_SET()
监视服务器上应用的所有GTID,包括从所有复制通道和用户客户端到达的事务。
它没有考虑复制通道是否已启动或停止。
有关更多信息,请参见 第17.1.3节“使用全局事务标识符进行复制” 。
与此函数一起使用的GTID集表示为字符串,因此必须引用,如以下示例所示:
MySQL的> SELECT WAIT_FOR_EXECUTED_GTID_SET('3E11FA47-71CA-11E1-9E33-C80AA9429562:1-5');
- > 0
有关GTID集的语法说明,请参见 第17.1.3.1节“GTID格式和存储” 。
对于
WAIT_FOR_EXECUTED_GTID_SET()
,返回值是查询的状态,其中0表示成功,1表示超时。
任何其他故障都会产生错误。
gtid_mode
任何客户端使用此功能等待GTID应用时,都无法更改为OFF。
WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS(
gtid_set
[,
timeout
][,channel
])
WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS()
类似于
WAIT_FOR_EXECUTED_GTID_SET()
它等待直到包含其全局事务标识符的所有事务
gtid_set
已被应用,或者直到
timeout
秒已经过去,以先发生者为准。
但是,
WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS()
适用于特定的复制通道,并且仅在已在应用程序必须运行的指定通道上应用事务后停止。
相反,
WAIT_FOR_EXECUTED_GTID_SET()
在应用事务后停止,无论它们应用于何处(在任何复制通道或任何用户客户端上),以及是否正在运行任何复制通道。
该
channel
选项命名该函数适用的复制通道。
如果未命名通道且不存在默认复制通道以外的通道,则该功能将应用于默认复制通道。
如果存在多个复制通道,则必须指定通道,否则不知道该功能适用于哪个复制通道。
有关
复制通道
的更多信息
,
请参见
第17.2.3节“复制通道”
。
由于
WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS()
应用于特定复制通道,如果预期事务到达不同的复制通道或用户客户端,例如在故障转移或手动恢复情况下,如果未设置超时,则该函数可无限期挂起。
使用
WAIT_FOR_EXECUTED_GTID_SET()
,而不是确保在这些情况下交易的正确处理。
使用的GTID集
WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS()
表示为字符串,必须以与for相同的方式引用
WAIT_FOR_EXECUTED_GTID_SET()
。
因为
WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS()
,函数的返回值是任意正数。
如果基于GTID的复制未激活(即,如果
gtid_mode
变量的值为OFF),则此值未定义并
WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS()
返回NULL。
如果从站未运行,则该函数也返回NULL。
gtid_mode
任何客户端使用此功能等待GTID应用时,都无法更改为OFF。
MySQL Enterprise Encryption是商业产品MySQL企业版中的扩展。 要了解有关商业产品的更多信息, 请访问https://www.mysql.com/products/ 。
MySQL Enterprise Edition包含一组基于OpenSSL库的加密函数,这些函数在SQL级别公开OpenSSL功能。 这些功能使企业应用程序能够执行以下操作:
使用公钥非对称加密实现增加的数据保护
创建公钥和私钥以及数字签名
执行非对称加密和解密
使用加密散列进行数字签名和数据验证和验证
MySQL Enterprise Encryption支持RSA,DSA和DH加密算法。
MySQL Enterprise Encryption作为用户定义函数(UDF)库提供,可以从中单独安装各个函数。
MySQL Enterprise Encryption函数位于插件目录(
plugin_dir
系统变量
指定的目录)中安装的用户定义函数(UDF)库文件中
。
UDF库基本名称
openssl_udf
和后缀是平台相关的。
例如,Linux或Windows上的文件名
分别
为
openssl_udf.so
或
openssl_udf.dll
。
要从库文件安装函数,请使用
CREATE
FUNCTION
语句。
要从库中加载所有函数,请使用这组语句(根据需要调整文件名后缀):
CREATE FUNCTION asymmetric_decrypt RETURNS STRING SONAME'openssl_udf.so'; CREATE FUNCTION asymmetric_derive RETURNS STRING SONAME'openssl_udf.so'; CREATE FUNCTION asymmetric_encrypt RETURNS STRING SONAME'openssl_udf.so'; CREATE FUNCTION asymmetric_sign RETURNS STRING SONAME'openssl_udf.so'; CREATE FUNCTION asymmetric_verify RETURNS INTEGER SONAME'openssl_udf.so'; 创建功能create_asymmetric_priv_key返回STRING SONAME'openssl_udf.so'; CREATE FUNCTION create_asymmetric_pub_key RETURNS STRING SONAME'openssl_udf.so'; 创建功能create_dh_parameters RETURNS STRING SONAME'openssl_udf.so'; CREATE FUNCTION create_digest RETURNS STRING SONAME'openssl_udf.so';
安装后,UDF将在服务器重新启动时保持安装状态。
要卸载UDF,请使用
DROP
FUNCTION
语句。
例如,要卸载密钥生成功能,请执行以下操作:
DROP FUNCTION create_asymmetric_priv_key; DROP FUNCTION create_asymmetric_pub_key;
在
CREATE
FUNCTION
和
DROP
FUNCTION
语句中,函数名必须以小写形式指定。
这与它们在函数调用时的使用不同,您可以使用任何字母。
该
CREATE
FUNCTION
和
DROP
FUNCTION
语句需要
INSERT
和
DROP
权限,分别为
mysql
数据库。
要在应用程序中使用MySQL Enterprise Encryption,请调用适合您要执行的操作的函数。 本节演示如何执行一些代表性任务:
- 加密演算法; 可以是“DSA”或“DH” SET @algo ='RSA'; - 密钥长度; 为更强的钥匙做大 SET @key_len = 1024; - 创建私钥 SET @priv = CREATE_ASYMMETRIC_PRIV_KEY(@ algo,@ key_len); - 使用相同的算法从私钥导出相应的公钥 SET @pub = CREATE_ASYMMETRIC_PUB_KEY(@algo,@ priv);
现在,您可以使用密钥对来加密和解密数据,签名和验证数据,或生成对称密钥。
这要求密钥对的成员是RSA密钥。
SET @ciphertext = ASYMMETRIC_ENCRYPT(@algo,'我的秘密文本',@ priv); SET @plaintext = ASYMMETRIC_DECRYPT(@ algo,@ ciphertext,@ pub);
相反,您可以使用公钥进行加密并使用私钥进行解密。
SET @ciphertext = ASYMMETRIC_ENCRYPT(@algo,'我的秘密文本',@ pub); SET @plaintext = ASYMMETRIC_DECRYPT(@ algo,@ ciphertext,@ priv);
在任何一种情况下,为加密和解密函数指定的算法必须与用于生成密钥的算法匹配。
- 摘要类型; 可以是'SHA256','SHA384'或'SHA512' SET @dig_type ='SHA224'; - 生成摘要字符串 SET @dig = CREATE_DIGEST(@dig_type,'我要消化的文字');
密钥对可用于签署数据,然后验证签名是否与摘要匹配。
- 加密演算法; 可能是'DSA'; 钥匙必须 - 使用相同的算法创建 SET @algo ='RSA'; - 为摘要生成签名并根据摘要验证签名 SET @sig = ASYMMETRIC_SIGN(@ algo,@ dig,@ priv,@ dig_type); - 验证签名与摘要 SET @verf = ASYMMETRIC_VERIFY(@ algo,@ dig,@ sig,@ pub,@ dig_type);
这需要DH私钥/公钥作为输入,使用共享的对称秘密创建。
通过传递密钥长度来创建秘密
CREATE_DH_PARAMETERS()
,然后将密钥作为
“
密钥长度
”
传递给
CREATE_ASYMMETRIC_PRIV_KEY()
。
- 生成DH共享对称秘密 SET @dhp = CREATE_DH_PARAMETERS(1024); - 生成DH密钥对 SET @algo ='DH'; SET @ priv1 = CREATE_ASYMMETRIC_PRIV_KEY(@algo,@ dhp); SET @ pub1 = CREATE_ASYMMETRIC_PUB_KEY(@algo,@ priv1); SET @ priv2 = CREATE_ASYMMETRIC_PRIV_KEY(@algo,@ dhp); SET @ pub2 = CREATE_ASYMMETRIC_PUB_KEY(@algo,@ priv2); - 使用第一方的公钥生成对称密钥, - 第二方的私钥 SET @ sym1 = ASYMMETRIC_DERIVE(@ pub1,@ priv2); - 或使用第二方的公钥,第一方的私钥 SET @ sym2 = ASYMMETRIC_DERIVE(@ pub2,@ priv1);
可以在运行时使用创建的密钥串的值,并存储到一个变量或表
SET
,
SELECT
或
INSERT
:
SET @ priv1 = CREATE_ASYMMETRIC_PRIV_KEY('RSA',1024); SELECT CREATE_ASYMMETRIC_PRIV_KEY('RSA',1024)INTO @ priv2; INSERT INTO t(key_col)VALUES(CREATE_ASYMMETRIC_PRIV_KEY('RSA',1024));
存储在文件中的键字符串值可以
LOAD_FILE()
由具有该
FILE
权限的
用户
使用该
函数
读取
。
摘要和签名字符串可以类似地处理。
在
CREATE_ASYMMETRIC_PRIV_KEY()
与
CREATE_DH_PARAMETERS()
加密函数采用一个密钥长度参数,和CPU资源的这些功能所需的量随着密钥长度增加而增加。
对于某些安装,如果应用程序经常生成过长的密钥,则可能会导致CPU使用率不可接受。
OpenSSL为所有密钥强加最小密钥长度1,024位。
OpenSSL还为DSA和RSA密钥分别施加10,000位和16,384位
CREATE_ASYMMETRIC_PRIV_KEY()
的最大密钥长度,最大密钥长度为10,000位
CREATE_DH_PARAMETERS()
。
如果这些最大值太高,则可以使用三个环境变量来使MySQL服务器管理员为密钥生成设置较低的最大长度,从而限制CPU使用率:
MYSQL_OPENSSL_UDF_DSA_BITS_THRESHOLD
:最大DSA密钥长度(以位为单位)
CREATE_ASYMMETRIC_PRIV_KEY()
。
此变量的最小值和最大值为1,024和10,000。
MYSQL_OPENSSL_UDF_RSA_BITS_THRESHOLD
:最大RSA密钥长度(以位为单位)
CREATE_ASYMMETRIC_PRIV_KEY()
。
此变量的最小值和最大值分别为1,024和16,384。
MYSQL_OPENSSL_UDF_DH_BITS_THRESHOLD
:最大密钥长度(以位为单位)
CREATE_DH_PARAMETERS()
。
此变量的最小值和最大值为1,024和10,000。
要使用任何这些环境变量,请在启动服务器的进程的环境中设置它们。
如果设置,则它们的值优先于OpenSSL施加的最大密钥长度。
例如,要为DSA和RSA密钥设置最大密钥长度为4,096位
CREATE_ASYMMETRIC_PRIV_KEY()
,请设置以下变量:
export MYSQL_OPENSSL_UDF_DSA_BITS_THRESHOLD = 4096 export MYSQL_OPENSSL_UDF_RSA_BITS_THRESHOLD = 4096
该示例使用Bourne shell语法。 其他shell的语法可能不同。
表12.24 MySQL企业加密功能
名称 | 描述 |
---|---|
ASYMMETRIC_DECRYPT() |
使用私钥或公钥解密密文 |
ASYMMETRIC_DERIVE() |
从非对称密钥导出对称密钥 |
ASYMMETRIC_ENCRYPT() |
使用私钥或公钥加密明文 |
ASYMMETRIC_SIGN() |
从摘要生成签名 |
ASYMMETRIC_VERIFY() |
验证签名是否与摘要匹配 |
CREATE_ASYMMETRIC_PRIV_KEY() |
创建私钥 |
CREATE_ASYMMETRIC_PUB_KEY() |
创建公钥 |
CREATE_DH_PARAMETERS() |
生成共享DH密钥 |
CREATE_DIGEST() |
从字符串生成摘要 |
MySQL Enterprise Encryption功能具有以下一般特征:
对于错误类型或不正确数量的参数的参数,每个函数都会返回错误。
如果参数不适合允许函数执行所请求的操作,则它会
NULL
根据需要
返回
0或0。
例如,如果函数不支持指定的算法,密钥长度太短或太长,或者预期为PEM格式的密钥字符串的字符串不是有效密钥,则会发生这种情况。
(OpenSSL强加了自己的密钥长度限制,服务器管理员可以通过设置环境变量对最大密钥长度施加额外限制。请参见
第12.19.2节“MySQL Enterprise加密用法和示例”
。)
底层SSL库负责随机初始化。
其中一些函数采用加密算法参数。 下表按功能总结了支持的算法。
表12.25按功能支持的算法
功能 | 支持的算法 |
---|---|
ASYMMETRIC_DECRYPT() |
RSA |
ASYMMETRIC_DERIVE() |
DH |
ASYMMETRIC_ENCRYPT() |
RSA |
ASYMMETRIC_SIGN() |
RSA,DSA |
ASYMMETRIC_VERIFY() |
RSA,DSA |
CREATE_ASYMMETRIC_PRIV_KEY() |
RSA,DSA,DH |
CREATE_ASYMMETRIC_PUB_KEY() |
RSA,DSA,DH |
CREATE_DH_PARAMETERS() |
DH |
虽然您可以使用任何RSA,DSA或DH加密算法创建密钥,但其他带有关键参数的函数可能只接受某些类型的密钥。
例如,
ASYMMETRIC_ENCRYPT()
并且
ASYMMETRIC_DECRYPT()
只接受RSA密钥。
以下描述描述了MySQL Enterprise Encryption功能的调用序列。 有关其他示例和讨论,请参见 第12.19.2节“MySQL Enterprise Encryption用法和示例” 。
ASYMMETRIC_DECRYPT(
algorithm
,
crypt_str
,
key_str
)
使用给定的算法和密钥字符串解密加密的字符串,并将生成的明文作为二进制字符串返回。
如果解密失败,结果是
NULL
。
key_str
必须是PEM格式的有效密钥字符串。
为了成功解密,它必须是与
ASYMMETRIC_ENCRYPT()
用于生成加密字符串
的私钥或公钥字符串对应的公钥或私钥
字符串。
algorithm
表示用于创建密钥的加密算法。
支持的
algorithm
值:
'RSA'
有关用法示例,请参阅说明
ASYMMETRIC_ENCRYPT()
。
ASYMMETRIC_DERIVE(
pub_key_str
,
priv_key_str
)
使用一方的私钥和另一方的公钥来派生对称密钥,并将得到的密钥作为二进制字符串返回。
如果密钥派生失败,则结果为
NULL
。
pub_key_str
并且
priv_key_str
必须是PEM格式的有效密钥字符串。
必须使用DH算法创建它们。
假设您有两对公钥和私钥:
SET @dhp = CREATE_DH_PARAMETERS(1024); SET @ priv1 = CREATE_ASYMMETRIC_PRIV_KEY('DH',@ dhp); SET @ pub1 = CREATE_ASYMMETRIC_PUB_KEY('DH',@ priv1); SET @ priv2 = CREATE_ASYMMETRIC_PRIV_KEY('DH',@ dhp); SET @ pub2 = CREATE_ASYMMETRIC_PUB_KEY('DH',@ priv2);
进一步假设您使用一对中的私钥和另一对中的公钥来创建对称密钥字符串。 然后,这种对称的密钥身份关系成立:
ASYMMETRIC_DERIVE(@ pub1,@ priv2)= ASYMMETRIC_DERIVE(@ pub2,@ priv1)
ASYMMETRIC_ENCRYPT(
algorithm
,
str
,
key_str
)
使用给定的算法和密钥字符串加密字符串,并将生成的密文作为二进制字符串返回。
如果加密失败,结果是
NULL
。
的
str
长度不能大于更大
key_str
长度- 11,以字节为单位
key_str
必须是PEM格式的有效密钥字符串。
algorithm
表示用于创建密钥的加密算法。
支持的
algorithm
值:
'RSA'
要加密字符串,请将私钥或公钥字符串传递给
ASYMMETRIC_ENCRYPT()
。
要恢复原始未加密的字符串,请将加密的字符串
ASYMMETRIC_DECRYPT()
与公钥或私钥字符串一起
传递
给与用于加密的私钥或公钥字符串相对应。
- 生成私钥/公钥对 SET @priv = CREATE_ASYMMETRIC_PRIV_KEY('RSA',1024); SET @pub = CREATE_ASYMMETRIC_PUB_KEY('RSA',@ priv); - 使用私钥加密,使用公钥解密 SET @ciphertext = ASYMMETRIC_ENCRYPT('RSA','快速棕狐',@ priv); SET @plaintext = ASYMMETRIC_DECRYPT('RSA',@ ciphertext,@ pub); - 使用公钥加密,使用私钥解密 SET @ciphertext = ASYMMETRIC_ENCRYPT('RSA','快速棕狐',@ pub); SET @plaintext = ASYMMETRIC_DECRYPT('RSA',@ ciphertext,@ priv);
假设:
SET @s =要加密的字符串 SET @priv = PEM格式的有效私有RSA密钥字符串 SET @pub = PEM格式的相应公共RSA密钥字符串
然后这些身份关系成立:
ASYMMETRIC_DECRYPT('RSA',ASYMMETRIC_ENCRYPT('RSA',@ s,@ priv),@ pub)= @s ASYMMETRIC_DECRYPT('RSA',ASYMMETRIC_ENCRYPT('RSA',@ s,@ pub),@ priv)= @s
ASYMMETRIC_SIGN(
algorithm
,
digest_str
,
priv_key_str
,
digest_type
)
使用私钥字符串签署摘要字符串,并将签名作为二进制字符串返回。
如果签名失败,结果是
NULL
。
digest_str
是摘要字符串。
它可以通过调用生成
CREATE_DIGEST()
。
digest_type
表示用于生成摘要字符串的摘要算法。
priv_key_str
是用于对摘要字符串进行签名的私钥字符串。
它必须是PEM格式的有效密钥字符串。
algorithm
表示用于创建密钥的加密算法。
支持的
algorithm
值:
'RSA'
,
'DSA'
支持的
digest_type
值:
'SHA224'
,
'SHA256'
,
'SHA384'
,
'SHA512'
有关用法示例,请参阅说明
ASYMMETRIC_VERIFY()
。
ASYMMETRIC_VERIFY(
algorithm
,
digest_str
,
sig_str
,
pub_key_str
,
digest_type
)
验证签名字符串是否与摘要字符串匹配,并返回1或0以指示验证是成功还是失败。
digest_str
是摘要字符串。
它可以通过调用生成
CREATE_DIGEST()
。
digest_type
表示用于生成摘要字符串的摘要算法。
sig_str
是签名字符串。
它可以通过调用生成
ASYMMETRIC_SIGN()
。
pub_key_str
是签名者的公钥字符串。
它对应于传递给
ASYMMETRIC_SIGN()
生成签名字符串
的私钥,
并且必须是PEM格式的有效密钥字符串。
algorithm
表示用于创建密钥的加密算法。
支持的
algorithm
值:
'RSA'
,
'DSA'
支持的
digest_type
值:
'SHA224'
,
'SHA256'
,
'SHA384'
,
'SHA512'
- 设置加密算法和摘要类型 SET @algo ='RSA'; SET @dig_type ='SHA224'; - 创建私钥/公钥对 SET @priv = CREATE_ASYMMETRIC_PRIV_KEY(@algo,1024); SET @pub = CREATE_ASYMMETRIC_PUB_KEY(@algo,@ priv); - 从字符串生成摘要 SET @dig = CREATE_DIGEST(@dig_type,'快速棕狐'); - 为摘要生成签名并根据摘要验证签名 SET @sig = ASYMMETRIC_SIGN(@ algo,@ dig,@ priv,@ dig_type); SET @verf = ASYMMETRIC_VERIFY(@ algo,@ dig,@ sig,@ pub,@ dig_type);
CREATE_ASYMMETRIC_PRIV_KEY(
algorithm
,
{key_len
|dh_secret
})
使用给定的算法和密钥长度或DH密钥创建私钥,并将密钥作为PEM格式的二进制字符串返回。
如果密钥生成失败,结果是
NULL
。
支持的
algorithm
值:
'RSA'
,
'DSA'
,
'DH'
支持的
key_len
值:最小密钥长度(以位为单位)为1,024。
最大密钥长度取决于算法:RSA为16,384,DSA为10,000。
这些密钥长度限制是OpenSSL强加的约束。
服务器管理员可以通过设置环境变量对最大密钥长度施加额外限制。
请参见
第12.19.2节“MySQL Enterprise Encryption用法和示例”
。
对于DH密钥,传递共享DH密钥而不是密钥长度。
要创建密钥,请将密钥长度传递给
CREATE_DH_PARAMETERS()
。
此示例创建一个2,048位DSA私钥,然后从私钥派生公钥:
SET @priv = CREATE_ASYMMETRIC_PRIV_KEY('DSA',2048); SET @pub = CREATE_ASYMMETRIC_PUB_KEY('DSA',@ priv);
有关显示DH密钥生成的示例,请参阅说明
ASYMMETRIC_DERIVE()
。
选择密钥长度和加密算法时的一些一般注意事项:
私钥和公钥的加密强度随密钥大小的增加而增加,但密钥生成的时间也会增加。
DH密钥的生成比RSA或RSA密钥花费更长的时间。
非对称加密函数比对称函数慢。
如果性能是一个重要因素,并且要经常使用这些功能,那么最好使用对称加密。
例如,考虑使用
AES_ENCRYPT()
和
AES_DECRYPT()
。
CREATE_ASYMMETRIC_PUB_KEY(
algorithm
,
priv_key_str
)
使用给定算法从给定私钥派生公钥,并将密钥作为PEM格式的二进制字符串返回。
如果密钥派生失败,则结果为
NULL
。
priv_key_str
必须是PEM格式的有效密钥字符串。
algorithm
表示用于创建密钥的加密算法。
支持的
algorithm
值:
'RSA'
,
'DSA'
,
'DH'
有关用法示例,请参阅说明
CREATE_ASYMMETRIC_PRIV_KEY()
。
创建用于生成DH私钥/公钥对的共享密钥,并返回可传递给的二进制字符串
CREATE_ASYMMETRIC_PRIV_KEY()
。
如果秘密生成失败,则结果为null。
支持的
key_len
值:最小和最大密钥长度(以位为单位)为1,024和10,000。
这些密钥长度限制是OpenSSL强加的约束。
服务器管理员可以通过设置环境变量对最大密钥长度施加额外限制。
请参见
第12.19.2节“MySQL Enterprise Encryption用法和示例”
。
有关如何使用返回值生成对称密钥的示例,请参阅的说明
ASYMMETRIC_DERIVE()
。
SET @dhp = CREATE_DH_PARAMETERS(1024);
CREATE_DIGEST(
digest_type
,
str
)
使用给定的摘要类型从给定字符串创建摘要,并将摘要作为二进制字符串返回。
如果摘要生成失败,结果是
NULL
。
支持的
digest_type
值:
'SHA224'
,
'SHA256'
,
'SHA384'
,
'SHA512'
SET @dig = CREATE_DIGEST('SHA512',快棕狐');
生成的摘要字符串适合与
ASYMMETRIC_SIGN()
和
一起使用
ASYMMETRIC_VERIFY()
。
本节介绍对值集合进行操作的组(聚合)函数。
表12.26聚合(GROUP BY)函数
名称 | 描述 |
---|---|
AVG() |
返回参数的平均值 |
BIT_AND() |
按位返回AND |
BIT_OR() |
按位返回OR |
BIT_XOR() |
按位返回异或 |
COUNT() |
返回返回的行数 |
COUNT(DISTINCT) |
返回许多不同值的计数 |
GROUP_CONCAT() |
返回连接的字符串 |
JSON_ARRAYAGG() |
将结果集作为单个JSON数组返回 |
JSON_OBJECTAGG() |
将结果集作为单个JSON对象返回 |
MAX() |
返回最大值 |
MIN() |
返回最小值 |
STD() |
返回人口标准差 |
STDDEV() |
返回人口标准差 |
STDDEV_POP() |
返回人口标准差 |
STDDEV_SAMP() |
返回样本标准差 |
SUM() |
归还总和 |
VAR_POP() |
返回人口标准差异 |
VAR_SAMP() |
返回样本方差 |
VARIANCE() |
返回人口标准差异 |
除非另有说明,否则组函数会忽略
NULL
值。
如果在包含无
GROUP BY
子句
的语句中使用组函数
,则等效于对所有行进行分组。
有关更多信息,请参见
第12.20.3节“GROUP BY的MySQL处理”
。
大多数聚合函数可用作窗口函数。
可以这种方式使用的那些在它们的语法描述中表示
,表示可选
子句。
在
第12.21.2节“窗口函数概念和语法”中进行了描述
,其中还包含有关窗口函数用法的其他信息。
[
over_clause
]OVER
over_clause
对于数字参数,方差和标准差函数返回一个
DOUBLE
值。
的
SUM()
和
AVG()
函数返回一个
DECIMAL
为准确值参数(整数或值
DECIMAL
),以及
DOUBLE
为近似值参数(值
FLOAT
或
DOUBLE
)。
在
SUM()
和
AVG()
聚合函数不具有时间价值的工作。
(它们将值转换为数字,在第一个非数字字符后丢失所有内容。)要解决此问题,请转换为数字单位,执行聚合操作,然后转换回时间值。
例子:
SELECT SEC_TO_TIME(SUM(TIME_TO_SEC(time_col
)))FROMtbl_name
; SELECT FROM_DAYS(SUM(TO_DAYS(date_col
)))FROMtbl_name
;
如果需要,
诸如
SUM()
或
AVG()
期望数字参数的函数将参数强制转换为数字。
对于
SET
或
ENUM
值,强制转换操作会导致使用基础数值。
的
BIT_AND()
,
BIT_OR()
和
BIT_XOR()
聚合函数执行位操作。
在MySQL 8.0之前,位函数和运算符需要
BIGINT
(64位整数)参数和返回
BIGINT
值,因此它们的最大范围为64位。
非
BIGINT
参数
BIGINT
在执行操作之前
被转换为
可能发生截断。
在MySQL 8.0中,位函数和运算符允许二进制字符串类型参数(
BINARY
,
VARBINARY
和
BLOB
类型)并返回类似的值,这使它们能够获取参数并生成大于64位的返回值。
有关位操作的参数评估和结果类型的讨论,请参见
第12.12节“位功能和操作符”中
的介绍性讨论
。
AVG([DISTINCT]
expr
)
[over_clause
]
返回的平均值
。
该
expr
DISTINCT
选项可用于返回不同值的平均值
expr
。
如果没有匹配的行,则
AVG()
返回
NULL
。
如果
over_clause
存在,
该函数作为窗口函数执行
。
over_clause
如
第12.21.2节“窗口函数概念和语法”中所述
;
它不能用于
DISTINCT
。
MySQL的>SELECT student_name, AVG(test_score)
FROM student
GROUP BY student_name;
返回
AND
所有位
的按
位
expr
。
结果类型取决于函数参数值是作为二进制字符串还是数字计算:
当参数值具有二进制字符串类型且参数不是十六进制文字,位字面值或
NULL
文字
时,会发生二进制字符串评估
。
否则进行数值计算,必要时将参数值转换为无符号64位整数。
二进制字符串评估生成与参数值长度相同的二进制字符串。
如果参数值具有不相等的长度,
ER_INVALID_BITWISE_OPERANDS_SIZE
则会发生错误。
如果参数大小超过511个字节,
ER_INVALID_BITWISE_AGGREGATE_OPERANDS_SIZE
则会发生错误。
数值计算生成无符号的64位整数。
如果没有匹配的行,则
BIT_AND()
返回与参数值具有相同长度的中性值(所有位设置为1)。
NULL
除非所有值都是,否则值不会影响结果
NULL
。
在这种情况下,结果是具有与参数值相同长度的中性值。
有关参数评估和结果类型的更多信息讨论,请参见 第12.12节“位功能和操作符”中 的介绍性讨论 。
从MySQL 8.0.12开始,如果
over_clause
存在
,该函数将作为窗口函数执行
。
over_clause
如
第12.21.2节“窗口函数概念和语法”中所述
。
返回
OR
所有位
的按
位
expr
。
结果类型取决于函数参数值是作为二进制字符串还是数字计算:
当参数值具有二进制字符串类型且参数不是十六进制文字,位字面值或
NULL
文字
时,会发生二进制字符串评估
。
否则进行数值计算,必要时将参数值转换为无符号64位整数。
二进制字符串评估生成与参数值长度相同的二进制字符串。
如果参数值具有不相等的长度,
ER_INVALID_BITWISE_OPERANDS_SIZE
则会发生错误。
如果参数大小超过511个字节,
ER_INVALID_BITWISE_AGGREGATE_OPERANDS_SIZE
则会发生错误。
数值计算生成无符号的64位整数。
如果没有匹配的行,则
BIT_OR()
返回与参数值具有相同长度的中性值(所有位设置为0)。
NULL
除非所有值都是,否则值不会影响结果
NULL
。
在这种情况下,结果是具有与参数值相同长度的中性值。
有关参数评估和结果类型的更多信息讨论,请参见 第12.12节“位功能和操作符”中 的介绍性讨论 。
从MySQL 8.0.12开始,如果
over_clause
存在
,该函数将作为窗口函数执行
。
over_clause
如
第12.21.2节“窗口函数概念和语法”中所述
。
返回
XOR
所有位
的按
位
expr
。
结果类型取决于函数参数值是作为二进制字符串还是数字计算:
当参数值具有二进制字符串类型且参数不是十六进制文字,位字面值或
NULL
文字
时,会发生二进制字符串评估
。
否则进行数值计算,必要时将参数值转换为无符号64位整数。
二进制字符串评估生成与参数值长度相同的二进制字符串。
如果参数值具有不相等的长度,
ER_INVALID_BITWISE_OPERANDS_SIZE
则会发生错误。
如果参数大小超过511个字节,
ER_INVALID_BITWISE_AGGREGATE_OPERANDS_SIZE
则会发生错误。
数值计算生成无符号的64位整数。
如果没有匹配的行,则
BIT_XOR()
返回与参数值具有相同长度的中性值(所有位设置为0)。
NULL
除非所有值都是,否则值不会影响结果
NULL
。
在这种情况下,结果是具有与参数值相同长度的中性值。
有关参数评估和结果类型的更多信息讨论,请参见 第12.12节“位功能和操作符”中 的介绍性讨论 。
从MySQL 8.0.12开始,如果
over_clause
存在
,该函数将作为窗口函数执行
。
over_clause
如
第12.21.2节“窗口函数概念和语法”中所述
。
返回
语句
检索的行
中非
NULL
值
数的计数
。
结果是一个
值。
expr
SELECT
BIGINT
如果没有匹配的行,则
COUNT()
返回
0
。
如果
over_clause
存在,
该函数作为窗口函数执行
。
over_clause
如...中所述
第12.21.2节“窗口函数概念和语法”中所述
。
MySQL的>SELECT student.student_name,COUNT(*)
FROM student,course
WHERE student.student_id=course.student_id
GROUP BY student_name;
COUNT(*)
有点不同,它返回检索的行数,无论它们是否包含
NULL
值。
对于事务性存储引擎,例如
InnoDB
,存储精确的行数是有问题的。
多个交易可能同时发生,每个交易都可能影响计数。
InnoDB
不保留表中的内部行数,因为并发事务可能同时
“
看到
”
不同数量的行。
因此,
SELECT COUNT(*)
语句只计算当前事务可见的行。
从MySQL 8.0.13开始,
如果没有诸如
或之类的
额外子句,则针对单线程工作负载优化表的
查询性能
。
SELECT COUNT(*) FROM
tbl_name
InnoDB
WHERE
GROUP BY
InnoDB
SELECT
COUNT(*)
通过遍历最小的可用二级索引来
处理
语句,除非索引或优化程序提示指示优化程序使用不同的索引。
如果不存在辅助索引,则
通过扫描聚簇索引来
InnoDB
处理
SELECT COUNT(*)
语句。
SELECT COUNT(*)
如果索引记录不完全在缓冲池中,则
处理
语句需要一些时间。
为了更快地计算,请创建一个计数器表,让应用程序根据插入和删除更新它。
但是,在数千个并发事务正在启动对同一计数器表的更新的情况下,此方法可能无法很好地扩展。
如果大概行数足够,请使用
SHOW TABLE STATUS
。
InnoDB
以相同的方式
处理
SELECT
COUNT(*)
和
SELECT COUNT(1)
操作。
没有性能差异。
对于
MyISAM
表,
COUNT(*)
如果
SELECT
从一个表检索,没有检索到其他列,并且没有
WHERE
子句
,
则优化为非常快速地返回
。
例如:
MySQL的> SELECT COUNT(*) FROM student;
此优化仅适用于
MyISAM
表,因为为此存储引擎存储了精确的行数,并且可以非常快速地访问。
COUNT(1)
如果第一列定义为,则仅受相同优化的影响
NOT
NULL
。
COUNT(DISTINCT
expr
,[expr
...])
返回具有不同非
NULL
expr
值
的行数
。
如果没有匹配的行,则
COUNT(DISTINCT)
返回
0
。
MySQL的> SELECT COUNT(DISTINCT results) FROM student;
在MySQL中,您可以
NULL
通过提供表达式列表
来获取不包含的不同表达式组合的数量
。
在标准SQL中,您必须对内部的所有表达式进行连接
COUNT(DISTINCT ...)
。
此函数返回字符串结果,其中
NULL
包含来自组
的连接非
值。
NULL
如果没有非
NULL
值
,则返回
。
完整语法如下:
GROUP_CONCAT([DISTINCT]expr
[,expr
...] [ORDER BY {unsigned_integer
|col_name
|expr
} [ASC | DESC] [,col_name
...]] [SEPARATORstr_val
])
MySQL的>SELECT student_name,
GROUP_CONCAT(test_score)
FROM student
GROUP BY student_name;
要么:
MySQL的>SELECT student_name,
GROUP_CONCAT(DISTINCT test_score
ORDER BY test_score DESC SEPARATOR ' ')
FROM student
GROUP BY student_name;
在MySQL中,您可以获得表达式组合的连接值。
要消除重复值,请使用该
DISTINCT
子句。
要对结果中的值进行排序,请使用该
ORDER BY
子句。
要按相反顺序排序,请将
DESC
(descending)关键字
添加
到要在
ORDER BY
子句
中排序的列的名称中
。
默认为升序;
这可以使用
ASC
关键字
明确指定
。
组中值之间的默认分隔符是逗号(
,
)。
要明确指定分隔符,请使用
SEPARATOR
后跟应在组值之间插入的字符串文字值。
要完全消除分隔符,请指定
SEPARATOR ''
。
结果被截断为
group_concat_max_len
系统变量
给出的最大长度
,其默认值为1024.尽管返回值的有效最大长度受值的约束,但该值可以设置得更高
max_allowed_packet
。
group_concat_max_len
在运行时
更改值的语法
如下,其中
val
是无符号整数:
SET [GLOBAL | SESSION] group_concat_max_len = val
;
返回值是非二进制或二进制字符串,具体取决于参数是非二进制还是二进制字符串。
结果类型是
TEXT
或者
BLOB
除非
group_concat_max_len
小于或等于512,在这种情况下结果类型是
VARCHAR
或
VARBINARY
。
另见
CONCAT()
和
CONCAT_WS()
:
第12.5节“字符串函数”
。
JSON_ARRAYAGG(
col_or_expr
)
[over_clause
]
将结果集聚合为单个
JSON
数组,其元素由行组成。
此数组中元素的顺序未定义。
该函数作用于计算为单个值的列或表达式。
返回
NULL
如果结果不包含任何行,或在错误的事件。
从MySQL 8.0.14开始,如果
over_clause
存在
,该函数将作为窗口函数执行
。
over_clause
如
第12.21.2节“窗口函数概念和语法”中所述
。
MySQL的>SELECT o_id, attribute, value FROM t3;
+ ------ + ----------- + -------- + | o_id | 属性| 价值| + ------ + ----------- + -------- + | 2 | 颜色| 红色| | 2 | 面料| 丝绸| | 3 | 颜色| 绿色| | 3 | 形状| 广场| + ------ + ----------- + -------- + 4行(0.00秒) MySQL的>SELECT o_id, JSON_ARRAYAGG(attribute) AS attributes
FROM t3 GROUP BY o_id;
+ ------ + --------------------- + | o_id | 属性| + ------ + --------------------- + | 2 | [“颜色”,“面料”] | | 3 | [“颜色”,“形状”] | + ------ + --------------------- + 2行(0.00秒)
JSON_OBJECTAGG(
key
,
value
)
[over_clause
]
将两个列名或表达式作为参数,第一个用作键,第二个用作值,并返回包含键值对的JSON对象。
返回
NULL
如果结果不包含任何行,或在错误的事件。
如果任何键名称
NULL
或参数数量不等于2,
则会发生错误
。
从MySQL 8.0.14开始,如果
over_clause
存在
,该函数将作为窗口函数执行
。
over_clause
如
第12.21.2节“窗口函数概念和语法”中所述
。
MySQL的>SELECT o_id, attribute, value FROM t3;
+ ------ + ----------- + -------- + | o_id | 属性| 价值| + ------ + ----------- + -------- + | 2 | 颜色| 红色| | 2 | 面料| 丝绸| | 3 | 颜色| 绿色| | 3 | 形状| 广场| + ------ + ----------- + -------- + 4行(0.00秒) MySQL的>SELECT o_id, JSON_OBJECTAGG(attribute, value)
FROM t3 GROUP BY o_id;
+ ------ + --------------------------------------- + | o_id | JSON_OBJECTAGG(属性,值)| + ------ + --------------------------------------- + | 2 | {“color”:“red”,“fabric”:“silk”} | 3 | {“color”:“green”,“shape”:“square”} | + ------ + --------------------------------------- + 2行(0.00秒)
当对该函数的结果进行归一化时,丢弃具有重复键的值。
为了与
JSON
不允许重复键
的MySQL
数据类型规范
保持一致
,只有遇到的最后一个值与返回对象中的该键一起使用(
“
最后重复键获胜
”
)。
这意味着在a的列上使用此函数的结果
SELECT
可以取决于返回行的顺序,这是不能保证的。
当用作窗口函数时,如果帧中存在重复的键,则结果中仅存在该键的最后一个值。
如果
ORDER BY
规范保证值具有特定顺序
,则帧中最后一行的键值是确定的
。
如果不是,则键的结果值是不确定的。
考虑以下:
MySQL的>CREATE TABLE t(c VARCHAR(10), i INT);
查询正常,0行受影响(0.03秒) MySQL的>INSERT INTO t VALUES
('key', 3), ('key', 4), ('key', 5);
查询OK,3行受影响(0.01秒) 记录:3个重复:0个警告:0 MySQL的>SELECT c, i FROM t;
+ ------ + ------ + | c | 我| + ------ + ------ + | 关键| 3 | | 关键| 4 | | 关键| 5 | + ------ + ------ + 3组(0.00秒) MySQL的>SELECT JSON_OBJECTAGG(c, i) FROM t;
+ ---------------------- + | JSON_OBJECTAGG(c,i)| + ---------------------- + | {“key”:5} | + ---------------------- + 1排(0.00秒) MySQL的>DELETE FROM t;
查询OK,3行受影响(0.00秒) MySQL的>INSERT INTO t VALUES
('key', 3), ('key', 5), ('key', 4);
查询OK,3行受影响(0.00秒) 记录:3个重复:0个警告:0 MySQL的>SELECT c, i FROM t;
+ ------ + ------ + | c | 我| + ------ + ------ + | 关键| 3 | | 关键| 5 | | 关键| 4 | + ------ + ------ + 3组(0.00秒) MySQL的>SELECT JSON_OBJECTAGG(c, i) FROM t;
+ ---------------------- + | JSON_OBJECTAGG(c,i)| + ---------------------- + | {“key”:4} | + ---------------------- + 1排(0.00秒)
从上一个查询中选择的密钥是不确定的。
如果您更喜欢特定的键排序,则可以
JSON_OBJECTAGG()
通过包含
OVER
带有
ORDER BY
规范
的
子句
来调用
作为窗口函数,
以在帧行上强加特定顺序。
以下示例显示了
ORDER BY
对于一些不同的帧规范
会发生和不发生的情况
。
没有
ORDER BY
,框架是整个分区:
MySQL的>SELECT JSON_OBJECTAGG(c, i)
OVER () AS json_object FROM t;
+ ------------- + | json_object | + ------------- + | {“key”:4} | | {“key”:4} | | {“key”:4} | + ------------- +
with
ORDER BY
,其中框架是默认值
RANGE BETWEEN UNBOUNDED PRECEDING AND
CURRENT ROW
(按升序和降序排列):
MySQL的>SELECT JSON_OBJECTAGG(c, i)
OVER (ORDER BY i) AS json_object FROM t;
+ ------------- + | json_object | + ------------- + | {“key”:3} | | {“key”:4} | | {“key”:5} | + ------------- + MySQL的>SELECT JSON_OBJECTAGG(c, i)
OVER (ORDER BY i DESC) AS json_object FROM t;
+ ------------- + | json_object | + ------------- + | {“key”:5} | | {“key”:4} | | {“key”:3} | + ------------- +
使用
ORDER BY
和整个分区的显式框架:
MySQL的>SELECT JSON_OBJECTAGG(c, i)
OVER (ORDER BY i
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
AS json_object
FROM t;
+ ------------- + | json_object | + ------------- + | {“key”:5} | | {“key”:5} | | {“key”:5} | + ------------- +
要返回特定键值(例如最小值或最大值),请
LIMIT
在相应的查询中
包含一个
子句。
例如:
MySQL的>SELECT JSON_OBJECTAGG(c, i)
OVER (ORDER BY i) AS json_object FROM t LIMIT 1;
+ ------------- + | json_object | + ------------- + | {“key”:3} | + ------------- + MySQL的>SELECT JSON_OBJECTAGG(c, i)
OVER (ORDER BY i DESC) AS json_object FROM t LIMIT 1;
+ ------------- + | json_object | + ------------- + | {“key”:5} | + ------------- +
有关 其他信息和示例 , 请参阅 JSON值的规范化,合并和自动包装 。
MAX([DISTINCT]
expr
)
[over_clause
]
返回的最大值
expr
。
MAX()
可以采用字符串参数;
在这种情况下,它返回最大字符串值。
请参见
第8.3.1节“MySQL如何使用索引”
。
的
DISTINCT
关键字可用于以找到最大的不同值中的
expr
,然而,这产生相同的结果作为遗漏
DISTINCT
。
如果没有匹配的行,则
MAX()
返回
NULL
。
如果
over_clause
存在,
该函数作为窗口函数执行
。
over_clause
如
第12.21.2节“窗口函数概念和语法”中所述
;
它不能用于
DISTINCT
。
MySQL的>SELECT student_name, MIN(test_score), MAX(test_score)
FROM student
GROUP BY student_name;
因为
MAX()
,MySQL当前
按字符串值
比较
ENUM
和
SET
列,而不是字符串在集合中的相对位置。
这与
ORDER BY
比较它们
有所不同
。
MIN([DISTINCT]
expr
)
[over_clause
]
返回的最小值
expr
。
MIN()
可以采用字符串参数;
在这种情况下,它返回最小字符串值。
请参见
第8.3.1节“MySQL如何使用索引”
。
的
DISTINCT
关键字可用来找到最小的不同值中的
expr
,然而,这产生相同的结果作为遗漏
DISTINCT
。
如果没有匹配的行,则
MIN()
返回
NULL
。
如果
over_clause
存在,
该函数作为窗口函数执行
。
over_clause
如
第12.21.2节“窗口函数概念和语法”中所述
;
它不能用于
DISTINCT
。
MySQL的>SELECT student_name, MIN(test_score), MAX(test_score)
FROM student
GROUP BY student_name;
因为
MIN()
,MySQL当前
按字符串值
比较
ENUM
和
SET
列,而不是字符串在集合中的相对位置。
这与
ORDER BY
比较它们
有所不同
。
返回人口标准差
expr
。
STD()
是标准SQL函数的同义词
STDDEV_POP()
,作为MySQL扩展提供。
如果没有匹配的行,则
STD()
返回
NULL
。
如果
over_clause
存在,
该函数作为窗口函数执行
。
over_clause
如
第12.21.2节“窗口函数概念和语法”中所述
。
返回人口标准差
expr
。
STDDEV()
是
STDDEV_POP()
与Oracle兼容
的标准SQL函数的同义词
。
如果没有匹配的行,则
STDDEV()
返回
NULL
。
如果
over_clause
存在,
该函数作为窗口函数执行
。
over_clause
如
第12.21.2节“窗口函数概念和语法”中所述
。
STDDEV_POP(
expr
)
[over_clause
]
返回
expr
(平方根
VAR_POP()
)
的总体标准差
。
你也可以使用
STD()
或
STDDEV()
等效但不是标准SQL。
如果没有匹配的行,则
STDDEV_POP()
返回
NULL
。
如果
over_clause
存在,
该函数作为窗口函数执行
。
over_clause
如
第12.21.2节“窗口函数概念和语法”中所述
。
STDDEV_SAMP(
expr
)
[over_clause
]
返回样本标准差
expr
(的平方根)
VAR_SAMP()
。
如果没有匹配的行,则
STDDEV_SAMP()
返回
NULL
。
如果
over_clause
存在,
该函数作为窗口函数执行
。
over_clause
如
第12.21.2节“窗口函数概念和语法”中所述
。
SUM([DISTINCT]
expr
)
[over_clause
]
返回的总和
expr
。
如果返回集没有行,则
SUM()
返回
NULL
。
的
DISTINCT
关键字可用来仅求和的不同的值
expr
。
如果没有匹配的行,则
SUM()
返回
NULL
。
如果
over_clause
存在,
该函数作为窗口函数执行
。
over_clause
如
第12.21.2节“窗口函数概念和语法”中所述
;
它不能用于
DISTINCT
。
返回人口标准方差
expr
。
它将行视为整个总体,而不是作为样本,因此它将行数作为分母。
您也可以使用
VARIANCE()
,这是等效的但不是标准SQL。
如果没有匹配的行,则
VAR_POP()
返回
NULL
。
如果
over_clause
存在,
该函数作为窗口函数执行
。
over_clause
如
第12.21.2节“窗口函数概念和语法”中所述
。
返回样本方差
expr
。
也就是说,分母是行数减1。
如果没有匹配的行,则
VAR_SAMP()
返回
NULL
。
如果
over_clause
存在,
该函数作为窗口函数执行
。
over_clause
如
第12.21.2节“窗口函数概念和语法”中所述
。
返回人口标准方差
expr
。
VARIANCE()
是标准SQL函数的同义词
VAR_POP()
,作为MySQL扩展提供。
如果没有匹配的行,则
VARIANCE()
返回
NULL
。
如果
over_clause
存在,
该函数作为窗口函数执行
。
over_clause
如
第12.21.2节“窗口函数概念和语法”中所述
。
该
GROUP BY
子句允许使用一个
WITH
ROLLUP
修饰符,使得汇总输出包含表示更高级别(即超级聚合)汇总操作的额外行。
ROLLUP
因此,您可以使用单个查询在多个分析级别回答问题。
例如,
ROLLUP
可用于为OLAP(在线分析处理)操作提供支持。
假设一个
sales
表有
year
,
country
,
product
,和
profit
列记录销售利润率:
CREATE TABLE销售 ( 年INT, country VARCHAR(20), 产品VARCHAR(32), 利润INT );
要总结每年的表格内容,请使用以下简单的内容
GROUP BY
:
MySQL的>SELECT year, SUM(profit) AS profit
FROM sales
GROUP BY year;
+ ------ + -------- + | 一年| 利润| + ------ + -------- + | 2000年| 4525 | | 2001 | 3010 | + ------ + -------- +
输出显示每年的总(总)利润。
要确定所有年份的总利润总额,您必须自己添加单个值或运行其他查询。
或者您可以使用
ROLLUP
,它通过单个查询提供两种级别的分析。
向
子句
添加
WITH ROLLUP
修饰符
GROUP
BY
会导致查询生成另一个(超级聚合)行,该行显示所有年份值的总计:
MySQL的>SELECT year, SUM(profit) AS profit
FROM sales
GROUP BY year WITH ROLLUP;
+ ------ + -------- + | 一年| 利润| + ------ + -------- + | 2000年| 4525 | | 2001 | 3010 | | NULL | 7535 | + ------ + -------- +
列中
的
NULL
值
year
标识总计超级聚合行。
ROLLUP
当有多
GROUP BY
列
时,会产生更复杂的效果
。
在这种情况下,每次除最后一个分组列之外的任何值发生更改时,查询都会生成一个额外的超级聚合摘要行。
例如,如果没有
ROLLUP
,该摘要
sales
基于表
year
,
country
以及
product
可能是这样的,当输出只在一年/国家/产品的分析水平表明汇总值:
MySQL的>SELECT year, country, product, SUM(profit) AS profit
FROM sales
GROUP BY year, country, product;
+ ------ + --------- + ------------ + -------- + | 一年| 国家| 产品| 利润| + ------ + --------- + ------------ + -------- + | 2000年| 芬兰| 电脑| 1500 | | 2000年| 芬兰| 电话| 100 | | 2000年| 印度| 计算器| 150 | | 2000年| 印度| 电脑| 1200 | | 2000年| 美国| 计算器| 75 | | 2000年| 美国| 电脑| 1500 | | 2001 | 芬兰| 电话| 10 | | 2001 | 美国| 计算器| 50 | | 2001 | 美国| 电脑| 2700 | | 2001 | 美国| 电视| 250 | + ------ + --------- + ------------ + -------- +
随着
ROLLUP
增加,查询会产生一些额外行:
MySQL的>SELECT year, country, product, SUM(profit) AS profit
FROM sales
GROUP BY year, country, product WITH ROLLUP;
+ ------ + --------- + ------------ + -------- + | 一年| 国家| 产品| 利润| + ------ + --------- + ------------ + -------- + | 2000年| 芬兰| 电脑| 1500 | | 2000年| 芬兰| 电话| 100 | | 2000年| 芬兰| NULL | 1600 | | 2000年| 印度| 计算器| 150 | | 2000年| 印度| 电脑| 1200 | | 2000年| 印度| NULL | 1350 | | 2000年| 美国| 计算器| 75 | | 2000年| 美国| 电脑| 1500 | | 2000年| 美国| NULL | 1575 | | 2000年| NULL | NULL | 4525 | | 2001 | 芬兰| 电话| 10 | | 2001 | 芬兰| NULL | 10 | | 2001 | 美国| 计算器| 50 | | 2001 | 美国| 电脑| 2700 | | 2001 | 美国| 电视| 250 | | 2001 | 美国| NULL | 3000 | | 2001 | NULL | NULL | 3010 | | NULL | NULL | NULL | 7535 | + ------ + --------- + ------------ + -------- +
现在输出包括四个分析级别的摘要信息,而不仅仅是一个:
在给定年份和国家/地区的每组产品行之后,将显示额外的超级汇总摘要行,显示所有产品的总计。
这些行的
product
列设置为
NULL
。
在给定年份的每组行之后,将显示一个额外的超级汇总摘要行,显示所有国家/地区和产品的总计。
这些行具有
country
与
products
列设置为
NULL
。
最后,在所有其他行之后,将显示一个额外的超级汇总摘要行,显示所有年份,国家/地区和产品的总计。
此行的
year
,,
country
和
products
列设置为
NULL
。
将
NULL
行发送到客户端时,将生成每个超级聚合行中
的
指示符。
服务器查看
GROUP BY
最左边的一个已更改值
的
子句中
指定的列
。
对于结果集中具有与任何名称匹配的名称的任何列,其值设置为
NULL
。
(如果按列位置指定分组列,则服务器会
NULL
按位置
标识要设置的列
。)
由于
NULL
超级聚合行中
的
值在查询处理的后期阶段放入结果集中,因此
NULL
只能在选择列表或
HAVING
子句
中将
它们作为
值
进行测试
。
您无法
NULL
在连接条件或
WHERE
子句
中将
它们作为
值进行
测试,
以确定要选择的行。
例如,您无法添加
WHERE product IS
NULL
查询以从输出中消除除超级聚合行之外的所有行。
这些
NULL
值确实显示
NULL
在客户端,可以使用任何MySQL客户端编程接口进行测试。
但是,此时,您无法区分a
NULL
表示常规分组值还是超级聚合值。
要测试区别,请使用
GROUPING()
稍后描述
的
函数。
以前,MySQL不允许使用
DISTINCT
或
ORDER BY
在具有
WITH ROLLUP
选项
的查询中使用
。
在MySQL 8.0.12及更高版本中解除了此限制。
(Bug#87450,Bug#86311,Bug#26640100,Bug#26073513)
对于
GROUP BY ... WITH ROLLUP
查询,要测试
NULL
结果中的值
是否
表示超级聚合值,该
GROUPING()
函数可用于选择列表,
HAVING
子句和(从MySQL 8.0.12开始)
ORDER BY
子句。
例如,
在
列中发生超级聚合行时
GROUPING(year)
返回1
,否则
返回
0。
同样,
并
分别
在
和
列中
为超级聚合
值
返回1
:
NULL
year
GROUPING(country)
GROUPING(product)
NULL
country
product
MySQL的>SELECT
year, country, product, SUM(profit) AS profit,
GROUPING(year) AS grp_year,
GROUPING(country) AS grp_country,
GROUPING(product) AS grp_product
FROM sales
GROUP BY year, country, product WITH ROLLUP;
+ ------ + --------- + ------------ + -------- + ---------- + ------------- ------------- + + | 一年| 国家| 产品| 利润| grp_year | grp_country | grp_product | + ------ + --------- + ------------ + -------- + ---------- + ------------- ------------- + + | 2000年| 芬兰| 电脑| 1500 | 0 | 0 | 0 | | 2000年| 芬兰| 电话| 100 | 0 | 0 | 0 | | 2000年| 芬兰| NULL | 1600 | 0 | 0 | 1 | | 2000年| 印度| 计算器| 150 | 0 | 0 | 0 | | 2000年| 印度| 电脑| 1200 | 0 | 0 | 0 | | 2000年| 印度| NULL | 1350 | 0 | 0 | 1 | | 2000年| 美国| 计算器| 75 | 0 | 0 | 0 | | 2000年| 美国| 电脑| 1500 | 0 | 0 | 0 | | 2000年| 美国| NULL | 1575 | 0 | 0 | 1 | | 2000年| NULL | NULL | 4525 | 0 | 1 | 1 | | 2001 | 芬兰| 电话| 10 | 0 | 0 | 0 | | 2001 | 芬兰| NULL | 10 | 0 | 0 | 1 | | 2001 | 美国| 计算器| 50 | 0 | 0 | 0 | | 2001 | 美国| 电脑| 2700 | 0 | 0 | 0 | | 2001 | 美国| 电视| 250 | 0 | 0 | 0 | | 2001 | 美国| NULL | 3000 | 0 | 0 | 1 | | 2001 | NULL | NULL | 3010 | 0 | 1 | 1 | | NULL | NULL | NULL | 7535 | 1 | 1 | 1 | + ------ + --------- + ------------ + -------- + ---------- + ------------- ------------- + +
GROUPING()
您可以使用
GROUPING()
替换标签来获取超级聚合
NULL
值
,
而不是
直接
显示
结果
:
MySQL的>SELECT
IF(GROUPING(year), 'All years', year) AS year,
IF(GROUPING(country), 'All countries', country) AS country,
IF(GROUPING(product), 'All products', product) AS product,
SUM(profit) AS profit
FROM sales
GROUP BY year, country, product WITH ROLLUP;
+ ----------- + -------- + -------------- + ------ - + | 一年| 国家| 产品| 利润| + ----------- + -------- + -------------- + ------ - + | 2000年| 芬兰| 电脑| 1500 | | 2000年| 芬兰| 电话| 100 | | 2000年| 芬兰| 所有产品| 1600 | | 2000年| 印度| 计算器| 150 | | 2000年| 印度| 电脑| 1200 | | 2000年| 印度| 所有产品| 1350 | | 2000年| 美国| 计算器| 75 | | 2000年| 美国| 电脑| 1500 | | 2000年| 美国| 所有产品| 1575 | | 2000年| 所有国家| 所有产品| 4525 | | 2001 | 芬兰| 电话| 10 | | 2001 | 芬兰| 所有产品| 10 | | 2001 | 美国| 计算器| 50 | | 2001 | 美国| 电脑| 2700 | | 2001 | 美国| 电视| 250 | | 2001 | 美国| 所有产品| 3000 | | 2001 | 所有国家| 所有产品| 3010 | | 所有年份| 所有国家| 所有产品| 7535 | + ----------- + -------- + -------------- + ------ - +
使用多个表达式参数,
GROUPING()
返回表示位掩码的结果,组合每个表达式的结果,最低位对应于最右侧表达式的结果。
例如,
GROUPING(year, country,
product)
评估如下:
GROUPING(product
)的结果 +结果为GROUPING(country
)<< 1 +结果为GROUPING(year
)<< 2
GROUPING()
如果任何表达式表示超级聚合
NULL
,
则
此类结果
为非零
,因此您只能返回超级聚合行并过滤掉常规分组行,如下所示:
MySQL的>SELECT year, country, product, SUM(profit) AS profit
FROM sales
GROUP BY year, country, product WITH ROLLUP
HAVING GROUPING(year, country, product) <> 0;
+ ------ + --------- + --------- + -------- + | 一年| 国家| 产品| 利润| + ------ + --------- + --------- + -------- + | 2000年| 芬兰| NULL | 1600 | | 2000年| 印度| NULL | 1350 | | 2000年| 美国| NULL | 1575 | | 2000年| NULL | NULL | 4525 | | 2001 | 芬兰| NULL | 10 | | 2001 | 美国| NULL | 3000 | | 2001 | NULL | NULL | 3010 | | NULL | NULL | NULL | 7535 | + ------ + --------- + --------- + -------- +
该
sales
表不包含任何
NULL
值,因此
结果中的
所有
NULL
值
都
ROLLUP
表示超级聚合值。
当数据集包含
NULL
值时,
ROLLUP
摘要
NULL
不仅
可以包含
超聚合行
中的
值,
还可以包含
常规分组行中的值。
GROUPING()
使这些可以区分。
假设该表
t1
包含一个简单的数据集,其中包含一组数量值的两个分组因子,其中
NULL
表示类似
“
其他
”
或
“
未知
”的内容
:
MySQL的> SELECT * FROM t1;
+ ------ + ------- + ---------- +
| 名字| 尺寸| 数量|
+ ------ + ------- + ---------- +
| 球| 小| 10 |
| 球| 大| 20 |
| 球| NULL | 5 |
| 箍| 小| 15 |
| 箍| 大| 5 |
| 箍| NULL | 3 |
+ ------ + ------- + ---------- +
一个简单的
ROLLUP
操作会产生这些结果,在这些结果中,将
NULL
超级聚合行中的
NULL
值与常规分组行中的值
区分开来并不容易
:
MySQL的>SELECT name, size, SUM(quantity) AS quantity
FROM t1
GROUP BY name, size WITH ROLLUP;
+ ------ + ------- + ---------- + | 名字| 尺寸| 数量| + ------ + ------- + ---------- + | 球| NULL | 5 | | 球| 大| 20 | | 球| 小| 10 | | 球| NULL | 35 | | 箍| NULL | 3 | | 箍| 大| 5 | | 箍| 小| 15 | | 箍| NULL | 23 | | NULL | NULL | 58 | + ------ + ------- + ---------- +
使用
GROUPING()
替代标签的超总量
NULL
值,使得结果更容易解释:
MySQL的>SELECT
IF(GROUPING(name) = 1, 'All items', name) AS name,
IF(GROUPING(size) = 1, 'All sizes', size) AS size,
SUM(quantity) AS quantity
FROM t1
GROUP BY name, size WITH ROLLUP;
+ ----------- ----------- + ---------- + + | 名字| 尺寸| 数量| + ----------- ----------- + ---------- + + | 球| NULL | 5 | | 球| 大| 20 | | 球| 小| 10 | | 球| 所有尺寸| 35 | | 箍| NULL | 3 | | 箍| 大| 5 | | 箍| 小| 15 | | 箍| 所有尺寸| 23 | | 所有项目| 所有尺寸| 58 | + ----------- ----------- + ---------- + +
以下讨论列出了一些特定于MySQL实现的行为
ROLLUP
。
在MySQL 8.0.12之前,当您使用时
ROLLUP
,您也不能使用
ORDER BY
子句对结果进行排序。
换句话说,
ROLLUP
并且
ORDER BY
在MySQL中是互斥的。
但是,您仍然可以控制排序顺序。
若要解决阻止使用限制
ROLLUP
使用
ORDER BY
,实现分组结果的具体排序顺序,生成分组结果集派生表,并应用
ORDER
BY
它。
例如:
MySQL的>SELECT * FROM
(SELECT year, SUM(profit) AS profit
FROM sales GROUP BY year WITH ROLLUP) AS dt
ORDER BY year DESC;
+ ------ + -------- + | 一年| 利润| + ------ + -------- + | 2001 | 3010 | | 2000年| 4525 | | NULL | 7535 | + ------ + -------- +
从MySQL 8.0.12的,
ORDER BY
并且
ROLLUP
可以一起使用,这使得能够使用
ORDER BY
和
GROUPING()
实现分组结果的具体排序顺序。
例如:
MySQL的>SELECT year, SUM(profit) AS profit
FROM sales
GROUP BY year WITH ROLLUP
ORDER BY GROUPING(year) DESC;
+ ------ + -------- + | 一年| 利润| + ------ + -------- + | NULL | 7535 | | 2000年| 4525 | | 2001 | 3010 | + ------ + -------- +
在这两种情况下,超级聚合摘要行都按计算它们的行进行排序,它们的位置取决于排序顺序(在升序排序的末尾,在降序排序的开头)。
LIMIT
可用于限制返回给客户端的行数。
LIMIT
在之后应用
ROLLUP
,因此该限制适用于添加的额外行
ROLLUP
。
例如:
MySQL的>SELECT year, country, product, SUM(profit) AS profit
FROM sales
GROUP BY year, country, product WITH ROLLUP
LIMIT 5;
+ ------ + --------- + ------------ + -------- + | 一年| 国家| 产品| 利润| + ------ + --------- + ------------ + -------- + | 2000年| 芬兰| 电脑| 1500 | | 2000年| 芬兰| 电话| 100 | | 2000年| 芬兰| NULL | 1600 | | 2000年| 印度| 计算器| 150 | | 2000年| 印度| 电脑| 1200 | + ------ + --------- + ------------ + -------- +
使用
LIMIT
with
ROLLUP
可能会产生更难以解释的结果,因为用于理解超级聚合行的上下文较少。
MySQL扩展允许
GROUP BY
列表
中未出现的
列在选择列表中命名。
(有关非
聚合
列的信息
GROUP BY
,请参见
第12.20.3节“GROUP BY的MySQL处理”
。)在这种情况下,服务器可以自由选择摘要行中此非聚合列的任何值,这包括添加的额外行通过
WITH ROLLUP
。
例如,在以下查询中,
country
是一个未出现在
GROUP BY
列表中的非
聚合列,并且
为此列选择的值是不确定的:
MySQL的>SELECT year, country, SUM(profit) AS profit
FROM sales
GROUP BY year WITH ROLLUP;
+ ------ + --------- + -------- + | 一年| 国家| 利润| + ------ + --------- + -------- + | 2000年| 印度| 4525 | | 2001 | 美国| 3010 | | NULL | 美国| 7535 | + ------ + --------- + -------- +
ONLY_FULL_GROUP_BY
未启用SQL模式
时,允许此行为
。
如果启用了该模式,则服务器会将查询拒绝为非法,因为
country
该
GROUP BY
子句中
未列出
该查询
。
与
ONLY_FULL_GROUP_BY
启用,您仍然可以通过执行查询
ANY_VALUE()
非确定性值列功能:
MySQL的>SELECT year, ANY_VALUE(country) AS country, SUM(profit) AS profit
FROM sales
GROUP BY year WITH ROLLUP;
+ ------ + --------- + -------- + | 一年| 国家| 利润| + ------ + --------- + -------- + | 2000年| 印度| 4525 | | 2001 | 美国| 3010 | | NULL | 美国| 7535 | + ------ + --------- + -------- +
SQL-92和更早版本不允许选择列表,
HAVING
条件或
ORDER
BY
列表引用未在
GROUP BY
子句中
命名的非聚合列的查询
。
例如,此查询在标准SQL-92中是非法的,因为
name
选择列表中的非
聚合
列不会出现在
GROUP BY
:
SELECT o.custid,c.name,MAX(o.payment) 来自订单AS o,客户AS c 在哪里o.custid = c.custid GROUP BY o.custid;
要使查询在SQL-92中合法,
name
必须从选择列表中省略该列,或在该
GROUP BY
子句中
对该
列进行命名
。
SQL:1999及更高版本允许每个可选功能T301的非聚合,如果它们在功能上依赖于
GROUP BY
列:如果
name
和
之间存在这样的关系
custid
,则查询是合法的。
例如,这是
custid
一个主要的关键
customers
。
MySQL实现了对功能依赖的检测。
如果
ONLY_FULL_GROUP_BY
启用
了
SQL模式(默认情况下是这样),则MySQL拒绝查询,其中选择列表,
HAVING
条件或
ORDER BY
列表引用非聚合列,这些列既不在
GROUP BY
子句中
命名
也不在功能上依赖于它们。
如果
ONLY_FULL_GROUP_BY
禁用,则标准SQL使用的MySQL扩展
GROUP BY
允许选择列表,
HAVING
条件或
ORDER
BY
列表引用非聚合列,即使列在功能上不依赖于
GROUP
BY
列。
这导致MySQL接受前面的查询。
在这种情况下,服务器可以自由选择每个组中的任何值,因此除非它们相同,否则所选的值是不确定的,这可能不是您想要的。
此外,添加一个
ORDER BY
条款
不会影响每个组的值的选择
。
结果集排序在选择值后发生,并且
ORDER BY
不会影响服务器选择的每个组中的哪个值。
ONLY_FULL_GROUP_BY
当您知道由于数据的某些属性时,每个未分配的每个非聚合列中的所有值
GROUP BY
对于每个组都是相同的
,因此
禁用
非常有用
。
您可以
ONLY_FULL_GROUP_BY
通过使用
ANY_VALUE()
引用非聚合列
来实现相同的效果而不禁用
。
以下讨论演示了函数依赖性,MySQL在缺少函数依赖时产生的错误消息,以及在没有函数依赖性的情况下使MySQL接受查询的方法。
ONLY_FULL_GROUP_BY
启用
此查询可能无效,
因为
address
选项列表中的非
聚合
列未在
GROUP BY
子句中
命名
:
SELECT名称,地址,MAX(年龄)FROM t GROUP BY名称;
如果查询是
name
主键
t
或是唯一
NOT
NULL
列,
则查询有效
。
在这种情况下,MySQL会识别所选列在功能上依赖于分组列。
例如,如果
name
是主键,则其值确定值,
address
因为每个组只有一个主键值,因此只有一行。
因此,
address
组
中
值
的选择没有随机性
,也不需要拒绝查询。
如果查询
name
不是主键
t
或唯一
NOT
NULL
列,
则查询无效
。
在这种情况下,不能推断出功能依赖性并发生错误:
MySQL的> SELECT name, address, MAX(age) FROM t GROUP BY name;
错误1055(42000):SELECT列表的表达式#2不在GROUP中
BY子句并包含非聚合列'mydb.t.address'
在功能上不依赖于GROUP BY子句中的列; 这个
与sql_mode = only_full_group_by不兼容
如果您知道,
对于给定的数据集,
每个
name
值实际上唯一地确定该
address
值,
address
在功能上是有效依赖的
name
。
要告诉MySQL接受查询,可以使用以下
ANY_VALUE()
函数:
SELECT名称,ANY_VALUE(地址),MAX(年龄)FROM t GROUP BY名称;
或者,禁用
ONLY_FULL_GROUP_BY
。
然而,前面的例子非常简单。 特别是,您不太可能在单个主键列上进行分组,因为每个组只包含一行。 有关在更复杂查询中显示函数依赖性的 附加 示例,请参见 第12.20.4节“函数依赖性检测” 。
如果查询具有聚合函数且没有
GROUP
BY
子句,则在
启用
的选择列表,
HAVING
条件或
ORDER BY
列表中
不能包含
非聚合
列
ONLY_FULL_GROUP_BY
:
MySQL的> SELECT name, MAX(age) FROM t;
错误1140(42000):在没有GROUP BY,表达式的聚合查询中
SELECT列表的#1包含非聚合列'mydb.t.name'; 这个
与sql_mode = only_full_group_by不兼容
没有
GROUP BY
,只有一个组,它是不确定的,
name
为组选择值。
ANY_VALUE()
如果
name
MySQL选择的值
不重要
,
也可以使用
这里
:
SELECT ANY_VALUE(name),MAX(age)FROM t;
ONLY_FULL_GROUP_BY
也会影响使用
DISTINCT
和
查询的处理
ORDER
BY
。
考虑表的情况下,
t
有三列
c1
,
c2
以及
c3
包含这些行:
c1 c2 c3 1 2 A. 3 4 B. 1 2 C.
假设我们执行以下查询,期望按以下顺序排序结果
c3
:
SELECT DISTINCT c1,c2 FROM t ORDER BY c3;
要订购结果,必须首先删除重复项。
但要这样做,我们应该保留第一行还是第三行?
这种任意选择会影响保留值
c3
,从而影响排序并使其任意。
要防止出现此问题,
如果任何
表达式不满足以下条件中的至少一个条件
,则该查询具有
DISTINCT
和
ORDER BY
被拒绝为无效
ORDER BY
:
表达式在选择列表中等于1
表达式引用并属于查询所选表的所有列都是选择列表的元素
标准SQL的另一个MySQL扩展允许
HAVING
子句中的
引用
到选择列表中的别名表达式。
例如,以下查询返回
name
在表中只出现一次的值
orders
:
SELECT名称,COUNT(名称)FROM订单 GROUP BY名称 有COUNT(名字)= 1;
MySQL扩展允许
HAVING
在聚合列
的
子句中
使用别名
:
SELECT name,COUNT(name)AS c FROM orders GROUP BY名称 有c = 1;
标准SQL只允许
GROUP
BY
子句中的
列表达式
,因此这样的语句无效,因为它
FLOOR(value/100)
是一个非列表达式:
SELECT id,FLOOR(value / 100)
从 tbl_name
GROUP BY id,FLOOR(value / 100);
MySQL扩展标准SQL以允许
GROUP BY
子句中的非
列表达式,
并认为前面的语句有效。
标准SQL也不允许
GROUP
BY
子句中的
别名
。
MySQL扩展标准SQL以允许别名,因此编写查询的另一种方法如下:
SELECT id,FLOOR(value / 100)AS val
从 tbl_name
GROUP BY id,val;
别名
val
在
GROUP BY
子句中
被视为列表达式
。
在
GROUP
BY
子句中
存在非列表达式的情况下
,MySQL会识别该表达式与选择列表中的表达式之间的相等性。
这意味着在
ONLY_FULL_GROUP_BY
启用SQL模式的情况下,包含的查询
GROUP BY id,
FLOOR(value/100)
是有效的,因为
FLOOR()
在选择列表中会出现
相同的
表达式。
但是,MySQL不会尝试识别对非
GROUP BY
列表达式的
函数依赖性
,因此以下查询在
ONLY_FULL_GROUP_BY
启用时
无效
,即使第三个选定表达式是
id
列
的简单公式
和
子句中
的
FLOOR()
表达式
GROUP BY
:
SELECT id,FLOOR(value / 100),id + FLOOR(value / 100)
从 tbl_name
GROUP BY id,FLOOR(value / 100);
解决方法是使用派生表:
SELECT id,F,id + F.
从
(SELECT id,FLOOR(value / 100)AS F.
从 tbl_name
GROUP BY id,FLOOR(value / 100))AS dt;
以下讨论提供了MySQL检测功能依赖性的方式的几个示例。 示例使用此表示法:
{X
} - > {Y
}
理解这一点如
“
X
唯一地确定
Y
,
”
这也意味着,
Y
在功能上依赖于
X
。
这些示例使用
world
数据库,可以从
https://dev.mysql.com/doc/index-other.html
下载
。
您可以在同一页面上找到有关如何安装数据库的详细信息。
以下查询为每个国家/地区选择口语数量:
SELECT co.Name,COUNT(*) 来自countrylanguage cl,country co 在哪里cl.CountryCode = co.Code GROUP BY co.Code;
co.Code
是一个主键
co
,因此所有列
co
都在功能上依赖于它,如使用此表示法表示的:
{co.Code} - > {co。*}
因此,
co.name
在功能上依赖于
GROUP BY
列并且查询是有效的。
可以使用列上
的
UNIQUE
索引
NOT
NULL
而不是主键,并且将应用相同的功能依赖性。
(对于
UNIQUE
允许
NULL
值
的
索引,情况
并非如此,
因为它允许多个
NULL
值,在这种情况下,唯一性会丢失。)
此查询为每个国家/地区选择所有口语的列表以及有多少人说话:
SELECT co.Name,cl.Language, cl.Percentage * co.Population / 100.0 AS SpokenBy 来自countrylanguage cl,country co 在哪里cl.CountryCode = co.Code GROUP BY cl.CountryCode,cl.Language;
对(
cl.CountryCode
,
cl.Language
)是两列复合主键
cl
,因此列对唯一地确定所有列
cl
:
{cl.CountryCode,cl.Language} - > {cl。*}
而且,由于
WHERE
条款
中的平等
:
{cl.CountryCode} - > {co.Code}
并且,因为
co.Code
是主要关键
co
:
{co.Code} - > {co。*}
“ 唯一确定 ” 关系是可传递的,因此:
{cl.CountryCode,cl.Language} - > {cl。*,co。*}
因此,查询有效。
与前面的示例一样,
可以使用列上
的
UNIQUE
键
NOT NULL
而不是主键。
的
INNER JOIN
条件可以被用来代替
WHERE
。
相同的功能依赖性适用:
SELECT co.Name,cl.Language, cl.Percentage * co.Population / 100.0 AS SpokenBy 来自countrylanguage cl INNER JOIN country co ON cl.CountryCode = co.Code GROUP BY cl.CountryCode,cl.Language;
虽然
WHERE
条件或
INNER JOIN
条件中的相等性测试是对称的,但外部连接条件中的相等性测试不是,因为表扮演不同的角色。
假设参照完整性被意外破坏,并且存在一行
countrylanguage
没有相应的行
country
。
考虑与前一个示例中相同的查询,但使用
LEFT JOIN
:
SELECT co.Name,cl.Language, cl.Percentage * co.Population / 100.0 AS SpokenBy 来自countrylanguage cl LEFT JOIN country co ON cl.CountryCode = co.Code GROUP BY cl.CountryCode,cl.Language;
对于给定值
cl.CountryCode
,
co.Code
连接结果中的值可以在匹配的行中找到(由...确定
cl.CountryCode
),或者
NULL
如果没有匹配
则也是
- 如果没有匹配(也由...确定
cl.CountryCode
)。
在每种情况下,这种关系适用:
{cl.CountryCode} - > {co.Code}
cl.CountryCode
它本身在功能上依赖于{
cl.CountryCode
,
cl.Language
}这是一个主键。
如果在连接结果中
co.Code
是
NULL
-complemented,
co.Name
那么也是如此。
如果
co.Code
不是
NULL
-complemented,那么因为它
co.Code
是一个主键,它确定
co.Name
。
因此,在所有情况下:
{co.Code} - > {co.Name}
产量:
{cl.CountryCode,cl.Language} - > {cl。*,co。*}
因此,查询有效。
但是,假设表已交换,如此查询中所示:
SELECT co.Name,cl.Language, cl.Percentage * co.Population / 100.0 AS SpokenBy 来自country co LEFT JOIN countrylanguage cl ON cl.CountryCode = co.Code GROUP BY cl.CountryCode,cl.Language;
现在,这种关系并 不能 适用:
{cl.CountryCode,cl.Language} - > {cl。*,co。*}
实际上,所有已
NULL
完成的
cl
行将被放入一个组(它们的
GROUP BY
列都等于
NULL
),并且在这个组中,值
co.Name
可以变化。
查询无效,MySQL拒绝它。
因此,外连接中的功能依赖性与行列式列是属于左侧还是右侧有关
LEFT JOIN
。
如果存在嵌套外连接或连接条件不完全由相等比较组成,则函数依赖性的确定变得更加复杂。
假设一个国家的观点产生他们的代码,他们的名字是大写的,他们有多少种不同的官方语言:
创建视图Country2 AS SELECT co.Code,UPPER(co.Name)AS UpperName, COUNT(cl.Language)AS OfficialLanguages 来自国家AS co JOIN countrylanguage AS cl ON cl.CountryCode = co.Code 在哪里cl.isOfficial ='T' GROUP BY co.Code;
此定义有效,因为:
{co.Code} - > {co。*}
在视图结果中,第一个选定的列是
co.Code
,也是组列,因此确定所有其他选定的表达式:
{Country2.Code} - > {Country2。*}
MySQL理解这一点并使用这些信息,如下所述。
此查询通过将视图加入
city
表格来
显示国家/地区,他们拥有多少种不同的官方语言以及他们拥有的城市数量
:
SELECT co2.Code,co2.UpperName,co2.OfficialLanguages, COUNT(*)AS城市 来自country2 AS co2 JOIN city ci ON ci.CountryCode = co2.Code GROUP BY co2.Code;
此查询有效,因为如前所示:
{co2.Code} - > {co2。*}
MySQL能够在视图的结果中发现功能依赖,并使用它来验证使用该视图的查询。
如果
country2
是派生表(或公用表表达式),情况也是如此,如:
SELECT co2.Code,co2.UpperName,co2.OfficialLanguages, COUNT(*)AS城市 从 ( SELECT co.Code,UPPER(co.Name)AS UpperName, COUNT(cl.Language)AS OfficialLanguages 来自国家AS co JOIN countrylanguage AS cl ON cl.CountryCode = co.Code 在哪里cl.isOfficial ='T' GROUP BY co.Code )AS co2 JOIN city ci ON ci.CountryCode = co2.Code GROUP BY co2.Code;
MySQL支持窗口函数,对于查询中的每一行,它使用与该行相关的行执行计算。
以下部分讨论如何使用窗口函数,包括
OVER
和
WINDOW
子句的
描述
。
第一部分提供非聚合窗口函数的描述。
有关聚合窗口函数的描述,请参见
第12.20.1节“聚合(GROUP BY)函数描述”
。
有关优化和窗口函数的信息,请参见 第8.2.1.20节“窗口函数优化” 。
本节介绍非聚合窗口函数,对于查询中的每一行,它使用与该行相关的行执行计算。 大多数聚合函数也可以用作窗口函数; 请参见 第12.20.1节“聚合(GROUP BY)功能描述” 。
有关窗口函数用法信息和示例,以及术语(如
OVER
子句,窗口,分区,框架和对等项)的定义,请参见
第12.21.2节“窗口函数概念和语法”
。
表12.27窗口函数
名称 | 描述 |
---|---|
CUME_DIST() |
累积分配值 |
DENSE_RANK() |
其分区内当前行的排名,没有间隙 |
FIRST_VALUE() |
窗口框架第一行的参数值 |
LAG() |
行中滞后当前行的参数值 |
LAST_VALUE() |
窗口框架最后一行的参数值 |
LEAD() |
分区中行前导行的参数值 |
NTH_VALUE() |
第N行窗口框架的参数值 |
NTILE() |
其分区中当前行的存储桶编号。 |
PERCENT_RANK() |
百分比等级值 |
RANK() |
其分区内当前行的排名,有差距 |
ROW_NUMBER() |
其分区中当前行的数量 |
在以下函数描述中,
over_clause
表示
第12.21.2节“窗口函数概念和语法”中
OVER
描述
的
子句
。
某些窗口函数允许一个
子句,指定
在计算结果时
如何处理
值。
该子句是可选的。
它是SQL标准的一部分,但MySQL实现仅允许
(这也是默认值)。
这意味着
在计算结果时会考虑值。
被解析,但产生错误。
null_treatment
NULL
RESPECT NULLS
NULL
IGNORE NULLS
CUME_DIST()
over_clause
返回一组值中的值的累积分布; 也就是说,分区值的百分比小于或等于当前行中的值。 这表示窗口分区的窗口顺序中当前行之前或与之对应的行数除以窗口分区中的总行数。 返回值的范围是0到1。
应该使用此函数将
ORDER
BY
分区行排序为所需的顺序。
如果没有
ORDER BY
,则所有行都是对等的并且值为
N
/
N
= 1,其中
N
是分区大小。
over_clause
如
第12.21.2节“窗口函数概念和语法”中所述
。
以下查询针对
val
列中的
CUME_DIST()
值集显示每行
的
值,以及类似
PERCENT_RANK()
函数
返回的百分比等级值
。
作为参考,查询还使用
ROW_NUMBER()
以下方式
显示行号
:
MySQL的>SELECT
val,
ROW_NUMBER() OVER w AS 'row_number',
CUME_DIST() OVER w AS 'cume_dist',
PERCENT_RANK() OVER w AS 'percent_rank'
FROM numbers
WINDOW w AS (ORDER BY val);
+ ------ + ------------ + -------------------- + -------- ------ + | val | row_number | cume_dist | percent_rank | + ------ + ------------ + -------------------- + -------- ------ + | 1 | 1 | 0.2222222222222222 | 0 | | 1 | 2 | 0.2222222222222222 | 0 | | 2 | 3 | 0.3333333333333333 | 0.25 | | 3 | 4 | 0.6666666666666666 | 0.375 | | 3 | 5 | 0.6666666666666666 | 0.375 | | 3 | 6 | 0.6666666666666666 | 0.375 | | 4 | 7 | 0.8888888888888888 | 0.75 | | 4 | 8 | 0.8888888888888888 | 0.75 | | 5 | 9 | 1 | 1 | + ------ + ------------ + -------------------- + -------- ------ +
DENSE_RANK()
over_clause
返回其分区中当前行的排名,没有间隙。
同行被视为关系,并获得相同的排名。
此功能将连续的等级分配给对等组;
结果是,大于1的组不会产生不连续的等级数。
有关示例,请参阅
RANK()
功能说明。
应该使用此函数将
ORDER
BY
分区行排序为所需的顺序。
没有
ORDER BY
,所有行都是对等的。
over_clause
如
第12.21.2节“窗口函数概念和语法”中所述
。
FIRST_VALUE(
[
expr
)null_treatment
]
over_clause
返回
expr
窗口框架第一行
的值
。
over_clause
如
第12.21.2节“窗口函数概念和语法”中所述
。
null_treatment
如引言部分所述。
下面的查询演示
FIRST_VALUE()
,
LAST_VALUE()
以及两个实例
NTH_VALUE()
:
MySQL的>SELECT
time, subject, val,
FIRST_VALUE(val) OVER w AS 'first',
LAST_VALUE(val) OVER w AS 'last',
NTH_VALUE(val, 2) OVER w AS 'second',
NTH_VALUE(val, 4) OVER w AS 'fourth'
FROM observations
WINDOW w AS (PARTITION BY subject ORDER BY time
ROWS UNBOUNDED PRECEDING);
+ ---------- + --------- + ------ + ------- + ------ + ------ - + -------- + | 时间| 主题| val | 第一个| 最后| 第二个| 第四| + ---------- + --------- + ------ + ------- + ------ + ------ - + -------- + | 07:00:00 | st113 | 10 | 10 | 10 | NULL | NULL | | 07:15:00 | st113 | 9 | 10 | 9 | 9 | NULL | | 07:30:00 | st113 | 25 | 10 | 25 | 9 | NULL | | 07:45:00 | st113 | 20 | 10 | 20 | 9 | 20 | | 07:00:00 | xh458 | 0 | 0 | 0 | NULL | NULL | | 07:15:00 | xh458 | 10 | 0 | 10 | 10 | NULL | | 07:30:00 | xh458 | 5 | 0 | 5 | 10 | NULL | | 07:45:00 | xh458 | 30 | 0 | 30 | 10 | 30 | | 08:00:00 | xh458 | 25 | 0 | 25 | 10 | 30 | + ---------- + --------- + ------ + ------- + ------ + ------ - + -------- +
每个函数使用当前帧中的行,根据所示的窗口定义,这些行从第一个分区行延伸到当前行。
对于
NTH_VALUE()
调用,当前帧并不总是包括所请求的行;
在这种情况下,返回值是
NULL
。
LAG(
[
expr
[,
N
[,
default
]])null_treatment
]
over_clause
返回
expr
当前行滞后(先于)
N
其分区内的
行的
行的值。
如果没有这样的行,则返回值为
default
。
例如,如果
N
为3,则返回值为
default
前两行。
如果
N
或
default
缺少,则默认值分别为1和1
NULL
。
N
必须是文字非负整数。
如果
N
为0,
expr
则评估当前行。
over_clause
如
第12.21.2节“窗口函数概念和语法”中所述
。
null_treatment
如引言部分所述。
LAG()
(和类似的
LEAD()
功能)通常用于计算行之间的差异。
以下查询显示了一组按时间顺序排列的观察值,并且对于每个观察
值,显示了相邻行的值
LAG()
和
LEAD()
值,以及当前行和相邻行之间的差异:
MySQL的>SELECT
t, val,
LAG(val) OVER w AS 'lag',
LEAD(val) OVER w AS 'lead',
val - LAG(val) OVER w AS 'lag diff',
val - LEAD(val) OVER w AS 'lead diff'
FROM series
WINDOW w AS (ORDER BY t);
+ ---------- + ------ + ------ + ------ + ---------- + ------ ----- + | t | val | 滞后| 铅| 滞后差异| lead diff | + ---------- + ------ + ------ + ------ + ---------- + ------ ----- + | 12:00:00 | 100 | NULL | 125 | NULL | -25 | | 13:00:00 | 125 | 100 | 132 | 25 | -7 | | 14:00:00 | 132 | 125 | 145 | 7 | -13 | | 15:00:00 | 145 | 132 | 140 | 13 | 5 | | 16:00:00 | 140 | 145 | 150 | -5 | -10 | | 17:00:00 | 150 | 140 | 200 | 10 | -50 | | 18:00:00 | 200 | 150 | NULL | 50 | NULL | + ---------- + ------ + ------ + ------ + ---------- + ------ ----- +
在示例中,
LAG()
和
LEAD()
调用分别使用默认值
N
和
default
值1和
NULL
。
第一行显示当没有前一行时发生的情况
LAG()
:函数返回
default
值(在本例中为
NULL
)。
当没有下一行时,最后一行显示相同的内容
LEAD()
。
LAG()
并且
LEAD()
还用于计算总和而不是差异。
考虑这个数据集,其中包含Fibonacci系列的前几个数字:
MySQL的> SELECT n FROM fib ORDER BY n;
+ ------ +
| n |
+ ------ +
| 1 |
| 1 |
| 2 |
| 3 |
| 5 |
| 8 |
+ ------ +
以下查询显示
LAG()
与
LEAD()
当前行相邻的行
的
和
值。
它还使用这些函数将前一行和后一行中的值添加到当前行值。
效果是在Fibonacci系列中生成下一个数字,然后是下一个数字:
MySQL的>SELECT
n,
LAG(n, 1, 0) OVER w AS 'lag',
LEAD(n, 1, 0) OVER w AS 'lead',
n + LAG(n, 1, 0) OVER w AS 'next_n',
n + LEAD(n, 1, 0) OVER w AS 'next_next_n'
FROM fib
WINDOW w AS (ORDER BY n);
+ ------ + ------ + ------ + -------- + ------------- + | n | 滞后| 铅| next_n | next_next_n | + ------ + ------ + ------ + -------- + ------------- + | 1 | 0 | 1 | 1 | 2 | | 1 | 1 | 2 | 2 | 3 | | 2 | 1 | 3 | 3 | 5 | | 3 | 2 | 5 | 5 | 8 | | 5 | 3 | 8 | 8 | 13 | | 8 | 5 | 0 | 13 | 8 | + ------ + ------ + ------ + -------- + ------------- +
生成初始Fibonacci数集的一种方法是使用递归公用表表达式。 有关示例,请参阅 Fibonacci Series Generation 。
LAST_VALUE(
[
expr
)null_treatment
]
over_clause
返回
expr
窗口框架最后一行
的值
。
over_clause
如
第12.21.2节“窗口函数概念和语法”中所述
。
null_treatment
如引言部分所述。
有关示例,请参阅
FIRST_VALUE()
功能说明。
LEAD(
[
expr
[,
N
[,
default
]])null_treatment
]
over_clause
返回
从其分区中
expr
的行引导(跟随)当前行的
N
行的值。
如果没有这样的行,则返回值为
default
。
例如,如果
N
为3,则返回值为
default
最后两行。
如果
N
或
default
缺少,则默认值分别为1和1
NULL
。
N
必须是文字非负整数。
如果
N
为0,
expr
则评估当前行。
over_clause
如
第12.21.2节“窗口函数概念和语法”中所述
。
null_treatment
如引言部分所述。
有关示例,请参阅
LAG()
功能说明。
NTH_VALUE(
[
expr
,
N
)from_first_last
] [
null_treatment
]
over_clause
返回
窗口框架
expr
的
N
第-th行
的值
。
如果没有这样的行,则返回值为
NULL
。
N
必须是字面正整数。
from_first_last
是SQL标准的一部分,但MySQL实现仅允许
FROM FIRST
(这也是默认值)。
这意味着计算从窗口的第一行开始。
FROM LAST
被解析,但产生错误。
要获得与
FROM
LAST
(在窗口的最后一行开始计算)
相同的效果
,请使用
ORDER BY
相反的顺序排序。
over_clause
如
第12.21.2节“窗口函数概念和语法”中所述
。
null_treatment
如引言部分所述。
有关示例,请参阅
FIRST_VALUE()
功能说明。
NTILE(
N
)over_clause
将分区划分为
N
组(存储桶),为分区中的每一行分配其存储桶编号,并返回其分区中当前行的存储区编号。
例如,如果
N
为4,
NTILE()
则将行分为四个桶。
如果
N
为100,
NTILE()
则将行划分为100个桶。
N
必须是字面正整数。
存储桶编号返回值的范围为1到
N
。
应该使用此函数将
ORDER
BY
分区行排序为所需的顺序。
over_clause
如
第12.21.2节“窗口函数概念和语法”中所述
。
以下查询针对
val
列中
的值集显示
通过将行划分为两个或四个组而产生的百分位数值。
作为参考,查询还使用
ROW_NUMBER()
以下方式
显示行号
:
MySQL的>SELECT
val,
ROW_NUMBER() OVER w AS 'row_number',
NTILE(2) OVER w AS 'ntile2',
NTILE(4) OVER w AS 'ntile4'
FROM numbers
WINDOW w AS (ORDER BY val);
+ ------ + ------------ + -------- + -------- + | val | row_number | ntile2 | ntile4 | + ------ + ------------ + -------- + -------- + | 1 | 1 | 1 | 1 | | 1 | 2 | 1 | 1 | | 2 | 3 | 1 | 1 | | 3 | 4 | 1 | 2 | | 3 | 5 | 1 | 2 | | 3 | 6 | 2 | 3 | | 4 | 7 | 2 | 3 | | 4 | 8 | 2 | 4 | | 5 | 9 | 2 | 4 | + ------ + ------------ + -------- + -------- +
PERCENT_RANK()
over_clause
返回小于当前行中值的分区值的百分比,不包括最高值。
返回值的范围从0到1,表示行的相对等级,计算为此公式的结果,其中
rank
是行等级,
rows
是分区行的数量:
(rank
- 1)/(rows
- 1)
应该使用此函数将
ORDER
BY
分区行排序为所需的顺序。
没有
ORDER BY
,所有行都是对等的。
over_clause
如
第12.21.2节“窗口函数概念和语法”中所述
。
有关示例,请参阅
CUME_DIST()
功能说明。
RANK()
over_clause
返回其分区中当前行的排名,带有间隙。 同行被视为关系,并获得相同的排名。 如果存在大于1的组,则此函数不会将连续的等级分配给对等组; 结果是不连续的排名数字。
应该使用此函数将
ORDER
BY
分区行排序为所需的顺序。
没有
ORDER BY
,所有行都是对等的。
over_clause
如
第12.21.2节“窗口函数概念和语法”中所述
。
以下查询显示了它们之间的差异
RANK()
,它产生了具有间隙的排名,并且
DENSE_RANK()
产生了没有间隙的排名。
该查询显示
val
列
中一组值的每个成员的等级值
,其中包含一些重复项。
RANK()
为对等体(重复)分配相同的等级值,并且下一个更大的值具有高于对等体的数量减去1的等级。
DENSE_RANK()
同时为对等体分配相同的等级值,但是下一个更高的值具有更高的等级1。
作为参考,查询还使用
ROW_NUMBER()
以下方式
显示行号
:
MySQL的>SELECT
val,
ROW_NUMBER() OVER w AS 'row_number',
RANK() OVER w AS 'rank',
DENSE_RANK() OVER w AS 'dense_rank'
FROM numbers
WINDOW w AS (ORDER BY val);
+ ------ + ------------ + ------ + ------------ + | val | row_number | 排名| dense_rank | + ------ + ------------ + ------ + ------------ + | 1 | 1 | 1 | 1 | | 1 | 2 | 1 | 1 | | 2 | 3 | 3 | 2 | | 3 | 4 | 4 | 3 | | 3 | 5 | 4 | 3 | | 3 | 6 | 4 | 3 | | 4 | 7 | 7 | 4 | | 4 | 8 | 7 | 4 | | 5 | 9 | 9 | 5 | + ------ + ------------ + ------ + ------------ +
ROW_NUMBER()
over_clause
返回其分区中当前行的编号。 行数从1到分区行数。
ORDER BY
影响行的编号顺序。
没有
ORDER BY
,行编号是不确定的。
ROW_NUMBER()
为同伴分配不同的行号。
要为对等体分配相同的值,请使用
RANK()
或
DENSE_RANK()
。
有关示例,请参阅
RANK()
功能说明。
over_clause
如
第12.21.2节“窗口函数概念和语法”中所述
。
本节介绍如何使用窗口函数。
示例使用与
第12.20.2节“GROUP BY Modifiers”
中的
GROUPING()
函数
讨论中相同的销售信息数据集
:
MySQL的> SELECT * FROM sales ORDER BY country, year, product;
+ ------ + --------- + ------------ + -------- +
| 一年| 国家| 产品| 利润|
+ ------ + --------- + ------------ + -------- +
| 2000年| 芬兰| 电脑| 1500 |
| 2000年| 芬兰| 电话| 100 |
| 2001 | 芬兰| 电话| 10 |
| 2000年| 印度| 计算器| 75 |
| 2000年| 印度| 计算器| 75 |
| 2000年| 印度| 电脑| 1200 |
| 2000年| 美国| 计算器| 75 |
| 2000年| 美国| 电脑| 1500 |
| 2001 | 美国| 计算器| 50 |
| 2001 | 美国| 电脑| 1500 |
| 2001 | 美国| 电脑| 1200 |
| 2001 | 美国| 电视| 150 |
| 2001 | 美国| 电视| 100 |
+ ------ + --------- + ------------ + -------- +
窗口函数对一组查询行执行类似聚合的操作。 但是,聚合操作将查询行分组到单个结果行中,而窗口函数会为每个查询行生成结果:
发生功能评估的行称为当前行。
与发生功能评估的当前行相关的查询行包括当前行的窗口。
例如,使用销售信息表,这两个查询执行聚合操作,为作为组的所有行生成单个全局总和,并按国家/地区分组的总和:
MySQL的>SELECT SUM(profit) AS total_profit
FROM sales;
+ -------------- + | total_profit | + -------------- + | 7535 | + -------------- + MySQL的>SELECT country, SUM(profit) AS country_profit
FROM sales
GROUP BY country
ORDER BY country;
+ --------- + ---------------- + | 国家| country_profit | + --------- + ---------------- + | 芬兰| 1610 | | 印度| 1350 | | 美国| 4575 | + --------- + ---------------- +
相比之下,窗口操作不会将查询行组折叠到单个输出行。
相反,它们为每一行产生一个结果。
与前面的查询一样,以下查询使用
SUM()
,但这次作为窗口函数:
MySQL的>SELECT
year, country, product, profit,
SUM(profit) OVER() AS total_profit,
SUM(profit) OVER(PARTITION BY country) AS country_profit
FROM sales
ORDER BY country, year, product, profit;
+ ------ + --------- + ------------ + -------- + ---------- ---- + ---------------- + | 一年| 国家| 产品| 利润| total_profit | country_profit | + ------ + --------- + ------------ + -------- + ---------- ---- + ---------------- + | 2000年| 芬兰| 电脑| 1500 | 7535 | 1610 | | 2000年| 芬兰| 电话| 100 | 7535 | 1610 | | 2001 | 芬兰| 电话| 10 | 7535 | 1610 | | 2000年| 印度| 计算器| 75 | 7535 | 1350 | | 2000年| 印度| 计算器| 75 | 7535 | 1350 | | 2000年| 印度| 电脑| 1200 | 7535 | 1350 | | 2000年| 美国| 计算器| 75 | 7535 | 4575 | | 2000年| 美国| 电脑| 1500 | 7535 | 4575 | | 2001 | 美国| 计算器| 50 | 7535 | 4575 | | 2001 | 美国| 电脑| 1200 | 7535 | 4575 | | 2001 | 美国| 电脑| 1500 | 7535 | 4575 | | 2001 | 美国| 电视| 100 | 7535 | 4575 | | 2001 | 美国| 电视| 150 | 7535 | 4575 | + ------ + --------- + ------------ + -------- + ---------- ---- + ---------------- +
查询中的每个窗口操作都通过包含一个
OVER
子句来
表示,该
子句指定如何将查询行分区为组以供窗口函数处理:
第一个
OVER
子句为空,它将整个查询行集视为单个分区。
因此,窗函数产生全局和,但对每一行都这样做。
第二个
OVER
子句按国家/地区划分行,每个分区(每个国家/地区)生成一个总和。
该函数为每个分区行生成此总和。
仅在选择列表和
ORDER BY
子句
中允许窗口函数
。
查询结果行从确定
FROM
子句后
WHERE
,
GROUP BY
以及
HAVING
处理和开窗执行发生之前
ORDER BY
,
LIMIT
和
SELECT
DISTINCT
。
该
OVER
子句允许用于许多聚合函数,因此可以用作窗口函数或非窗口函数,具体取决于是否
OVER
子句
存在:
AVG() BIT_AND() BIT_OR() BIT_XOR() 计数() JSON_ARRAYAGG() JSON_OBJECTAGG() MAX() MIN() STDDEV_POP(),STDDEV(),STD() STDDEV_SAMP() 和() VAR_POP(),VARIANCE() VAR_SAMP()
有关每个聚合函数的详细信息,请参见 第12.20.1节“聚合(GROUP BY)函数说明” 。
MySQL还支持仅用作窗口函数的非聚合函数。
对于这些,
OVER
条款是强制性的:
CUME_DIST() DENSE_RANK() FIRST_VALUE() 落后() LAST_VALUE() 铅() NTH_VALUE() NTILE() PERCENT_RANK() 秩() ROW_NUMBER()
有关每个非 聚合 函数的详细信息,请参见 第12.21.1节“窗口函数说明” 。
作为其中一个非聚合窗口函数的示例,此查询使用
ROW_NUMBER()
,它生成其分区中每行的行号。
在这种情况下,行按每个国家/地区编号。
默认情况下,分区行是无序的,行编号是不确定的。
要对分区行进行排序,请
ORDER BY
在窗口定义中
包含一个
子句。
该查询使用无序和有序分区(
row_num1
和
row_num2
列)来说明省略和包括之间的区别
ORDER BY
:
MySQL的>SELECT
year, country, product, profit,
ROW_NUMBER() OVER(PARTITION BY country) AS row_num1,
ROW_NUMBER() OVER(PARTITION BY country ORDER BY year, product) AS row_num2
FROM sales;
+ ------ + --------- + ------------ + -------- + ---------- + ---------- + | 一年| 国家| 产品| 利润| row_num1 | row_num2 | + ------ + --------- + ------------ + -------- + ---------- + ---------- + | 2000年| 芬兰| 电脑| 1500 | 2 | 1 | | 2000年| 芬兰| 电话| 100 | 1 | 2 | | 2001 | 芬兰| 电话| 10 | 3 | 3 | | 2000年| 印度| 计算器| 75 | 2 | 1 | | 2000年| 印度| 计算器| 75 | 3 | 2 | | 2000年| 印度| 电脑| 1200 | 1 | 3 | | 2000年| 美国| 计算器| 75 | 5 | 1 | | 2000年| 美国| 电脑| 1500 | 4 | 2 | | 2001 | 美国| 计算器| 50 | 2 | 3 | | 2001 | 美国| 电脑| 1500 | 3 | 4 | | 2001 | 美国| 电脑| 1200 | 7 | 5 | | 2001 | 美国| 电视| 150 | 1 | 6 | | 2001 | 美国| 电视| 100 | 6 | 7 | + ------ + --------- + ------------ + -------- + ---------- + ---------- +
如前所述,要使用窗口函数(或将聚合函数视为窗口函数),请
OVER
在函数调用后
包含一个
子句。
该
OVER
条款有两种形式:
over_clause
: {OVER(window_spec
)| 超过window_name
}
两种形式都定义了窗口函数应如何处理查询行。
它们的不同之处在于窗口是直接在
OVER
子句中
定义
,还是由对查询中其他位置定义的命名窗口的引用提供:
在第一种情况下,窗口规范直接出现在
OVER
括号内
的
子句中。
在第二种情况下,
window_name
是由
WINDOW
查询中其他地方
的
子句
定义的窗口规范的名称
。
有关详细信息,请参见
第12.21.4节“命名Windows”
。
对于
语法,窗口规范有几个部分,都是可选的:
OVER
(
window_spec
)
window_spec
: [window_name
] [partition_clause
] [order_clause
] [frame_clause
]
如果
OVER()
为空,则窗口由所有查询行组成,窗口函数使用所有行计算结果。
否则,括号内的子句确定使用哪些查询行来计算函数结果以及如何对它们进行分区和排序:
window_name
:由
WINDOW
查询中其他位置
的
子句
定义的窗口的名称
。
如果
window_name
在
OVER
子句中单独出现,则它完全定义窗口。
如果还给出了分区,排序或框架子句,则它们会修改指定窗口的解释。
有关详细信息,请参见
第12.21.4节“命名Windows”
。
partition_clause
:
PARTITION BY
子句指示如何将查询行划分为组。
给定行的窗口函数结果基于包含该行的分区的行。
如果
PARTITION BY
省略,则存在由所有查询行组成的单个分区。
窗口函数的分区与表分区不同。 有关表分区的信息,请参见 第23章, 分区 。
partition_clause
有这种语法:
partition_clause
: PARTITION BYexpr
[,expr
] ......
标准SQL只需要
PARTITION BY
后跟列名。
MySQL扩展是允许表达式,而不仅仅是列名。
例如,如果一个表包含一个
TIMESTAMP
名为
的
列
ts
,标准SQL允许
PARTITION BY ts
但不允许
PARTITION BY HOUR(ts)
,而MySQL允许两者。
order_clause
:
ORDER
BY
子句指示如何对每个分区中的行进行排序。
根据
ORDER BY
子句
相等的分区行
被视为对等。
如果
ORDER BY
省略,则分区行是无序的,没有隐含的处理顺序,并且所有分区行都是对等的。
order_clause
有这种语法:
order_clause
: ORDER BYexpr
[ASC | DESC] [,expr
[ASC | DESC]] ......
每个
ORDER BY
表达式可选地可以跟随
ASC
或
DESC
指示排序方向。
默认为
ASC
未指定方向。
NULL
值首先排序为升序排序,最后排序为降序排序。
一个
ORDER BY
单独的分区中的一个窗口定义适用。
要将结果集整体排序,请
ORDER BY
在查询顶级
包含a
。
frame_clause
:帧是当前分区的子集,frame子句指定如何定义子集。
frame子句有许多子条款。
有关详细信息,请参见
第12.21.3节“窗口功能框架规范”
。
与窗口函数一起使用的窗口的定义可以包括frame子句。 帧是当前分区的子集,frame子句指定如何定义子集。
帧是根据当前行确定的,这使得帧能够在分区内移动,具体取决于其分区内当前行的位置。 例子:
通过将帧定义为从分区开始到当前行的所有行,您可以计算每行的运行总计。
通过将框架定义为
N
当前行两侧的
扩展
行,您可以计算滚动平均值。
以下查询演示了如何使用移动框架来计算每组时间排序
level
值中的
运行总计
,以及从当前行计算的滚动平均值以及紧接在其之前和之后的行:
MySQL的>SELECT
time, subject, val,
SUM(val) OVER (PARTITION BY subject ORDER BY time
ROWS UNBOUNDED PRECEDING)
AS running_total,
AVG(val) OVER (PARTITION BY subject ORDER BY time
ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING)
AS running_average
FROM observations;
+ ---------- + --------- + ------ + --------------- + ----- ------------ + | 时间| 主题| val | running_total | running_average | + ---------- + --------- + ------ + --------------- + ----- ------------ + | 07:00:00 | st113 | 10 | 10 | 9.5000 | | 07:15:00 | st113 | 9 | 19 | 14.6667 | | 07:30:00 | st113 | 25 | 44 | 18.0000 | | 07:45:00 | st113 | 20 | 64 | 22.5000 | | 07:00:00 | xh458 | 0 | 0 | 5.0000 | | 07:15:00 | xh458 | 10 | 10 | 5.0000 | | 07:30:00 | xh458 | 5 | 15 | 15.0000 | | 07:45:00 | xh458 | 30 | 45 | 20.0000 | | 08:00:00 | xh458 | 25 | 70 | 27.5000 | + ---------- + --------- + ------ + --------------- + ----- ------------ +
对于
running_average
列,在第一个之前或之后没有帧行。
在这些情况下,
AVG()
计算可用行的平均值。
用作窗口函数的聚合函数对当前行框架中的行进行操作,这些非聚合窗口函数也是如此:
FIRST_VALUE() LAST_VALUE() NTH_VALUE()
标准SQL指定在整个分区上运行的窗口函数应该没有frame子句。 MySQL为这些函数允许一个frame子句但忽略它。 即使指定了框架,这些函数也会使用整个分区:
CUME_DIST() DENSE_RANK() 落后() 铅() NTILE() PERCENT_RANK() 秩() ROW_NUMBER()
如果给出了frame子句,则具有以下语法:
frame_clause
:frame_units
frame_extent
frame_units
: {ROWS | 范围}
在没有frame子句的情况下,默认帧取决于是否存在
ORDER BY
子句,如本节后面所述。
该
frame_units
值指示当前行和帧行之间的关系类型:
ROWS
:框架由开始和结束行位置定义。
偏移量是行号与当前行号的差异。
RANGE
:框架由值范围内的行定义。
偏移量是行值与当前行值的差异。
该
frame_extent
值表示帧的起点和终点。
您可以只指定帧的开头(在这种情况下,当前行隐式结束)或用于
BETWEEN
指定两个帧端点:
frame_extent
: {frame_start
|frame_between
}frame_between
: 在frame_start
和之间frame_end
frame_start
,frame_end
:{ 当前行 | 无约束的先行 | 以下是无限制的 |expr
前 |expr
以下 }
使用
BETWEEN
语法,
frame_start
不得晚于
frame_end
。
允许
值
frame_start
和
frame_end
值具有以下含义:
CURRENT ROW
:对于
ROWS
,绑定是当前行。
因为
RANGE
,bound是当前行的对等体。
UNBOUNDED PRECEDING
:绑定是第一个分区行。
UNBOUNDED FOLLOWING
:绑定是最后一个分区行。
:对于
expr
PRECEDINGROWS
,绑定是
expr
当前行之前的行。
对于
RANGE
,bound是值等于当前行值减去的行
expr
;
如果当前行值为
NULL
,
则该行是
该行的对等点。
对于
(和
expr
PRECEDING
),
expr
FOLLOWINGexpr
可以是
?
参数标记(用于预准备语句),非负数字文字或表单的时间间隔
。
对于
表达式,
指定非负区间值,并且
是一个关键字,指示应在其中解释值的单位。
(有关详细信息,允许
符,看到的描述
功能在
12.7节,“日期和时间函数”
。)
INTERVAL
val
unit
INTERVAL
val
unit
units
DATE_ADD()
RANGE
分别对
数字或时间表达式
的数字或时间
expr
要求
ORDER
BY
。
有效
和
expr
PRECEDING
指标的
例子
:
expr
FOLLOWING
10预先 间隔5天预付款 5以下 INTERVAL'2:30'MINUTE_SECOND以下
:对于
expr
FOLLOWINGROWS
,绑定是
expr
当前行之后的行。
对于
RANGE
,bound是值等于当前行值加上的行
expr
;
如果当前行值为
NULL
,
则该行是
该行的对等点。
有关允许值
expr
,请参阅说明
。
expr
PRECEDING
下面的查询演示
FIRST_VALUE()
,
LAST_VALUE()
以及两个实例
NTH_VALUE()
:
MySQL的>SELECT
time, subject, val,
FIRST_VALUE(val) OVER w AS 'first',
LAST_VALUE(val) OVER w AS 'last',
NTH_VALUE(val, 2) OVER w AS 'second',
NTH_VALUE(val, 4) OVER w AS 'fourth'
FROM observations
WINDOW w AS (PARTITION BY subject ORDER BY time
ROWS UNBOUNDED PRECEDING);
+ ---------- + --------- + ------ + ------- + ------ + ------ - + -------- + | 时间| 主题| val | 第一个| 最后| 第二个| 第四| + ---------- + --------- + ------ + ------- + ------ + ------ - + -------- + | 07:00:00 | st113 | 10 | 10 | 10 | NULL | NULL | | 07:15:00 | st113 | 9 | 10 | 9 | 9 | NULL | | 07:30:00 | st113 | 25 | 10 | 25 | 9 | NULL | | 07:45:00 | st113 | 20 | 10 | 20 | 9 | 20 | | 07:00:00 | xh458 | 0 | 0 | 0 | NULL | NULL | | 07:15:00 | xh458 | 10 | 0 | 10 | 10 | NULL | | 07:30:00 | xh458 | 5 | 0 | 5 | 10 | NULL | | 07:45:00 | xh458 | 30 | 0 | 30 | 10 | 30 | | 08:00:00 | xh458 | 25 | 0 | 25 | 10 | 30 | + ---------- + --------- + ------ + ------- + ------ + ------ - + -------- +
每个函数使用当前帧中的行,根据所示的窗口定义,这些行从第一个分区行延伸到当前行。
对于
NTH_VALUE()
调用,当前帧并不总是包括所请求的行;
在这种情况下,返回值是
NULL
。
在没有frame子句的情况下,默认帧取决于是否存在
ORDER BY
子句:
使用
ORDER BY
:默认框架包括从分区开始到当前行的行,包括当前行的所有对等项(根据
ORDER BY
子句
等于当前行的行
)。
默认值等效于此帧规范:
无界先行与当前行之间的范围
不使用
ORDER BY
:默认框架包括所有分区行(因为没有
ORDER
BY
,所有分区行都是对等的)。
默认值等效于此帧规范:
无界先行与无界之间的范围
因为默认框架根据是否存在而不同
ORDER BY
,添加
ORDER
BY
到查询以获得确定性结果可能会更改结果。
(例如,
SUM()
可能会更改
生成的值
。)要获得相同但按顺序排序的结果
ORDER BY
,请提供要使用的显式帧规范,而不管是否
ORDER BY
存在。
当前行值为时,帧规范的含义可以是非显而易见的
NULL
。
假设是这种情况,这些示例说明了各种帧规范如何适用:
ORDER BY X ASC RANGE BETWEEN 10 FOLLOWING AND 15
FOLLOWING
帧开始于
NULL
和停止
NULL
,因此仅包括具有值的行
NULL
。
ORDER BY X ASC RANGE BETWEEN 10 FOLLOWING AND
UNBOUNDED FOLLOWING
框架从
NULL
分区结束处
开始
并停止。
因为
ASC
排序
NULL
首先
放置
值,所以帧是整个分区。
ORDER BY X DESC RANGE BETWEEN 10 FOLLOWING AND
UNBOUNDED FOLLOWING
框架从
NULL
分区结束处
开始
并停止。
因为
DESC
排序
NULL
最后
放置
值,所以框架只是
NULL
值。
ORDER BY X ASC RANGE BETWEEN 10 PRECEDING AND
UNBOUNDED FOLLOWING
框架从
NULL
分区结束处
开始
并停止。
因为
ASC
排序
NULL
首先
放置
值,所以帧是整个分区。
ORDER BY X ASC RANGE BETWEEN 10 PRECEDING AND 10
FOLLOWING
帧开始于
NULL
和停止
NULL
,因此仅包括具有值的行
NULL
。
ORDER BY X ASC RANGE BETWEEN 10 PRECEDING AND 1
PRECEDING
帧开始于
NULL
和停止
NULL
,因此仅包括具有值的行
NULL
。
ORDER BY X ASC RANGE BETWEEN UNBOUNDED PRECEDING
AND 10 FOLLOWING
框架从分区的开始处开始,并在具有值的行处停止
NULL
。
因为
ASC
排序
NULL
首先
放置
值,所以框架只是
NULL
值。
可以定义Windows并给出用于在
OVER
子句中
引用它们的名称
。
为此,请使用
WINDOW
子句。
如果存在于查询中,则该
WINDOW
子句位于
HAVING
和
ORDER BY
子句
的位置之间
,并具有以下语法:
WINDOWwindow_name
AS(window_spec
) [,window_name
AS(window_spec
)] ......
对于每个窗口定义,
window_name
是窗口名称,并且与
子句
window_spec
的括号之间给出的窗口规范类型相同
OVER
,如
第12.21.2节“窗口函数概念和语法”中所述
:
window_spec
: [window_name
] [partition_clause
] [order_clause
] [frame_clause
]
甲
WINDOW
子句对于其中多个查询是有用
OVER
的条款,否则定义相同的窗口。
相反,您可以定义窗口一次,为其命名,并在
OVER
子句中
引用名称
。
考虑这个查询,它多次定义同一个窗口:
选择 VAL, ROW_NUMBER()OVER(ORDER BY val)AS'row_number', RANK()OVER(ORDER BY val)AS'rank', DENSE_RANK()OVER(ORDER BY val)AS'heavy_rank' 来自数字;
通过使用
WINDOW
一次定义窗口并在
OVER
子句中
按名称引用窗口,
可以更简单地编写查询
:
选择 VAL, ROW_NUMBER()超过'row_number', RANK()超过'等级', DENSE_RANK()超过'dense_rank' 从数字 WINDOW W AS(ORDER BY val);
命名窗口还可以更轻松地尝试窗口定义以查看对查询结果的影响。
您只需要修改
WINDOW
子句中
的窗口定义
,而不是多个
OVER
子句定义。
如果
OVER
子句使用
而不是
,则可以通过添加其他子句来修改命名窗口。
例如,此查询定义了一个包含分区的窗口,并
在
子句中
使用
以不同方式修改窗口:
OVER
(
window_name
...)OVER
window_name
ORDER BY
OVER
选择 DISTINCT年份,国家, FIRST_VALUE(年)超过(按年度ASC排序)AS, FIRST_VALUE(年)超过(按年度DESC)作为最后一个 从销售 WINDOW W AS(国家分区);
一个
OVER
子句只能添加属性命名的窗口,不能修改它们。
如果指定的窗口定义包含分区,排序或框架属性,则
OVER
引用窗口名称
的
子句也不能包含相同类型的属性或发生错误:
允许此构造,因为窗口定义和引用
OVER
子句不包含相同类型的属性:
超过(按国家/地区分类) ... WINDOW w AS(按国家划分)
不允许使用此构造,因为该
OVER
子句
PARTITION
BY
为已经具有以下内容的命名窗口
指定
PARTITION BY
:
超过(按年度划分) ... WINDOW w AS(按国家划分)
命名窗口的定义本身可以以a开头
window_name
。
在这种情况下,允许前向和后向引用,但不允许循环:
这是允许的; 它包含前向和后向引用,但没有循环:
WINDOW w1 AS(w2),w2 AS(),w3 AS(w1)
这是不允许的,因为它包含一个循环:
WINDOW w1 AS(w2),w2 AS(w3),w3 AS(w1)
SQL标准对不能使用的窗口函数
UPDATE
或
DELETE
更新行的语句
施加约束
。
允许在这些语句的子查询中使用此类函数(以选择行)。
MySQL不支持这些窗口功能:
DISTINCT
聚合窗口函数的语法。
嵌套窗口函数。
动态帧端点,它取决于当前行的值。
解析器识别这些不支持的窗口构造:
的
GROUPS
帧为单位指定符进行解析,但产生一个错误。
只有
ROWS
和
RANGE
支持。
EXCLUDE
解析帧规范
的
子句,但会产生错误。
IGNORE NULLS
被解析,但产生错误。
仅
RESPECT NULLS
支持。
FROM LAST
被解析,但产生错误。
仅
FROM FIRST
支持。
从MySQL 8.0.16开始,MySQL包含内置的SQL函数,可以格式化或检索性能模式数据,并且可以用作相应
sys
模式存储函数的
等效
函数。
可以在任何模式中调用内置函数,并且不需要限定符,这与
sys
需要
sys.
模式限定符或
sys
当前模式
的
函数
不同
。
表12.28性能模式函数
名称 | 描述 |
---|---|
FORMAT_BYTES() |
将字节数转换为带单位的值 |
FORMAT_PICO_TIME() |
将时间(皮秒)转换为单位值 |
PS_CURRENT_THREAD_ID() |
当前线程的性能架构线程ID |
PS_THREAD_ID() |
给定线程的性能架构线程ID |
内置函数取代了相应的
sys
函数,这些函数已弃用,将在未来的MySQL版本中删除。
sys
应调整
使用这些
函数的
应用程序
以使用内置函数,同时记住
sys
函数和内置函数
之间的一些细微差别
。
有关这些差异的详细信息,请参阅本节中的功能说明。
给定数字字节计数,将其转换为人类可读格式并返回由值和单位指示符组成的字符串。 该字符串包含舍入到2位小数的字节数和最少3位有效数字。 小于1024字节的数字表示为整数,不是舍入的。
units指示符取决于byte-count参数的大小,如下表所示。
论证价值 | 结果单位 | 结果单位指标 |
---|---|---|
高达1023 | 字节 | 字节 |
最多1024 2 - 1 | kibibytes | 昆明植物研究所 |
最多1024 3 - 1 | mebibytes | MIB |
最多1024 4 - 1 | gibibytes | 吉布 |
最多1024 5 - 1 | tebibytes | 的TiB |
最多1024 6 - 1 | pebibytes | PiB负荷 |
1024 6 及以上 | exbibytes | EIB |
MySQL的> SELECT FORMAT_BYTES(512), FORMAT_BYTES(18446644073709551615);
+ ------------------- + ----------------------------- ------- +
| FORMAT_BYTES(512)| FORMAT_BYTES(18446644073709551615)|
+ ------------------- + ----------------------------- ------- +
| 512字节| 16.00 EiB |
+ ------------------- + ----------------------------- ------- +
FORMAT_BYTES()
在MySQL 8.0.16中添加了。
它可以用来代替
sys
模式
format_bytes()
函数,记住这个区别:
FORMAT_BYTES()
使用
EiB
单位指标。
sys.format_bytes()
才不是。
给定数字性能模式延迟或以皮秒为单位的等待时间,将其转换为人类可读格式并返回由值和单位指示符组成的字符串。 该字符串包含舍入到2位小数的十进制时间和最少3位有效数字。 1纳秒以下的时间表示为整数,不是四舍五入。
单位指示符取决于时间值参数的大小,如下表所示。
论证价值 | 结果单位 | 结果单位指标 |
---|---|---|
最多10 3 - 1 | 皮秒 | PS |
最多10 6 - 1 | 纳秒 | NS |
高达10 9 - 1 | 微秒 | 我们 |
最多10 12 - 1 | 毫秒 | 女士 |
高达60×10 12 - 1 | 秒 | 小号 |
高达3.6×10 15 - 1 | 分钟 | 分 |
高达8.64×10 16 - 1 | 小时 | H |
8.64×10 16 及以上 | 天 | d |
MySQL的> SELECT FORMAT_PICO_TIME(3501), FORMAT_PICO_TIME(188732396662000);
+ ------------------------ + ------------------------ ----------- +
| FORMAT_PICO_TIME(3501)| FORMAT_PICO_TIME(188732396662000)|
+ ------------------------ + ------------------------ ----------- +
| 3.50 ns | 3.15分钟|
+ ------------------------ + ------------------------ ----------- +
FORMAT_PICO_TIME()
在MySQL 8.0.16中添加了。
它可以用来代替
sys
模式
format_time()
函数,记住这些差异:
要指示分钟,请
sys.format_time()
使用
m
单位指示符,而
FORMAT_PICO_TIME()
使用
min
。
sys.format_time()
使用
w
(周)单位指标。
FORMAT_PICO_TIME()
才不是。
返回
BIGINT UNSIGNED
表示分配给当前连接的Performance Schema线程ID
的
值。
线程ID返回值是
THREAD_ID
Performance Schema表列中
给出的类型的值
。
性能架构配置的影响
PS_CURRENT_THREAD_ID()
方式
与之
相同
PS_THREAD_ID()
。
有关详细信息,请参阅该功能的说明。
MySQL的>SELECT PS_CURRENT_THREAD_ID();
+ ------------------------ + | PS_CURRENT_THREAD_ID()| + ------------------------ + | 52 | + ------------------------ + MySQL的>SELECT PS_THREAD_ID(CONNECTION_ID());
+ ------------------------------- + | PS_THREAD_ID(CONNECTION_ID())| + ------------------------------- + | 52 | + ------------------------------- +
PS_CURRENT_THREAD_ID()
在MySQL 8.0.16中添加了。
它可以用作调用
带有
或
的参数
的
sys
模式
ps_thread_id()
函数
的快捷方式
。
NULL
CONNECTION_ID()
给定连接ID,返回
BIGINT
UNSIGNED
表示分配给连接ID的性能模式线程ID
的
值,或
NULL
如果
不存在线程ID。
后者可以针对未检测的线程发生。
连接ID参数是
PROCESSLIST_ID
Performance Schema
threads
表或
Id
列的
列中
给出的类型的值
SHOW
PROCESSLIST
输出
。
线程ID返回值是在给定的类型的值
THREAD_ID
Performance Schema表列中
。
性能模式配置会影响
PS_THREAD_ID()
操作,如下所示。
(这些评论也适用于
PS_CURRENT_THREAD_ID()
。)
禁用
thread_instrumentation
使用者会禁用在线程级别收集和聚合的统计信息,但不会对其产生影响
PS_THREAD_ID()
。
如果
performance_schema_max_thread_instances
不为0,则性能模式为线程统计分配内存,并为每个可用实例内存的线程分配内部ID。
如果存在实例内存不可用的线程,则
PS_THREAD_ID()
返回
NULL
;
在这种情况下,
Performance_schema_thread_instances_lost
将非零。
如果
performance_schema_max_thread_instances
为0,则性能模式不分配线程内存并
PS_THREAD_ID()
返回
NULL
。
如果禁用性能架构本身,则会
PS_THREAD_ID()
产生错误。
MySQL的> SELECT PS_THREAD_ID(6);
+ ----------------- +
| PS_THREAD_ID(6)|
+ ----------------- +
| 45 |
+ ----------------- +
PS_THREAD_ID()
在MySQL 8.0.16中添加了。
它可以用来代替
sys
模式
ps_thread_id()
函数,记住这个区别:
使用参数
NULL
,
sys.ps_thread_id()
返回当前连接的线程ID,而
PS_THREAD_ID()
返回
NULL
。
要获取当前连接线程ID,请
PS_CURRENT_THREAD_ID()
改用。
表12.29内部功能
名称 | 描述 |
---|---|
CAN_ACCESS_COLUMN() |
限内部使用 |
CAN_ACCESS_DATABASE() |
限内部使用 |
CAN_ACCESS_TABLE() |
限内部使用 |
CAN_ACCESS_VIEW() |
限内部使用 |
GET_DD_COLUMN_PRIVILEGES() |
限内部使用 |
GET_DD_CREATE_OPTIONS() |
限内部使用 |
GET_DD_INDEX_SUB_PART_LENGTH() |
限内部使用 |
INTERNAL_AUTO_INCREMENT() |
限内部使用 |
INTERNAL_AVG_ROW_LENGTH() |
限内部使用 |
INTERNAL_CHECK_TIME() |
限内部使用 |
INTERNAL_CHECKSUM() |
限内部使用 |
INTERNAL_DATA_FREE() |
限内部使用 |
INTERNAL_DATA_LENGTH() |
限内部使用 |
INTERNAL_DD_CHAR_LENGTH() |
限内部使用 |
INTERNAL_GET_COMMENT_OR_ERROR() |
限内部使用 |
INTERNAL_GET_VIEW_WARNING_OR_ERROR() |
限内部使用 |
INTERNAL_INDEX_COLUMN_CARDINALITY() |
限内部使用 |
INTERNAL_INDEX_LENGTH() |
限内部使用 |
INTERNAL_KEYS_DISABLED() |
限内部使用 |
INTERNAL_MAX_DATA_LENGTH() |
限内部使用 |
INTERNAL_TABLE_ROWS() |
限内部使用 |
INTERNAL_UPDATE_TIME() |
限内部使用 |
本节中列出的功能仅供服务器内部使用。 用户尝试调用它们会导致错误。
表12.30其他功能
名称 | 描述 |
---|---|
ANY_VALUE() |
抑制ONLY_FULL_GROUP_BY值拒绝 |
BIN_TO_UUID() |
将二进制UUID转换为字符串 |
DEFAULT() |
返回表列的默认值 |
GROUPING() |
区分超级聚合ROLLUP行与常规行 |
INET_ATON() |
返回IP地址的数值 |
INET_NTOA() |
从数值返回IP地址 |
INET6_ATON() |
返回IPv6地址的数值 |
INET6_NTOA() |
从数值返回IPv6地址 |
IS_IPV4() |
参数是否为IPv4地址 |
IS_IPV4_COMPAT() |
参数是否是IPv4兼容的地址 |
IS_IPV4_MAPPED() |
参数是否是IPv4映射地址 |
IS_IPV6() |
参数是否是IPv6地址 |
IS_UUID() |
参数是否是有效的UUID |
MASTER_POS_WAIT() |
阻止,直到从站已读取并应用所有更新到指定位置 |
NAME_CONST() |
导致列具有给定名称 |
RAND() |
返回随机浮点值 |
SLEEP() |
睡几秒钟 |
UUID() |
返回通用唯一标识符(UUID) |
UUID_SHORT() |
返回整数值通用标识符 |
UUID_TO_BIN() |
将字符串UUID转换为二进制 |
VALUES() |
定义INSERT期间要使用的值 |
对于
启用SQL模式的
GROUP BY
查询,
此函数非常有用
ONLY_FULL_GROUP_BY
,因为MySQL拒绝您知道MySQL无法确定的查询的查询。
函数返回值和类型与其参数的返回值和类型相同,但不检查
ONLY_FULL_GROUP_BY
SQL模式
的函数结果
。
例如,如果
name
是非索引列,则以下查询将失败并
ONLY_FULL_GROUP_BY
启用:
MySQL的> SELECT name, address, MAX(age) FROM t GROUP BY name;
错误1055(42000):SELECT列表的表达式#2不在GROUP中
BY子句并包含非聚合列'mydb.t.address'
在功能上不依赖于GROUP BY子句中的列; 这个
与sql_mode = only_full_group_by不兼容
发生故障是因为
address
非聚合列既不在
GROUP BY
列中
命名,
也不在功能上依赖于它们。
因此,
address
每个
name
组中的
行
的
值
是不确定的。
有多种方法可以使MySQL接受查询:
更改表以创建
name
主键或唯一
NOT NULL
列。
这使MySQL能够确定
address
在功能上依赖于
name
;
也就是说,
address
由唯一确定
name
。
(如果
NULL
必须允许
此技术
作为有效值,
则此技术不适用
name
。)
使用
ANY_VALUE()
是指
address
:
SELECT名称,ANY_VALUE(地址),MAX(年龄)FROM t GROUP BY名称;
在这种情况下,MySQL忽略
address
每个
name
组
中
值
的不确定性
并接受查询。
如果您根本不关心为每个组选择哪个非聚合列的值,这可能很有用。
ANY_VALUE()
不是聚集函数,不像功能,例如
SUM()
或
COUNT()
。
它只是用来抑制非确定性的测试。
禁用
ONLY_FULL_GROUP_BY
。
这相当于使用
ANY_VALUE()
with
ONLY_FULL_GROUP_BY
enabled,如上一项所述。
ANY_VALUE()
如果列之间存在函数依赖,但MySQL无法确定它,这也很有用。
以下查询是有效的,因为
age
它在功能上依赖于分组列
age-1
,但MySQL不能告诉它并拒绝
ONLY_FULL_GROUP_BY
启用
的查询
:
选择年龄FROM t GROUP BY age-1;
要使MySQL接受查询,请使用
ANY_VALUE()
:
SELECT ANY_VALUE(age)FROM t GROUP BY age-1;
ANY_VALUE()
可以用于在没有
GROUP BY
子句
的情况下引用聚合函数的查询
:
MySQL的> SELECT name, MAX(age) FROM t;
错误1140(42000):在没有GROUP BY,表达式的聚合查询中
SELECT列表的#1包含非聚合列'mydb.t.name'; 这个
与sql_mode = only_full_group_by不兼容
没有
GROUP BY
,只有一个组,它是不确定的,
name
为组选择值。
ANY_VALUE()
告诉MySQL接受查询:
SELECT ANY_VALUE(name),MAX(age)FROM t;
可能是由于给定数据集的某些属性,您知道所选的非聚合列在功能上有效地依赖于
GROUP BY
列。
例如,应用程序可以强制一列相对于另一列的唯一性。
在这种情况下,使用
ANY_VALUE()
有效的功能依赖列可能是有意义的。
有关其他讨论,请参见 第12.20.3节“GROUP BY的MySQL处理” 。
BIN_TO_UUID(
,
binary_uuid
)BIN_TO_UUID(
binary_uuid
,
swap_flag
)
BIN_TO_UUID()
是反的
UUID_TO_BIN()
。
它将二进制UUID转换为字符串UUID并返回结果。
二进制值应该是UUID作为
VARBINARY(16)
值。
返回值是
utf8
由破折号分隔的五个十六进制数字
的
字符串。
(有关此格式的详细信息,请参阅
UUID()
函数说明。)如果UUID参数为
NULL
,则返回值为
NULL
。
如果任何参数无效,则会发生错误。
BIN_TO_UUID()
需要一个或两个参数:
单参数形式采用二进制UUID值。 假设UUID值没有交换时间低和时间高的部分。 字符串结果与二进制参数的顺序相同。
双参数形式采用二进制UUID值和swap-flag值:
如果
swap_flag
为0,则双参数形式等效于单参数形式。
字符串结果与二进制参数的顺序相同。
如果
swap_flag
为1,则假定UUID值具有交换的时间低和时间高的部分。
这些部件将交换回结果值中的原始位置。
有关时间 - 部分交换的用法示例和信息,请参阅
UUID_TO_BIN()
功能说明。
返回表列的默认值。 如果列没有默认值,则会出现错误。
仅允许具有文字默认值的列
使用
指定命名列的默认值,而不允许使用具有表达式默认值的列。
DEFAULT(
col_name
)
MySQL的> UPDATE t SET i = DEFAULT(i)+1 WHERE id < 100;
将数字格式化
X
为格式
'#,###,###.##'
,舍入到
D
小数位,并将结果作为字符串返回。
有关详细信息,请参见
第12.5节“字符串函数”
。
对于
GROUP BY
包含
WITH ROLLUP
修饰符的
查询
,该
ROLLUP
操作会生成超级聚合输出行,其中
NULL
表示所有值的集合。
该
GROUPING()
功能使您可以区分
NULL
超级聚合行的
NULL
值与常规分组行中的值。
GROUPING()
只允许在选择列表或
HAVING
子句中使用。
每个参数
GROUPING()
必须是与
GROUP BY
子句
中的表达式完全匹配的表达式
。
表达式不能是位置说明符。
对于每个表达式,
GROUPING()
如果当前行中的表达式值
NULL
表示超级聚合值
,则
生成1
。
否则,
GROUPING()
生成0,表示表达式值是
NULL
常规结果行的a或不是
NULL
。
假设该表
t1
包含这些行,其中
NULL
表示
“
other
”
或
“
unknown
”之类的内容
:
MySQL的> SELECT * FROM t1;
+ ------ + ------- + ---------- +
| 名字| 尺寸| 数量|
+ ------ + ------- + ---------- +
| 球| 小| 10 |
| 球| 大| 20 |
| 球| NULL | 5 |
| 箍| 小| 15 |
| 箍| 大| 5 |
| 箍| NULL | 3 |
+ ------ + ------- + ---------- +
表的摘要不是
WITH ROLLUP
这样的:
MySQL的>SELECT name, size, SUM(quantity) AS quantity
FROM t1
GROUP BY name, size;
+ ------ + ------- + ---------- + | 名字| 尺寸| 数量| + ------ + ------- + ---------- + | 球| 小| 10 | | 球| 大| 20 | | 球| NULL | 5 | | 箍| 小| 15 | | 箍| 大| 5 | | 箍| NULL | 3 | + ------ + ------- + ---------- +
结果包含
NULL
值,但这些值不代表超级聚合行,因为查询不包含
WITH ROLLUP
。
添加
WITH ROLLUP
会生成包含其他
NULL
值的
超级聚合摘要行
。
但是,如果不将此结果与前一个结果进行比较,则很难看出哪些
NULL
值出现在超级聚合行中,哪些值出现在常规分组行中:
MySQL的>SELECT name, size, SUM(quantity) AS quantity
FROM t1
GROUP BY name, size WITH ROLLUP;
+ ------ + ------- + ---------- + | 名字| 尺寸| 数量| + ------ + ------- + ---------- + | 球| NULL | 5 | | 球| 大| 20 | | 球| 小| 10 | | 球| NULL | 35 | | 箍| NULL | 3 | | 箍| 大| 5 | | 箍| 小| 15 | | 箍| NULL | 23 | | NULL | NULL | 58 | + ------ + ------- + ---------- +
要区分
NULL
超级聚合行中的值与常规分组行中的值,请使用
GROUPING()
,仅对超级聚合
NULL
值
返回1
:
MySQL的>SELECT
name, size, SUM(quantity) AS quantity,
GROUPING(name) AS grp_name,
GROUPING(size) AS grp_size
FROM t1
GROUP BY name, size WITH ROLLUP;
+ ------ + ------- + ---------- + ---------- + ---------- + | 名字| 尺寸| 数量| grp_name | grp_size | + ------ + ------- + ---------- + ---------- + ---------- + | 球| NULL | 5 | 0 | 0 | | 球| 大| 20 | 0 | 0 | | 球| 小| 10 | 0 | 0 | | 球| NULL | 35 | 0 | 1 | | 箍| NULL | 3 | 0 | 0 | | 箍| 大| 5 | 0 | 0 | | 箍| 小| 15 | 0 | 0 | | 箍| NULL | 23 | 0 | 1 | | NULL | NULL | 58 | 1 | 1 | + ------ + ------- + ---------- + ---------- + ---------- +
常用用途
GROUPING()
:
用标签代替超级聚合
NULL
值:
MySQL的>SELECT
IF(GROUPING(name) = 1, 'All items', name) AS name,
IF(GROUPING(size) = 1, 'All sizes', size) AS size,
SUM(quantity) AS quantity
FROM t1
GROUP BY name, size WITH ROLLUP;
+ ----------- ----------- + ---------- + + | 名字| 尺寸| 数量| + ----------- ----------- + ---------- + + | 球| NULL | 5 | | 球| 大| 20 | | 球| 小| 10 | | 球| 所有尺寸| 35 | | 箍| NULL | 3 | | 箍| 大| 5 | | 箍| 小| 15 | | 箍| 所有尺寸| 23 | | 所有项目| 所有尺寸| 58 | + ----------- ----------- + ---------- + +
通过过滤掉常规的分组行,仅返回超级聚合行:
MySQL的>SELECT name, size, SUM(quantity) AS quantity
FROM t1
GROUP BY name, size WITH ROLLUP
HAVING GROUPING(name) = 1 OR GROUPING(size) = 1;
+ ------ + ------ + ---------- + | 名字| 尺寸| 数量| + ------ + ------ + ---------- + | 球| NULL | 35 | | 箍| NULL | 23 | | NULL | NULL | 58 | + ------ + ------ + ---------- +
GROUPING()
允许多个表达式参数。
在这种情况下,
GROUPING()
返回值表示从每个表达式的结果组合的位掩码,其中最低位对应于最右侧表达式的结果。
例如,使用三个表达式参数,
就像这样计算:
GROUPING(
expr1
,
expr2
,
expr3
)
GROUPING的结果(expr3
)的 +结果为GROUPING(expr2
)<< 1 +结果为GROUPING(expr1
)<< 2
以下查询显示如何
GROUPING()
单个参数的结果
组合以进行多参数调用以生成位掩码值:
MySQL的>SELECT
name, size, SUM(quantity) AS quantity,
GROUPING(name) AS grp_name,
GROUPING(size) AS grp_size,
GROUPING(name, size) AS grp_all
FROM t1
GROUP BY name, size WITH ROLLUP;
+ ------ + ------- + ---------- + ---------- + ---------- + - -------- + | 名字| 尺寸| 数量| grp_name | grp_size | grp_all | + ------ + ------- + ---------- + ---------- + ---------- + - -------- + | 球| NULL | 5 | 0 | 0 | 0 | | 球| 大| 20 | 0 | 0 | 0 | | 球| 小| 10 | 0 | 0 | 0 | | 球| NULL | 35 | 0 | 1 | 1 | | 箍| NULL | 3 | 0 | 0 | 0 | | 箍| 大| 5 | 0 | 0 | 0 | | 箍| 小| 15 | 0 | 0 | 0 | | 箍| NULL | 23 | 0 | 1 | 1 | | NULL | NULL | 58 | 1 | 1 | 3 | + ------ + ------- + ---------- + ---------- + ---------- + - -------- +
对于多个表达式参数,
GROUPING()
如果任何表达式表示超级聚合值
,则
返回值为非零。
GROUPING()
因此,通过使用单个多参数
GROUPING()
调用而不是多个单参数调用,
多参数
语法提供了一种更简单的方法来编写仅返回超级聚合行的早期查询
:
MySQL的>SELECT name, size, SUM(quantity) AS quantity
FROM t1
GROUP BY name, size WITH ROLLUP
HAVING GROUPING(name, size) <> 0;
+ ------ + ------ + ---------- + | 名字| 尺寸| 数量| + ------ + ------ + ---------- + | 球| NULL | 35 | | 箍| NULL | 23 | | NULL | NULL | 58 | + ------ + ------ + ---------- +
使用
GROUPING()
受以下限制:
不要将子查询
GROUP BY
表达式用作
GROUPING()
参数,因为匹配可能会失败。
例如,此查询的匹配失败:
MySQL的>SELECT GROUPING((SELECT MAX(name) FROM t1))
FROM t1
GROUP BY (SELECT MAX(name) FROM t1) WITH ROLLUP;
ERROR 3580(HY000):GROUPING函数的参数#1不在GROUP BY中
GROUP BY
文字表达式不应该在
HAVING
子句中用作
GROUPING()
参数。
由于当优化评估之间的差异
GROUP BY
和
HAVING
,匹配可能会成功,但
GROUPING()
评价不会产生预期的结果。
考虑这个查询:
选择AS f1,'w'AS f2 从T GROUP BY f1,f2 WITH ROLLUP 分组(f2)= 1;
GROUPING()
对于文字常量表达式的评估比对整个
HAVING
子句的
评估更早
并返回0.要检查此类查询是否受到影响,
EXPLAIN
请
Impossible having
在
Extra
列中
使用
并查找
。
有关详细信息
WITH ROLLUP
,并
GROUPING()
请参阅
第12.20.2,“GROUP BY修改”
。
给定IPv4网络地址的虚线四边形表示为字符串,返回一个整数,表示网络字节顺序(大端)的地址的数值。
如果它不理解它的参数,则
INET_ATON()
返回
NULL
。
MySQL的> SELECT INET_ATON('10.0.5.9');
- > 167773449
对于此示例,返回值计算为10×256 3 + 0×256 2 + 5×256 + 9。
INET_ATON()
可能会也可能不会返回
NULL
短格式IP地址
的非
结果(例如
'127.1'
表示
'127.0.0.1'
)。
因此,
INET_ATON()
不应将a用于此类地址。
要存储生成的值
INET_ATON()
,请使用
INT UNSIGNED
列而不是
INT
签名。
如果使用带符号列,则无法正确存储与第一个八位字节大于127的IP地址对应的值。
请参见
第11.2.6节“超出范围和溢出处理”
。
给定网络字节顺序的数字IPv4网络地址,返回地址的点分四字符串表示形式作为连接字符集中的字符串。
如果它不理解它的参数,则
INET_NTOA()
返回
NULL
。
MySQL的> SELECT INET_NTOA(167773449);
- > '10 .0.5.9'
给定IPv6或IPv4网络地址作为字符串,返回二进制字符串,该字符串表示网络字节顺序(大端)的地址的数值。
由于数字格式的IPv6地址需要的字节数多于最大的整数类型,因此此函数返回的表示形式具有以下
VARBINARY
数据类型:
VARBINARY(16)
用于IPv6地址和
VARBINARY(4)
IPv4地址。
如果参数不是有效地址,则
INET6_ATON()
返回
NULL
。
以下示例用于
HEX()
以
INET6_ATON()
可打印的形式
显示
结果:
MySQL的>SELECT HEX(INET6_ATON('fdfe::5a55:caff:fefa:9089'));
- >'FDFE0000000000005A55CAFFFEFA9089' MySQL的>SELECT HEX(INET6_ATON('10.0.5.9'));
- >'0A000509'
INET6_ATON()
观察有效参数的几个约束。
这些在下面的列表中给出以及示例。
不允许使用尾随区域ID,如
fe80::3%1
或
fe80::3%eth0
。
不允许使用尾随网络掩码,如
2001:45f:3:ba::/64
或
198.51.100.0/24
。
对于表示IPv4地址的值,仅支持无类地址。
有类别的地址如
198.51.1
被拒绝。
不允许使用尾随端口号,如
198.51.100.2:8080
。
不允许地址组件中的十六进制数字,如
198.0xa0.1.2
。
不支持八进制数:
198.51.010.1
被视为
198.51.10.1
,不是
198.51.8.1
。
这些IPv4约束也适用于具有IPv4地址部分的IPv6地址,例如IPv4兼容或IPv4映射地址。
要
expr
将以数字形式表示
的IPv4地址
作为
INT
值
转换为
以数字形式表示
的IPv6地址作为
VARBINARY
值,请使用以下表达式:
INET6_ATON(INET_NTOA(expr
))
例如:
MySQL的> SELECT HEX(INET6_ATON(INET_NTOA(167773449)));
- >'0A000509'
给定以数字形式表示为二进制字符串的IPv6或IPv4网络地址,将地址的字符串表示形式返回为连接字符集中的字符串。
如果参数不是有效地址,则
INET6_NTOA()
返回
NULL
。
INET6_NTOA()
有这些属性:
它不使用操作系统函数来执行转换,因此输出字符串与平台无关。
返回字符串的最大长度为39(4 x 8 + 7)。 鉴于此声明:
CREATE TABLE t AS SELECT INET6_NTOA(expr
)AS c1;
结果表将具有以下定义:
CREATE TABLE t(c1 VARCHAR(39)CHARACTER SET utf8 DEFAULT NULL);
返回字符串使用小写字母表示IPv6地址。
MySQL的>SELECT INET6_NTOA(INET6_ATON('fdfe::5a55:caff:fefa:9089'));
- >'fdfe :: 5a55:caff:fefa:9089' MySQL的>SELECT INET6_NTOA(INET6_ATON('10.0.5.9'));
- > '10 .0.5.9' MySQL的>SELECT INET6_NTOA(UNHEX('FDFE0000000000005A55CAFFFEFA9089'));
- >'fdfe :: 5a55:caff:fefa:9089' MySQL的>SELECT INET6_NTOA(UNHEX('0A000509'));
- > '10 .0.5.9'
如果参数是指定为字符串的有效IPv4地址,则返回1,否则返回0。
MySQL的> SELECT IS_IPV4('10.0.5.9'), IS_IPV4('10.0.5.256');
- > 1,0
对于给定的参数,如果
IS_IPV4()
返回1,
INET_ATON()
(和
INET6_ATON()
)将返回非
NULL
。
相反的陈述不正确:在某些情况下,
INET_ATON()
返回非
NULL
时
IS_IPV4()
返回0
返回
。
正如前面的评论所暗示的那样,
IS_IPV4()
比
INET_ATON()
构成有效IPv4地址的内容
更严格
,因此对于需要对无效值执行强检查的应用程序可能很有用。
或者,用于
INET6_ATON()
将IPv4地址转换为内部格式并检查
NULL
结果(表示无效的地址)。
关于检查IPv4地址
INET6_ATON()
同样强大
IS_IPV4()
。
此函数将以数字形式表示的IPv6地址作为二进制字符串,如返回
INET6_ATON()
。
如果参数是有效的IPv4兼容IPv6地址,则返回1,否则返回0。
IPv4兼容地址具有该形式
。
::
ipv4_address
MySQL的>SELECT IS_IPV4_COMPAT(INET6_ATON('::10.0.5.9'));
- > 1 MySQL的>SELECT IS_IPV4_COMPAT(INET6_ATON('::ffff:10.0.5.9'));
- > 0
IPv4兼容地址的IPv4部分也可以使用十六进制表示法表示。
例如,
198.51.100.1
具有此原始十六进制值:
MySQL的> SELECT HEX(INET6_ATON('198.51.100.1'));
- >'C6336401'
以IPv4兼容的形式表示,
::198.51.100.1
相当于
::c0a8:0001
或(没有前导零)
::c0a8:1
mysql>SELECT
- >IS_IPV4_COMPAT(INET6_ATON('::198.51.100.1')),
- >IS_IPV4_COMPAT(INET6_ATON('::c0a8:0001')),
- >IS_IPV4_COMPAT(INET6_ATON('::c0a8:1'));
- > 1,1,1
此函数将以数字形式表示的IPv6地址作为二进制字符串,如返回
INET6_ATON()
。
如果参数是有效的IPv4映射IPv6地址,则返回1,否则返回0。
IPv4映射地址具有该形式
。
::ffff:
ipv4_address
MySQL的>SELECT IS_IPV4_MAPPED(INET6_ATON('::10.0.5.9'));
- > 0 MySQL的>SELECT IS_IPV4_MAPPED(INET6_ATON('::ffff:10.0.5.9'));
- > 1
与
IS_IPV4_COMPAT()
IPv4映射地址的IPv4部分一样,也可以使用十六进制表示法表示:
mysql>SELECT
- >IS_IPV4_MAPPED(INET6_ATON('::ffff:198.51.100.1')),
- >IS_IPV4_MAPPED(INET6_ATON('::ffff:c0a8:0001')),
- >IS_IPV4_MAPPED(INET6_ATON('::ffff:c0a8:1'));
- > 1,1,1
如果参数是指定为字符串的有效IPv6地址,则返回1,否则返回0。 此功能不会将IPv4地址视为有效的IPv6地址。
MySQL的> SELECT IS_IPV6('10.0.5.9'), IS_IPV6('::1');
- > 0,1
对于给定的参数,如果
IS_IPV6()
返回1,
INET6_ATON()
则返回非
NULL
。
如果该参数是一个有效的字符串格式的UUID,0如果参数是不是有效的UUID,并返回1
NULL
如果该参数
NULL
。
“ 有效 ” 表示该值采用可以解析的格式。 也就是说,它具有正确的长度并且仅包含允许的字符(任何字母表中的十六进制数字,以及可选的破折号和花括号)。 这种格式最常见:
AAAAAAAA - BBBB - CCCC-DDDD-eeeeeeeeeeee
这些其他格式也是允许的:
aaaaaaaabbbbccccddddeeeeeeeeeeee {AAAAAAAA-BBBB-CCCC-DDDD-eeeeeeeeeeee}
有关值内字段的含义,请参阅
UUID()
函数说明。
MySQL的>SELECT IS_UUID('6ccd780c-baba-1026-9564-5b8c656024db');
+ ------------------------------------------------- + | IS_UUID('6ccd780c-baba-1026-9564-5b8c656024db')| + ------------------------------------------------- + | 1 | + ------------------------------------------------- + MySQL的>SELECT IS_UUID('6CCD780C-BABA-1026-9564-5B8C656024DB');
+ ------------------------------------------------- + | IS_UUID('6CCD780C-BABA-1026-9564-5B8C656024DB')| + ------------------------------------------------- + | 1 | + ------------------------------------------------- + MySQL的>SELECT IS_UUID('6ccd780cbaba102695645b8c656024db');
+ --------------------------------------------- + | IS_UUID('6ccd780cbaba102695645b8c656024db')| + --------------------------------------------- + | 1 | + --------------------------------------------- + MySQL的>SELECT IS_UUID('{6ccd780c-baba-1026-9564-5b8c656024db}');
+ ------------------------------------------------- - + | IS_UUID('{6ccd780c-baba-1026-9564-5b8c656024db}')| + ------------------------------------------------- - + | 1 | + ------------------------------------------------- - + MySQL的>SELECT IS_UUID('6ccd780c-baba-1026-9564-5b8c6560');
+ --------------------------------------------- + | IS_UUID('6ccd780c-baba-1026-9564-5b8c6560')| + --------------------------------------------- + | 0 | + --------------------------------------------- + MySQL的>SELECT IS_UUID(RAND());
+ ----------------- + | IS_UUID(RAND())| + ----------------- + | 0 | + ----------------- +
MASTER_POS_WAIT(
log_name
,log_pos
[,timeout
][,channel
])
此功能对于控制主/从同步很有用。
它会阻塞,直到从属设备已读取并将所有更新应用到主日志中的指定位置。
返回值是从站必须等待前进到指定位置的日志事件数。
NULL
如果未启动从属SQL线程,未初始化从属主信息,参数不正确或发生错误,则
函数返回
。
-1
如果超出超时
,则返回
。
如果从属SQL线程在
MASTER_POS_WAIT()
等待时
停止,
则该函数返回
NULL
。
如果从站超过指定位置,则该函数立即返回。
上一个多线程从机,功能等待,直到由所述设置的限制期满
slave_checkpoint_group
或
slave_checkpoint_period
系统变量,当检查点操作被称为更新从站的状态。
因此,根据系统变量的设置,函数可能会在达到指定位置后返回一段时间。
如果
timeout
指定
了
值,则
MASTER_POS_WAIT()
在
timeout
秒数过后
停止等待
。
timeout
必须大于0;
零或负
timeout
意味着没有超时。
可选
channel
值使您可以命名该函数适用的复制通道。
有关
更多信息
,
请参见
第17.2.3节“复制通道”
。
此函数对于基于语句的复制不安全。
如果在
binlog_format
设置
为时使用此功能,则会记录警告
STATEMENT
。
返回给定值。
用于生成结果集列时,
NAME_CONST()
会使列具有给定名称。
参数应该是常量。
MySQL的> SELECT NAME_CONST('myname', 14);
+ -------- +
| myname |
+ -------- +
| 14 |
+ -------- +
此功能仅供内部使用。 服务器在从包含对本地程序变量的引用的存储程序中编写语句时使用它,如 第24.7节“存储程序二进制日志记录”中所述 。 您可能会在 mysqlbinlog 的输出中看到此函数 。
对于您的应用程序,您可以使用简单的别名获得与刚刚显示的示例完全相同的结果,如下所示:
MySQL的> SELECT 14 AS myname;
+ -------- +
| myname |
+ -------- +
| 14 |
+ -------- +
1排(0.00秒)
有关列别名的更多信息 , 请参见 第13.2.10节“SELECT语法” 。
休眠(暂停)
duration
参数
给出的秒数
,然后返回0.持续时间可能有一个小数部分。
如果参数为
NULL
或为负,则
SLEEP()
在严格SQL模式下生成警告或错误。
当睡眠正常返回(没有中断)时,它返回0:
MySQL的> SELECT SLEEP(1000);
+ ------------- +
| 睡眠(1000)|
+ ------------- +
| 0 |
+ ------------- +
何时
SLEEP()
是被中断的查询调用的唯一内容,它返回1并且查询本身不返回错误。
无论查询是被终止还是超时,都是如此:
使用
KILL
QUERY
另一个会话
中断此语句
:
MySQL的> SELECT SLEEP(1000);
+ ------------- +
| 睡眠(1000)|
+ ------------- +
| 1 |
+ ------------- +
超时会中断此声明:
MySQL的> SELECT /*+ MAX_EXECUTION_TIME(1) */ SLEEP(1000);
+ ------------- +
| 睡眠(1000)|
+ ------------- +
| 1 |
+ ------------- +
如果
SLEEP()
只是查询中断的一部分,查询将返回错误:
使用
KILL
QUERY
另一个会话
中断此语句
:
MySQL的> SELECT 1 FROM t1 WHERE SLEEP(1000);
错误1317(70100):查询执行被中断
超时会中断此声明:
MySQL的> SELECT /*+ MAX_EXECUTION_TIME(1000) */ 1 FROM t1 WHERE SLEEP(1000);
ERROR 3024(HY000):查询执行被中断,最大语句
超出执行时间
此函数对于基于语句的复制不安全。
如果在
binlog_format
设置
为时使用此功能,则会记录警告
STATEMENT
。
返回根据RFC 4122 “ A Universally Unique IDentifier(UUID)URN命名空间 ” 生成 的通用唯一标识符(UUID) ( http://www.ietf.org/rfc/rfc4122.txt )。
UUID被设计为在空间和时间上全球唯一的数字。
UUID()
预计
两次调用将
生成两个不同的值,即使这些调用是在两个彼此未连接的独立设备上执行的。
虽然
UUID()
价值观是独一无二的,但它们不一定是不可评论的或不可预测的。
如果需要不可预测性,则应以其他方式生成UUID值。
UUID()
返回符合RFC 4122中描述的UUID版本1的值。该值是128位数字,表示为
utf8
格式为五个十六进制数字
的
字符串
aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee
:
前三个数字是从时间戳的低,中,高部分生成的。 高部分还包括UUID版本号。
如果时间戳值失去单调性(例如,由于夏令时),则第四个数字保留时间唯一性。
第五个数字是提供空间唯一性的IEEE 802节点号。 如果后者不可用,则替换随机数(例如,因为主机设备没有以太网卡,或者不知道如何在主机操作系统上找到接口的硬件地址)。 在这种情况下,无法保证空间唯一性。 然而,碰撞应该具有 非常 低的概率。
仅在FreeBSD,Linux和Windows上考虑接口的MAC地址。 在其他操作系统上,MySQL使用随机生成的48位数字。
MySQL的> SELECT UUID();
- >'6ccd780c-baba-1026-9564-5b8c656024db'
要在字符串和二进制UUID值之间进行转换,请使用
UUID_TO_BIN()
和
BIN_TO_UUID()
函数。
要检查字符串是否为有效的UUID值,请使用该
IS_UUID()
函数。
此函数对于基于语句的复制不安全。
如果在
binlog_format
设置
为时使用此功能,则会记录警告
STATEMENT
。
将
“
短
”
通用标识符作为64位无符号整数返回。
返回的值
UUID_SHORT()
与
UUID()
函数
返回的字符串格式128位标识符
不同,并且具有不同的唯一性属性。
UUID_SHORT()
如果满足以下条件
,
则保证
值
是唯一的:
在
server_id
当前服务器的值介于0和255之间,您的设置主从服务器中是唯一的
您不会在 mysqld restarts 之间设置服务器主机的系统时间
UUID_SHORT()
在
mysqld
重启
之间,
你
平均每秒
调用的
次数少于1600万次
该
UUID_SHORT()
返回值的构造是这样的:
(server_id&255)<< 56 +(server_startup_time_in_seconds << 24) + incremented_variable ++;
MySQL的> SELECT UUID_SHORT();
- > 92395783831158784
UUID_SHORT()
不适用于基于语句的复制。
UUID_TO_BIN(
,
string_uuid
)UUID_TO_BIN(
string_uuid
,
swap_flag
)
将字符串UUID转换为二进制UUID并返回结果。
(
IS_UUID()
函数描述列出了允许的字符串UUID格式。)返回二进制UUID是一个
VARBINARY(16)
值。
如果是UUID参数
NULL
,则返回值为
NULL
。
如果任何参数无效,则会发生错误。
UUID_TO_BIN()
需要一个或两个参数:
单参数形式采用字符串UUID值。 二进制结果与字符串参数的顺序相同。
双参数形式采用字符串UUID值和标志值:
如果
swap_flag
为0,则双参数形式等效于单参数形式。
二进制结果与字符串参数的顺序相同。
如果
swap_flag
为1,则返回值的格式不同:交换时间低和时间高的部分(分别为第一组和第三组十六进制数字)。
这会将更快速变化的部分向右移动,并且如果结果存储在索引列中,则可以提高索引效率。
时间 - 部分交换假定使用UUID版本1值,例如由
UUID()
函数
生成的
值。
对于不遵循版本1格式的其他方法生成的UUID值,时间 - 部分交换不会带来任何好处。
有关版本1格式的详细信息,请参阅
UUID()
功能说明。
假设您具有以下字符串UUID值:
MySQL的> SET @uuid = '6ccd780c-baba-1026-9564-5b8c656024db';
要使用或不使用时间 - 部分交换将字符串UUID转换为二进制,请使用
UUID_TO_BIN()
:
MySQL的>SELECT HEX(UUID_TO_BIN(@uuid));
+ ---------------------------------- + | HEX(UUID_TO_BIN(@uuid))| + ---------------------------------- + | 6CCD780CBABA102695645B8C656024DB | + ---------------------------------- + MySQL的>SELECT HEX(UUID_TO_BIN(@uuid, 0));
+ ---------------------------------- + | HEX(UUID_TO_BIN(@ uuid,0))| + ---------------------------------- + | 6CCD780CBABA102695645B8C656024DB | + ---------------------------------- + MySQL的>SELECT HEX(UUID_TO_BIN(@uuid, 1));
+ ---------------------------------- + | HEX(UUID_TO_BIN(@ uuid,1))| + ---------------------------------- + | 1026BABA6CCD780C95645B8C656024DB | + ---------------------------------- +
要将返回的二进制UUID转换为
UUID_TO_BIN()
字符串UUID,请使用
BIN_TO_UUID()
。
如果通过
UUID_TO_BIN()
使用第二个参数1来交换时间部分来
生成二进制UUID
,则还应该传递第二个参数1,
BIN_TO_UUID()
以便在将二进制UUID转换回字符串UUID时取消
交换时间部分
:
MySQL的>SELECT BIN_TO_UUID(UUID_TO_BIN(@uuid));
+ -------------------------------------- + | BIN_TO_UUID(UUID_TO_BIN(@ uuid))| + -------------------------------------- + | 6ccd780c-baba-1026-9564-5b8c656024db | + -------------------------------------- + MySQL的>SELECT BIN_TO_UUID(UUID_TO_BIN(@uuid,0),0);
+ -------------------------------------- + | BIN_TO_UUID(UUID_TO_BIN(@ uuid,0),0)| + -------------------------------------- + | 6ccd780c-baba-1026-9564-5b8c656024db | + -------------------------------------- + MySQL的>SELECT BIN_TO_UUID(UUID_TO_BIN(@uuid,1),1);
+ -------------------------------------- + | BIN_TO_UUID(UUID_TO_BIN(@ uuid,1),1)| + -------------------------------------- + | 6ccd780c-baba-1026-9564-5b8c656024db | + -------------------------------------- +
如果两个方向的转换使用时间 - 部分交换不相同,则原始UUID将无法正确恢复:
MySQL的>SELECT BIN_TO_UUID(UUID_TO_BIN(@uuid,0),1);
+ -------------------------------------- + | BIN_TO_UUID(UUID_TO_BIN(@ uuid,0),1)| + -------------------------------------- + | baba1026-780c-6ccd-9564-5b8c656024db | + -------------------------------------- + MySQL的>SELECT BIN_TO_UUID(UUID_TO_BIN(@uuid,1),0);
+ -------------------------------------- + | BIN_TO_UUID(UUID_TO_BIN(@ uuid,1),0)| + -------------------------------------- + | 1026baba-6ccd-780c-9564-5b8c656024db | + -------------------------------------- +
在
INSERT
... ON DUPLICATE KEY UPDATE
语句中,您可以使用
子句中
的
函数
来引用
语句部分中的
列值
。
换句话说,
在
子句中引用了
将插入
的值
,没有发生重复键冲突。
此功能在多行插入中特别有用。
该
函数仅在
语句
的
子句中
有意义
,
否则
返回
。
请参见
第13.2.6.2节“INSERT ... ON DUPLICATE KEY UPDATE语法”
。
VALUES(
col_name
)UPDATE
INSERT
VALUES(
col_name
)UPDATE
col_name
VALUES()
ON DUPLICATE KEY UPDATE
INSERT
NULL
mysql>INSERT INTO table (a,b,c) VALUES (1,2,3),(4,5,6)
- >ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b);
MySQL提供对精确数学的支持:数值处理可以产生极其准确的结果,并且可以高度控制无效值。 精确数学基于以下两个特征:
控制服务器接受或拒绝无效数据的严格程度的SQL模式。
用于定点算术的MySQL库。
这些功能对数值运算有几个含义,并提供与标准SQL的高度兼容性:
精确计算
:对于精确值数字,计算不会引入浮点错误。
相反,使用精确的精度。
例如,MySQL将一个数字视为
.0001
精确值而不是近似值,并将其相加10,000次会产生精确的结果
1
,而不是仅仅
“
接近
”
1的值。
明确定义的舍入行为
:对于精确值数字,结果
ROUND()
取决于其参数,而不取决于环境因素,例如底层C库的工作方式。
平台独立性 :对于不同平台(如Windows和Unix),精确数值的操作是相同的。
控制无效值的处理
:可以检测到溢出和除零,可以将其视为错误。
例如,您可以将对于列而言太大的值视为错误,而不是将值截断为位于列的数据类型的范围内。
类似地,您可以将除以零视为错误而不是作为产生结果的操作
NULL
。
选择采用哪种方法取决于服务器SQL模式的设置。
以下讨论涵盖精确数学如何工作的几个方面,包括可能与旧应用程序不兼容。 最后,给出了一些示例,演示了MySQL如何精确处理数值运算。 有关控制SQL模式的信息,请参见 第5.1.11节“服务器SQL模式” 。
精确值运算的精度数学范围包括精确值数据类型(整数和
DECIMAL
类型)和精确值数字文字。
近似值数据类型和数字文字作为浮点数处理。
精确值数字文字具有整数部分或小数部分,或两者都有。
他们可能会签名。
例如:
1
,
.2
,
3.4
,
-5
,
-6.78
,
+9.10
。
近似值数字文字用科学记数法表示,带有尾数和指数。
可以签署任一部分或两部分。
例如:
1.2E3
,
1.2E-3
,
-1.2E3
,
-1.2E-3
。
两个看起来相似的数字可能会有不同的对待。
例如,
2.34
是精确值(定点)数,而是
2.34E0
近似值(浮点数)。
The DECIMAL
data type is a
fixed-point type and calculations are exact. In MySQL, the
DECIMAL
type has several synonyms:
NUMERIC
,
DEC
,
FIXED
. The integer types also are
exact-value types.
The FLOAT
and
DOUBLE
data types are
floating-point types and calculations are approximate. In MySQL,
types that are synonymous with
FLOAT
or
DOUBLE
are
DOUBLE PRECISION
and
REAL
.
This section discusses the characteristics of the
DECIMAL
data type (and its
synonyms), with particular regard to the following topics:
Maximum number of digits
Storage format
Storage requirements
The nonstandard MySQL extension to the upper range of
DECIMAL
columns
The declaration syntax for a
DECIMAL
column is
DECIMAL(
.
The ranges of values for the arguments are as follows:
M
,D
)
M
is the maximum number of digits
(the precision). It has a range of 1 to 65.
D
is the number of digits to the
right of the decimal point (the scale). It has a range of 0 to
30 and must be no larger than M
.
If D
is omitted, the default is 0. If
M
is omitted, the default is 10.
The maximum value of 65 for M
means
that calculations on DECIMAL
values
are accurate up to 65 digits. This limit of 65 digits of precision
also applies to exact-value numeric literals, so the maximum range
of such literals differs from before.
Values for DECIMAL
columns are
stored using a binary format that packs nine decimal digits into 4
bytes. The storage requirements for the integer and fractional
parts of each value are determined separately. Each multiple of
nine digits requires 4 bytes, and any remaining digits left over
require some fraction of 4 bytes. The storage required for
remaining digits is given by the following table.
Leftover Digits | Number of Bytes |
---|---|
0 | 0 |
1–2 | 1 |
3–4 | 2 |
5–6 | 3 |
7–9 | 4 |
For example, a DECIMAL(18,9)
column has nine
digits on either side of the decimal point, so the integer part
and the fractional part each require 4 bytes. A
DECIMAL(20,6)
column has fourteen integer
digits and six fractional digits. The integer digits require four
bytes for nine of the digits and 3 bytes for the remaining five
digits. The six fractional digits require 3 bytes.
DECIMAL
columns do not store a
leading +
character or -
character or leading 0
digits. If you insert
+0003.1
into a DECIMAL(5,1)
column, it is stored as 3.1
. For negative
numbers, a literal -
character is not stored.
DECIMAL
columns do not permit
values larger than the range implied by the column definition. For
example, a DECIMAL(3,0)
column supports a range
of -999
to 999
. A
DECIMAL(
column permits up to M
,D
)M
-
D
digits to the left of the decimal
point.
The SQL standard requires that the precision of
NUMERIC(
be exactly M
,D
)M
digits. For
DECIMAL(
,
the standard requires a precision of at least
M
,D
)M
digits but permits more. In MySQL,
DECIMAL(
and
M
,D
)NUMERIC(
are the same, and both have a precision of exactly
M
,D
)M
digits.
For a full explanation of the internal format of
DECIMAL
values, see the file
strings/decimal.c
in a MySQL source
distribution. The format is explained (with an example) in the
decimal2bin()
function.
With precision math, exact-value numbers are used as given
whenever possible. For example, numbers in comparisons are used
exactly as given without a change in value. In strict SQL mode,
for INSERT
into a column with an
exact data type (DECIMAL
or
integer), a number is inserted with its exact value if it is
within the column range. When retrieved, the value should be the
same as what was inserted. (If strict SQL mode is not enabled,
truncation for INSERT
is
permissible.)
Handling of a numeric expression depends on what kind of values the expression contains:
If any approximate values are present, the expression is approximate and is evaluated using floating-point arithmetic.
If no approximate values are present, the expression contains
only exact values. If any exact value contains a fractional
part (a value following the decimal point), the expression is
evaluated using DECIMAL
exact
arithmetic and has a precision of 65 digits. The term
“exact” is subject to the limits of what can be
represented in binary. For example, 1.0/3.0
can be approximated in decimal notation as
.333...
, but not written as an exact
number, so (1.0/3.0)*3.0
does not evaluate
to exactly 1.0
.
Otherwise, the expression contains only integer values. The
expression is exact and is evaluated using integer arithmetic
and has a precision the same as
BIGINT
(64 bits).
If a numeric expression contains any strings, they are converted to double-precision floating-point values and the expression is approximate.
Inserts into numeric columns are affected by the SQL mode, which
is controlled by the sql_mode
system variable. (See Section 5.1.11,
“Server SQL Modes”.) The following
discussion mentions strict mode (selected by the
STRICT_ALL_TABLES
or
STRICT_TRANS_TABLES
mode values)
and ERROR_FOR_DIVISION_BY_ZERO
.
To turn on all restrictions, you can simply use
TRADITIONAL
mode, which includes
both strict mode values and
ERROR_FOR_DIVISION_BY_ZERO
:
SET sql_mode='TRADITIONAL';
If a number is inserted into an exact type column
(DECIMAL
or integer), it is
inserted with its exact value if it is within the column range and
precision.
If the value has too many digits in the fractional part, rounding occurs and a note is generated. Rounding is done as described in Section 12.25.4, “Rounding Behavior”. Truncation due to rounding of the fractional part is not an error, even in strict mode.
If the value has too many digits in the integer part, it is too large (out of range) and is handled as follows:
If strict mode is not enabled, the value is truncated to the nearest legal value and a warning is generated.
If strict mode is enabled, an overflow error occurs.
Underflow is not detected, so underflow handling is undefined.
For inserts of strings into numeric columns, conversion from string to number is handled as follows if the string has nonnumeric contents:
A string that does not begin with a number cannot be used as a number and produces an error in strict mode, or a warning otherwise. This includes the empty string.
A string that begins with a number can be converted, but the trailing nonnumeric portion is truncated. If the truncated portion contains anything other than spaces, this produces an error in strict mode, or a warning otherwise.
By default, division by zero produces a result of
NULL
and no warning. By setting the SQL mode
appropriately, division by zero can be restricted.
With the
ERROR_FOR_DIVISION_BY_ZERO
SQL
mode enabled, MySQL handles division by zero differently:
If strict mode is not enabled, a warning occurs.
If strict mode is enabled, inserts and updates involving division by zero are prohibited, and an error occurs.
In other words, inserts and updates involving expressions that
perform division by zero can be treated as errors, but this
requires
ERROR_FOR_DIVISION_BY_ZERO
in
addition to strict mode.
Suppose that we have this statement:
INSERT INTO t SET i = 1/0;
This is what happens for combinations of strict and
ERROR_FOR_DIVISION_BY_ZERO
modes.
sql_mode
Value |
Result |
---|---|
'' (Default) |
No warning, no error; i is set to
NULL . |
strict | No warning, no error; i is set to
NULL . |
ERROR_FOR_DIVISION_BY_ZERO |
Warning, no error; i is set to
NULL . |
strict,ERROR_FOR_DIVISION_BY_ZERO |
Error condition; no row is inserted. |
This section discusses precision math rounding for the
ROUND()
function and for
inserts
into columns with exact-value types
(DECIMAL
and integer).
The ROUND()
function rounds
differently depending on whether its argument is exact or
approximate:
For exact-value numbers,
ROUND()
uses the “round
half up” rule: A value with a fractional part of .5 or
greater is rounded up to the next integer if positive or down
to the next integer if negative. (In other words, it is
rounded away from zero.) A value with a fractional part less
than .5 is rounded down to the next integer if positive or up
to the next integer if negative. (In other words, it is
rounded toward zero.)
For approximate-value numbers, the result depends on the C
library. On many systems, this means that
ROUND()
uses the “round
to nearest even” rule: A value with a fractional part
exactly half way between two integers is rounded to the
nearest even integer.
The following example shows how rounding differs for exact and approximate values:
mysql> SELECT ROUND(2.5), ROUND(25E-1);
+------------+--------------+
| ROUND(2.5) | ROUND(25E-1) |
+------------+--------------+
| 3 | 2 |
+------------+--------------+
For inserts into a DECIMAL
or
integer column, the target is an exact data type, so rounding uses
“round half away from zero,” regardless of whether
the value to be inserted is exact or approximate:
mysql>CREATE TABLE t (d DECIMAL(10,0));
Query OK, 0 rows affected (0.00 sec) mysql>INSERT INTO t VALUES(2.5),(2.5E0);
Query OK, 2 rows affected, 2 warnings (0.00 sec) Records: 2 Duplicates: 0 Warnings: 2 mysql>SHOW WARNINGS;
+-------+------+----------------------------------------+ | Level | Code | Message | +-------+------+----------------------------------------+ | Note | 1265 | Data truncated for column 'd' at row 1 | | Note | 1265 | Data truncated for column 'd' at row 2 | +-------+------+----------------------------------------+ 2 rows in set (0.00 sec) mysql>SELECT d FROM t;
+------+ | d | +------+ | 3 | | 3 | +------+ 2 rows in set (0.00 sec)
The SHOW
WARNINGS
statement
displays the notes that are generated by truncation due to
rounding of the fractional part. Such truncation is not an error,
even in strict SQL mode (see
Section 12.25.3,
“Expression Handling”).
This section provides some examples that show precision math query results in MySQL. These examples demonstrate the principles described in Section 12.25.3, “Expression Handling”, and Section 12.25.4, “Rounding Behavior”.
Example 1. Numbers are used with their exact value as given when possible:
mysql> SELECT (.1 + .2) = .3;
+----------------+
| (.1 + .2) = .3 |
+----------------+
| 1 |
+----------------+
For floating-point values, results are inexact:
mysql> SELECT (.1E0 + .2E0) = .3E0;
+----------------------+
| (.1E0 + .2E0) = .3E0 |
+----------------------+
| 0 |
+----------------------+
Another way to see the difference in exact and approximate value
handling is to add a small number to a sum many times. Consider
the following stored procedure, which adds
.0001
to a variable 1,000 times.
CREATE PROCEDURE p () BEGIN DECLARE i INT DEFAULT 0; DECLARE d DECIMAL(10,4) DEFAULT 0; DECLARE f FLOAT DEFAULT 0; WHILE i < 10000 DO SET d = d + .0001; SET f = f + .0001E0; SET i = i + 1; END WHILE; SELECT d, f; END;
The sum for both d
and f
logically should be 1, but that is true only for the decimal
calculation. The floating-point calculation introduces small
errors:
+--------+------------------+ | d | f | +--------+------------------+ | 1.0000 | 0.99999999999991 | +--------+------------------+
Example 2. Multiplication is
performed with the scale required by standard SQL. That is, for
two numbers X1
and
X2
that have scale
S1
and S2
,
the scale of the result is
:
S1
+ S2
mysql> SELECT .01 * .01;
+-----------+
| .01 * .01 |
+-----------+
| 0.0001 |
+-----------+
Example 3. Rounding behavior for exact-value numbers is well-defined:
Rounding behavior (for example, with the
ROUND()
function) is
independent of
the implementation of the underlying C library, which means that
results are consistent from platform to platform.
Rounding for exact-value columns
(DECIMAL
and integer) and
exact-valued numbers uses the “round half away from
zero” rule. A value with a fractional part of .5 or
greater is rounded away from zero to the nearest integer, as
shown here:
mysql> SELECT ROUND(2.5), ROUND(-2.5);
+------------+-------------+
| ROUND(2.5) | ROUND(-2.5) |
+------------+-------------+
| 3 | -3 |
+------------+-------------+
Rounding for floating-point values uses the C library, which on many systems uses the “round to nearest even” rule. A value with a fractional part exactly half way between two integers is rounded to the nearest even integer:
mysql> SELECT ROUND(2.5E0), ROUND(-2.5E0);
+--------------+---------------+
| ROUND(2.5E0) | ROUND(-2.5E0) |
+--------------+---------------+
| 2 | -2 |
+--------------+---------------+
Example 4. In strict mode, inserting a value that is out of range for a column causes an error, rather than truncation to a legal value.
When MySQL is not running in strict mode, truncation to a legal value occurs:
mysql>SET sql_mode='';
Query OK, 0 rows affected (0.00 sec) mysql>CREATE TABLE t (i TINYINT);
Query OK, 0 rows affected (0.01 sec) mysql>INSERT INTO t SET i = 128;
Query OK, 1 row affected, 1 warning (0.00 sec) mysql>SELECT i FROM t;
+------+ | i | +------+ | 127 | +------+ 1 row in set (0.00 sec)
However, an error occurs if strict mode is in effect:
mysql>SET sql_mode='STRICT_ALL_TABLES';
Query OK, 0 rows affected (0.00 sec) mysql>CREATE TABLE t (i TINYINT);
Query OK, 0 rows affected (0.00 sec) mysql>INSERT INTO t SET i = 128;
ERROR 1264(22003):超出了第1行第'i列'的范围值 MySQL的>SELECT i FROM t;
空集(0.00秒)
示例5
:在严格模式下并使用
ERROR_FOR_DIVISION_BY_ZERO
set,除以零会导致错误,而不是结果
NULL
。
在非严格模式下,除以零的结果是
NULL
:
MySQL的>SET sql_mode='';
查询OK,0行受影响(0.01秒) MySQL的>CREATE TABLE t (i TINYINT);
查询正常,0行受影响(0.00秒) MySQL的>INSERT INTO t SET i = 1 / 0;
查询正常,1行受影响(0.00秒) MySQL的>SELECT i FROM t;
+ ------ + | 我| + ------ + | NULL | + ------ + 1排(0.03秒)
但是,如果正确的SQL模式生效,除以零是错误的:
MySQL的>SET sql_mode='STRICT_ALL_TABLES,ERROR_FOR_DIVISION_BY_ZERO';
查询正常,0行受影响(0.00秒) MySQL的>CREATE TABLE t (i TINYINT);
查询正常,0行受影响(0.00秒) MySQL的>INSERT INTO t SET i = 1 / 0;
ERROR 1365(22012):除以0 MySQL的>SELECT i FROM t;
空集(0.01秒)
例6 。 精确值文字被评估为精确值。
使用浮点计算近似值文字,但精确值文字的处理方式如下
DECIMAL
:
MySQL的>CREATE TABLE t SELECT 2.5 AS a, 25E-1 AS b;
查询OK,1行受影响(0.01秒) 记录:1个重复:0警告:0 MySQL的>DESCRIBE t;
+ ------- + ------------ + ------ + ----- + ---- ----- + ------- + | 领域| 输入| 空| 钥匙| 默认| 额外的| + ------- + ------------ + ------ + ----- + ---- ----- + ------- + | a | 十进制(2,1)无符号| 没有| | 0.0 | | | b | 双| 没有| | 0 | | + ------- + ------------ + ------ + ----- + ---- ----- + ------- + 2行(0.01秒)
例7 。 如果聚合函数的参数是精确的数字类型,则结果也是精确的数字类型,其比例至少为参数的比例。
请考虑以下陈述:
mysql>CREATE TABLE t (i INT, d DECIMAL, f FLOAT);
mysql>INSERT INTO t VALUES(1,1,1);
mysql>CREATE TABLE y SELECT AVG(i), AVG(d), AVG(f) FROM t;
结果是浮点参数只有一个double。 对于精确类型参数,结果也是精确类型:
MySQL的> DESCRIBE y;
+ -------- + -------- + ------ + ------ + --------- + - ------ +
| 领域| 输入| 空| 钥匙| 默认| 额外的|
+ -------- + -------- + ------ + ------ + --------- + - ------ +
| AVG(i)| 十进制(14,4)| 是的| | NULL | |
| AVG(d)| 十进制(14,4)| 是的| | NULL | |
| AVG(f)| 双| 是的| | NULL | |
+ -------- + -------- + ------ + ------ + --------- + - ------ +
结果是浮点参数只有一个double。 对于精确类型参数,结果也是精确类型。