MySQL8.0 Chapter 12 Functions and Operatorsphp
官網html
Table of Contentsnode
Expressions can be used at several points in SQL statements, such as in the ORDER BY
or HAVING
clauses of SELECT
statements, in the WHERE
clause of a SELECT
, DELETE
, or UPDATE
statement, or in SET
statements. Expressions can be written using literal values, column values, NULL
, built-in functions, stored functions, user-defined functions, and operators. This chapter describes the functions and operators that are permitted for writing expressions in MySQL. Instructions for writing stored functions and user-defined functions are given in Section 24.2, 「Using Stored Routines」, and Section 29.4, 「Adding New Functions to MySQL」. See Section 9.2.4, 「Function Name Parsing and Resolution」, for the rules describing how the server interprets references to different kinds of functions.
An expression that contains NULL
always produces a NULL
value unless otherwise indicated in the documentation for a particular function or operator.
By default, there must be no whitespace between a function name and the parenthesis following it. This helps the MySQL parser distinguish between function calls and references to tables or columns that happen to have the same name as a function. However, spaces around function arguments are permitted.
You can tell the MySQL server to accept spaces after function names by starting it with the --sql-mode=IGNORE_SPACE
option. (See Section 5.1.11, 「Server SQL Modes」.) Individual client programs can request this behavior by using the CLIENT_IGNORE_SPACE
option for mysql_real_connect()
. In either case, all function names become reserved words.
For the sake of brevity, most examples in this chapter display the output from the mysql program in abbreviated form. Rather than showing examples in this format:
mysql> +-----------+ | mod(29,9) | +-----------+ | 2 | +-----------+ 1 rows in set (0.00 sec) SELECT MOD(29,9);
This format is used instead:
mysql> -> 2 SELECT MOD(29,9);
Table 12.1 Functions and Operators
Name | Description |
---|---|
ABS() |
Return the absolute value |
ACOS() |
Return the arc cosine |
ADDDATE() |
Add time values (intervals) to a date value |
ADDTIME() |
Add time |
AES_DECRYPT() |
Decrypt using AES |
AES_ENCRYPT() |
Encrypt using AES |
AND , && |
Logical AND |
ANY_VALUE() |
Suppress ONLY_FULL_GROUP_BY value rejection |
ASCII() |
Return numeric value of left-most character |
ASIN() |
Return the arc sine |
= |
Assign a value (as part of a SET statement, or as part of the SET clause in an UPDATE statement) |
:= |
Assign a value |
ASYMMETRIC_DECRYPT() |
Decrypt ciphertext using private or public key |
ASYMMETRIC_DERIVE() |
Derive symmetric key from asymmetric keys |
ASYMMETRIC_ENCRYPT() |
Encrypt cleartext using private or public key |
ASYMMETRIC_SIGN() |
Generate signature from digest |
ASYMMETRIC_VERIFY() |
Verify that signature matches digest |
ATAN() |
Return the arc tangent |
ATAN2() , ATAN() |
Return the arc tangent of the two arguments |
AVG() |
Return the average value of the argument |
BENCHMARK() |
Repeatedly execute an expression |
BETWEEN ... AND ... |
Check whether a value is within a range of values |
BIN() |
Return a string containing binary representation of a number |
BIN_TO_UUID() |
Convert binary UUID to string |
BINARY |
Cast a string to a binary string |
BIT_AND() |
Return bitwise AND |
BIT_COUNT() |
Return the number of bits that are set |
BIT_LENGTH() |
Return length of argument in bits |
BIT_OR() |
Return bitwise OR |
BIT_XOR() |
Return bitwise XOR |
& |
Bitwise AND |
~ |
Bitwise inversion |
| |
Bitwise OR |
^ |
Bitwise XOR |
CAN_ACCESS_COLUMN() |
Internal use only |
CAN_ACCESS_DATABASE() |
Internal use only |
CAN_ACCESS_TABLE() |
Internal use only |
CAN_ACCESS_VIEW() |
Internal use only |
CASE |
Case operator |
CAST() |
Cast a value as a certain type |
CEIL() |
Return the smallest integer value not less than the argument |
CEILING() |
Return the smallest integer value not less than the argument |
CHAR() |
Return the character for each integer passed |
CHAR_LENGTH() |
Return number of characters in argument |
CHARACTER_LENGTH() |
Synonym for CHAR_LENGTH() |
CHARSET() |
Return the character set of the argument |
COALESCE() |
Return the first non-NULL argument |
COERCIBILITY() |
Return the collation coercibility value of the string argument |
COLLATION() |
Return the collation of the string argument |
COMPRESS() |
Return result as a binary string |
CONCAT() |
Return concatenated string |
CONCAT_WS() |
Return concatenate with separator |
CONNECTION_ID() |
Return the connection ID (thread ID) for the connection |
CONV() |
Convert numbers between different number bases |
CONVERT() |
Cast a value as a certain type |
CONVERT_TZ() |
Convert from one time zone to another |
COS() |
Return the cosine |
COT() |
Return the cotangent |
COUNT() |
Return a count of the number of rows returned |
COUNT(DISTINCT) |
Return the count of a number of different values |
CRC32() |
Compute a cyclic redundancy check value |
CREATE_ASYMMETRIC_PRIV_KEY() |
Create private key |
CREATE_ASYMMETRIC_PUB_KEY() |
Create public key |
CREATE_DH_PARAMETERS() |
Generate shared DH secret |
CREATE_DIGEST() |
Generate digest from string |
CUME_DIST() |
Cumulative distribution value |
CURDATE() |
Return the current date |
CURRENT_DATE() , CURRENT_DATE |
Synonyms for CURDATE() |
CURRENT_ROLE() |
Return the current active roles |
CURRENT_TIME() , CURRENT_TIME |
Synonyms for CURTIME() |
CURRENT_TIMESTAMP() , CURRENT_TIMESTAMP |
Synonyms for NOW() |
CURRENT_USER() , CURRENT_USER |
The authenticated user name and host name |
CURTIME() |
Return the current time |
DATABASE() |
Return the default (current) database name |
DATE() |
Extract the date part of a date or datetime expression |
DATE_ADD() |
Add time values (intervals) to a date value |
DATE_FORMAT() |
Format date as specified |
DATE_SUB() |
Subtract a time value (interval) from a date |
DATEDIFF() |
Subtract two dates |
DAY() |
Synonym for DAYOFMONTH() |
DAYNAME() |
Return the name of the weekday |
DAYOFMONTH() |
Return the day of the month (0-31) |
DAYOFWEEK() |
Return the weekday index of the argument |
DAYOFYEAR() |
Return the day of the year (1-366) |
DECODE() |
Decode a string encrypted using ENCODE() |
DEFAULT() |
Return the default value for a table column |
DEGREES() |
Convert radians to degrees |
DENSE_RANK() |
Rank of current row within its partition, without gaps |
DES_DECRYPT() |
Decrypt a string |
DES_ENCRYPT() |
Encrypt a string |
DIV |
Integer division |
/ |
Division operator |
ELT() |
Return string at index number |
ENCODE() |
Encode a string |
ENCRYPT() |
Encrypt a string |
= |
Equal operator |
<=> |
NULL-safe equal to operator |
EXP() |
Raise to the power of |
EXPORT_SET() |
Return a string such that for every bit set in the value bits, you get an on string and for every unset bit, you get an off string |
EXTRACT() |
Extract part of a date |
ExtractValue() |
Extract a value from an XML string using XPath notation |
FIELD() |
Index (position) of first argument in subsequent arguments |
FIND_IN_SET() |
Index (position) of first argument within second argument |
FIRST_VALUE() |
Value of argument from first row of window frame |
FLOOR() |
Return the largest integer value not greater than the argument |
FORMAT() |
Return a number formatted to specified number of decimal places |
FORMAT_BYTES() |
Convert byte count to value with units |
FORMAT_PICO_TIME() |
Convert time in picoseconds to value with units |
FOUND_ROWS() |
For a SELECT with a LIMIT clause, the number of rows that would be returned were there no LIMIT clause |
FROM_BASE64() |
Decode base64 encoded string and return result |
FROM_DAYS() |
Convert a day number to a date |
FROM_UNIXTIME() |
Format Unix timestamp as a date |
GeomCollection() |
Construct geometry collection from geometries |
GeometryCollection() |
Construct geometry collection from geometries |
GET_DD_COLUMN_PRIVILEGES() |
Internal use only |
GET_DD_CREATE_OPTIONS() |
Internal use only |
GET_DD_INDEX_SUB_PART_LENGTH() |
Internal use only |
GET_FORMAT() |
Return a date format string |
GET_LOCK() |
Get a named lock |
> |
Greater than operator |
>= |
Greater than or equal operator |
GREATEST() |
Return the largest argument |
GROUP_CONCAT() |
Return a concatenated string |
GROUPING() |
Distinguish super-aggregate ROLLUP rows from regular rows |
GTID_SUBSET() |
Return true if all GTIDs in subset are also in set; otherwise false. |
GTID_SUBTRACT() |
Return all GTIDs in set that are not in subset. |
HEX() |
Hexadecimal representation of decimal or string value |
HOUR() |
Extract the hour |
ICU_VERSION() |
ICU library version |
IF() |
If/else construct |
IFNULL() |
Null if/else construct |
IN() |
Check whether a value is within a set of values |
INET_ATON() |
Return the numeric value of an IP address |
INET_NTOA() |
Return the IP address from a numeric value |
INET6_ATON() |
Return the numeric value of an IPv6 address |
INET6_NTOA() |
Return the IPv6 address from a numeric value |
INSERT() |
Insert substring at specified position up to specified number of characters |
INSTR() |
Return the index of the first occurrence of substring |
INTERNAL_AUTO_INCREMENT() |
Internal use only |
INTERNAL_AVG_ROW_LENGTH() |
Internal use only |
INTERNAL_CHECK_TIME() |
Internal use only |
INTERNAL_CHECKSUM() |
Internal use only |
INTERNAL_DATA_FREE() |
Internal use only |
INTERNAL_DATA_LENGTH() |
Internal use only |
INTERNAL_DD_CHAR_LENGTH() |
Internal use only |
INTERNAL_GET_COMMENT_OR_ERROR() |
Internal use only |
INTERNAL_GET_VIEW_WARNING_OR_ERROR() |
Internal use only |
INTERNAL_INDEX_COLUMN_CARDINALITY() |
Internal use only |
INTERNAL_INDEX_LENGTH() |
Internal use only |
INTERNAL_KEYS_DISABLED() |
Internal use only |
INTERNAL_MAX_DATA_LENGTH() |
Internal use only |
INTERNAL_TABLE_ROWS() |
Internal use only |
INTERNAL_UPDATE_TIME() |
Internal use only |
INTERVAL() |
Return the index of the argument that is less than the first argument |
IS |
Test a value against a boolean |
IS_FREE_LOCK() |
Whether the named lock is free |
IS_IPV4() |
Whether argument is an IPv4 address |
IS_IPV4_COMPAT() |
Whether argument is an IPv4-compatible address |
IS_IPV4_MAPPED() |
Whether argument is an IPv4-mapped address |
IS_IPV6() |
Whether argument is an IPv6 address |
IS NOT |
Test a value against a boolean |
IS NOT NULL |
NOT NULL value test |
IS NULL |
NULL value test |
IS_USED_LOCK() |
Whether the named lock is in use; return connection identifier if true |
IS_UUID() |
Whether argument is a valid UUID |
ISNULL() |
Test whether the argument is NULL |
JSON_ARRAY() |
Create JSON array |
JSON_ARRAY_APPEND() |
Append data to JSON document |
JSON_ARRAY_INSERT() |
Insert into JSON array |
JSON_ARRAYAGG() |
Return result set as a single JSON array |
-> |
Return value from JSON column after evaluating path; equivalent to JSON_EXTRACT(). |
JSON_CONTAINS() |
Whether JSON document contains specific object at path |
JSON_CONTAINS_PATH() |
Whether JSON document contains any data at path |
JSON_DEPTH() |
Maximum depth of JSON document |
JSON_EXTRACT() |
Return data from JSON document |
->> |
Return value from JSON column after evaluating path and unquoting the result; equivalent to JSON_UNQUOTE(JSON_EXTRACT()). |
JSON_INSERT() |
Insert data into JSON document |
JSON_KEYS() |
Array of keys from JSON document |
JSON_LENGTH() |
Number of elements in JSON document |
JSON_MERGE() (deprecated 8.0.3) |
Merge JSON documents, preserving duplicate keys. Deprecated synonym for JSON_MERGE_PRESERVE() |
JSON_MERGE_PATCH() |
Merge JSON documents, replacing values of duplicate keys |
JSON_MERGE_PRESERVE() |
Merge JSON documents, preserving duplicate keys |
JSON_OBJECT() |
Create JSON object |
JSON_OBJECTAGG() |
Return result set as a single JSON object |
JSON_PRETTY() |
Print a JSON document in human-readable format |
JSON_QUOTE() |
Quote JSON document |
JSON_REMOVE() |
Remove data from JSON document |
JSON_REPLACE() |
Replace values in JSON document |
JSON_SCHEMA_VALID() |
Validate JSON document against JSON schema |
JSON_SEARCH() |
Path to value within JSON document |
JSON_SET() |
Insert data into JSON document |
JSON_STORAGE_FREE() |
Freed space within binary representation of JSON column value following partial update |
JSON_STORAGE_SIZE() |
Space used for storage of binary representation of a JSON document |
JSON_TABLE() |
Return data from a JSON expression as a relational table |
JSON_TYPE() |
Type of JSON value |
JSON_UNQUOTE() |
Unquote JSON value |
JSON_VALID() |
Whether JSON value is valid |
LAG() |
Value of argument from row lagging current row within partition |
LAST_DAY |
Return the last day of the month for the argument |
LAST_INSERT_ID() |
Value of the AUTOINCREMENT column for the last INSERT |
LAST_VALUE() |
Value of argument from last row of window frame |
LCASE() |
Synonym for LOWER() |
LEAD() |
Value of argument from row leading current row within partition |
LEAST() |
Return the smallest argument |
LEFT() |
Return the leftmost number of characters as specified |
<< |
Left shift |
LENGTH() |
Return the length of a string in bytes |
< |
Less than operator |
<= |
Less than or equal operator |
LIKE |
Simple pattern matching |
LineString() |
Construct LineString from Point values |
LN() |
Return the natural logarithm of the argument |
LOAD_FILE() |
Load the named file |
LOCALTIME() , LOCALTIME |
Synonym for NOW() |
LOCALTIMESTAMP , LOCALTIMESTAMP() |
Synonym for NOW() |
LOCATE() |
Return the position of the first occurrence of substring |
LOG() |
Return the natural logarithm of the first argument |
LOG10() |
Return the base-10 logarithm of the argument |
LOG2() |
Return the base-2 logarithm of the argument |
LOWER() |
Return the argument in lowercase |
LPAD() |
Return the string argument, left-padded with the specified string |
LTRIM() |
Remove leading spaces |
MAKE_SET() |
Return a set of comma-separated strings that have the corresponding bit in bits set |
MAKEDATE() |
Create a date from the year and day of year |
MAKETIME() |
Create time from hour, minute, second |
MASTER_POS_WAIT() |
Block until the slave has read and applied all updates up to the specified position |
MATCH |
Perform full-text search |
MAX() |
Return the maximum value |
MBRContains() |
Whether MBR of one geometry contains MBR of another |
MBRCoveredBy() |
Whether one MBR is covered by another |
MBRCovers() |
Whether one MBR covers another |
MBRDisjoint() |
Whether MBRs of two geometries are disjoint |
MBREquals() |
Whether MBRs of two geometries are equal |
MBRIntersects() |
Whether MBRs of two geometries intersect |
MBROverlaps() |
Whether MBRs of two geometries overlap |
MBRTouches() |
Whether MBRs of two geometries touch |
MBRWithin() |
Whether MBR of one geometry is within MBR of another |
MD5() |
Calculate MD5 checksum |
MICROSECOND() |
Return the microseconds from argument |
MID() |
Return a substring starting from the specified position |
MIN() |
Return the minimum value |
- |
Minus operator |
MINUTE() |
Return the minute from the argument |
MOD() |
Return the remainder |
% , MOD |
Modulo operator |
MONTH() |
Return the month from the date passed |
MONTHNAME() |
Return the name of the month |
MultiLineString() |
Contruct MultiLineString from LineString values |
MultiPoint() |
Construct MultiPoint from Point values |
MultiPolygon() |
Construct MultiPolygon from Polygon values |
NAME_CONST() |
Cause the column to have the given name |
NOT , ! |
Negates value |
NOT BETWEEN ... AND ... |
Check whether a value is not within a range of values |
!= , <> |
Not equal operator |
NOT IN() |
Check whether a value is not within a set of values |
NOT LIKE |
Negation of simple pattern matching |
NOT REGEXP |
Negation of REGEXP |
NOW() |
Return the current date and time |
NTH_VALUE() |
Value of argument from N-th row of window frame |
NTILE() |
Bucket number of current row within its partition. |
NULLIF() |
Return NULL if expr1 = expr2 |
OCT() |
Return a string containing octal representation of a number |
OCTET_LENGTH() |
Synonym for LENGTH() |
OR , || |
Logical OR |
ORD() |
Return character code for leftmost character of the argument |
PASSWORD() |
Calculate and return a password string |
PERCENT_RANK() |
Percentage rank value |
PERIOD_ADD() |
Add a period to a year-month |
PERIOD_DIFF() |
Return the number of months between periods |
PI() |
Return the value of pi |
+ |
Addition operator |
Point() |
Construct Point from coordinates |
Polygon() |
Construct Polygon from LineString arguments |
POSITION() |
Synonym for LOCATE() |
POW() |
Return the argument raised to the specified power |
POWER() |
Return the argument raised to the specified power |
PS_CURRENT_THREAD_ID() |
Performance Schema thread ID for current thread |
PS_THREAD_ID() |
Performance Schema thread ID for given thread |
QUARTER() |
Return the quarter from a date argument |
QUOTE() |
Escape the argument for use in an SQL statement |
RADIANS() |
Return argument converted to radians |
RAND() |
Return a random floating-point value |
RANDOM_BYTES() |
Return a random byte vector |
RANK() |
Rank of current row within its partition, with gaps |
REGEXP |
Whether string matches regular expression |
REGEXP_INSTR() |
Starting index of substring matching regular expression |
REGEXP_LIKE() |
Whether string matches regular expression |
REGEXP_REPLACE() |
Replace substrings matching regular expression |
REGEXP_SUBSTR() |
Return substring matching regular expression |
RELEASE_ALL_LOCKS() |
Release all current named locks |
RELEASE_LOCK() |
Release the named lock |
REPEAT() |
Repeat a string the specified number of times |
REPLACE() |
Replace occurrences of a specified string |
REVERSE() |
Reverse the characters in a string |
RIGHT() |
Return the specified rightmost number of characters |
>> |
Right shift |
RLIKE |
Whether string matches regular expression |
ROLES_GRAPHML() |
Return a GraphML document representing memory role subgraphs |
ROUND() |
Round the argument |
ROW_COUNT() |
The number of rows updated |
ROW_NUMBER() |
Number of current row within its partition |
RPAD() |
Append string the specified number of times |
RTRIM() |
Remove trailing spaces |
SCHEMA() |
Synonym for DATABASE() |
SEC_TO_TIME() |
Converts seconds to 'hh:mm:ss' format |
SECOND() |
Return the second (0-59) |
SESSION_USER() |
Synonym for USER() |
SHA1() , SHA() |
Calculate an SHA-1 160-bit checksum |
SHA2() |
Calculate an SHA-2 checksum |
SIGN() |
Return the sign of the argument |
SIN() |
Return the sine of the argument |
SLEEP() |
Sleep for a number of seconds |
SOUNDEX() |
Return a soundex string |
SOUNDS LIKE |
Compare sounds |
SPACE() |
Return a string of the specified number of spaces |
SQRT() |
Return the square root of the argument |
ST_Area() |
Return Polygon or MultiPolygon area |
ST_AsBinary() , ST_AsWKB() |
Convert from internal geometry format to WKB |
ST_AsGeoJSON() |
Generate GeoJSON object from geometry |
ST_AsText() , ST_AsWKT() |
Convert from internal geometry format to WKT |
ST_Buffer() |
Return geometry of points within given distance from geometry |
ST_Buffer_Strategy() |
Produce strategy option for ST_Buffer() |
ST_Centroid() |
Return centroid as a point |
ST_Contains() |
Whether one geometry contains another |
ST_ConvexHull() |
Return convex hull of geometry |
ST_Crosses() |
Whether one geometry crosses another |
ST_Difference() |
Return point set difference of two geometries |
ST_Dimension() |
Dimension of geometry |
ST_Disjoint() |
Whether one geometry is disjoint from another |
ST_Distance() |
The distance of one geometry from another |
ST_Distance_Sphere() |
Minimum distance on earth between two geometries |
ST_EndPoint() |
End Point of LineString |
ST_Envelope() |
Return MBR of geometry |
ST_Equals() |
Whether one geometry is equal to another |
ST_ExteriorRing() |
Return exterior ring of Polygon |
ST_GeoHash() |
Produce a geohash value |
ST_GeomCollFromText() , ST_GeometryCollectionFromText() , ST_GeomCollFromTxt() |
Return geometry collection from WKT |
ST_GeomCollFromWKB() , ST_GeometryCollectionFromWKB() |
Return geometry collection from WKB |
ST_GeometryN() |
Return N-th geometry from geometry collection |
ST_GeometryType() |
Return name of geometry type |
ST_GeomFromGeoJSON() |
Generate geometry from GeoJSON object |
ST_GeomFromText() , ST_GeometryFromText() |
Return geometry from WKT |
ST_GeomFromWKB() , ST_GeometryFromWKB() |
Return geometry from WKB |
ST_InteriorRingN() |
Return N-th interior ring of Polygon |
ST_Intersection() |
Return point set intersection of two geometries |
ST_Intersects() |
Whether one geometry intersects another |
ST_IsClosed() |
Whether a geometry is closed and simple |
ST_IsEmpty() |
Placeholder function |
ST_IsSimple() |
Whether a geometry is simple |
ST_IsValid() |
Whether a geometry is valid |
ST_LatFromGeoHash() |
Return latitude from geohash value |
ST_Latitude() |
Return latitude of Point |
ST_Length() |
Return length of LineString |
ST_LineFromText() , ST_LineStringFromText() |
Construct LineString from WKT |
ST_LineFromWKB() , ST_LineStringFromWKB() |
Construct LineString from WKB |
ST_LongFromGeoHash() |
Return longitude from geohash value |
ST_Longitude() |
Return longitude of Point |
ST_MakeEnvelope() |
Rectangle around two points |
ST_MLineFromText() , ST_MultiLineStringFromText() |
Construct MultiLineString from WKT |
ST_MLineFromWKB() , ST_MultiLineStringFromWKB() |
Construct MultiLineString from WKB |
ST_MPointFromText() , ST_MultiPointFromText() |
Construct MultiPoint from WKT |
ST_MPointFromWKB() , ST_MultiPointFromWKB() |
Construct MultiPoint from WKB |
ST_MPolyFromText() , ST_MultiPolygonFromText() |
Construct MultiPolygon from WKT |
ST_MPolyFromWKB() , ST_MultiPolygonFromWKB() |
Construct MultiPolygon from WKB |
ST_NumGeometries() |
Return number of geometries in geometry collection |
ST_NumInteriorRing() , ST_NumInteriorRings() |
Return number of interior rings in Polygon |
ST_NumPoints() |
Return number of points in LineString |
ST_Overlaps() |
Whether one geometry overlaps another |
ST_PointFromGeoHash() |
Convert geohash value to POINT value |
ST_PointFromText() |
Construct Point from WKT |
ST_PointFromWKB() |
Construct Point from WKB |
ST_PointN() |
Return N-th point from LineString |
ST_PolyFromText() , ST_PolygonFromText() |
Construct Polygon from WKT |
ST_PolyFromWKB() , ST_PolygonFromWKB() |
Construct Polygon from WKB |
ST_Simplify() |
Return simplified geometry |
ST_SRID() |
Return spatial reference system ID for geometry |
ST_StartPoint() |
Start Point of LineString |
ST_SwapXY() |
Return argument with X/Y coordinates swapped |
ST_SymDifference() |
Return point set symmetric difference of two geometries |
ST_Touches() |
Whether one geometry touches another |
ST_Transform() |
Transform coordinates of geometry |
ST_Union() |
Return point set union of two geometries |
ST_Validate() |
Return validated geometry |
ST_Within() |
Whether one geometry is within another |
ST_X() |
Return X coordinate of Point |
ST_Y() |
Return Y coordinate of Point |
STATEMENT_DIGEST() |
Compute statement digest hash value |
STATEMENT_DIGEST_TEXT() |
Compute normalized statement digest |
STD() |
Return the population standard deviation |
STDDEV() |
Return the population standard deviation |
STDDEV_POP() |
Return the population standard deviation |
STDDEV_SAMP() |
Return the sample standard deviation |
STR_TO_DATE() |
Convert a string to a date |
STRCMP() |
Compare two strings |
SUBDATE() |
Synonym for DATE_SUB() when invoked with three arguments |
SUBSTR() |
Return the substring as specified |
SUBSTRING() |
Return the substring as specified |
SUBSTRING_INDEX() |
Return a substring from a string before the specified number of occurrences of the delimiter |
SUBTIME() |
Subtract times |
SUM() |
Return the sum |
SYSDATE() |
Return the time at which the function executes |
SYSTEM_USER() |
Synonym for USER() |
TAN() |
Return the tangent of the argument |
TIME() |
Extract the time portion of the expression passed |
TIME_FORMAT() |
Format as time |
TIME_TO_SEC() |
Return the argument converted to seconds |
TIMEDIFF() |
Subtract time |
* |
Multiplication operator |
TIMESTAMP() |
With a single argument, this function returns the date or datetime expression; with two arguments, the sum of the arguments |
TIMESTAMPADD() |
Add an interval to a datetime expression |
TIMESTAMPDIFF() |
Subtract an interval from a datetime expression |
TO_BASE64() |
Return the argument converted to a base-64 string |
TO_DAYS() |
Return the date argument converted to days |
TO_SECONDS() |
Return the date or datetime argument converted to seconds since Year 0 |
TRIM() |
Remove leading and trailing spaces |
TRUNCATE() |
Truncate to specified number of decimal places |
UCASE() |
Synonym for UPPER() |
- |
Change the sign of the argument |
UNCOMPRESS() |
Uncompress a string compressed |
UNCOMPRESSED_LENGTH() |
Return the length of a string before compression |
UNHEX() |
Return a string containing hex representation of a number |
UNIX_TIMESTAMP() |
Return a Unix timestamp |
UpdateXML() |
Return replaced XML fragment |
UPPER() |
Convert to uppercase |
USER() |
The user name and host name provided by the client |
UTC_DATE() |
Return the current UTC date |
UTC_TIME() |
Return the current UTC time |
UTC_TIMESTAMP() |
Return the current UTC date and time |
UUID() |
Return a Universal Unique Identifier (UUID) |
UUID_SHORT() |
Return an integer-valued universal identifier |
UUID_TO_BIN() |
Convert string UUID to binary |
VALIDATE_PASSWORD_STRENGTH() |
Determine strength of password |
VALUES() |
Define the values to be used during an INSERT |
VAR_POP() |
Return the population standard variance |
VAR_SAMP() |
Return the sample variance |
VARIANCE() |
Return the population standard variance |
VERSION() |
Return a string that indicates the MySQL server version |
WAIT_FOR_EXECUTED_GTID_SET() |
Wait until the given GTIDs have executed on slave. |
WAIT_UNTIL_SQL_THREAD_AFTER_GTIDS() |
Wait until the given GTIDs have executed on slave. |
WEEK() |
Return the week number |
WEEKDAY() |
Return the weekday index |
WEEKOFYEAR() |
Return the calendar week of the date (1-53) |
WEIGHT_STRING() |
Return the weight string for a string |
XOR |
Logical XOR |
YEAR() |
Return the year |
YEARWEEK() |
Return the year and week |
When an operator is used with operands of different types, type conversion occurs to make the operands compatible. Some conversions occur implicitly. For example, MySQL automatically converts strings to numbers as necessary, and vice versa.
mysql> -> 2 mysql> -> '2 test' SELECT 1+'1';SELECT CONCAT(2,' test');
It is also possible to convert a number to a string explicitly using the CAST()
function. Conversion occurs implicitly with the CONCAT()
function because it expects string arguments.
mysql> -> 38.8, '38.8' mysql> -> 38.8, '38.8' SELECT 38.8, CAST(38.8 AS CHAR);SELECT 38.8, CONCAT(38.8);
See later in this section for information about the character set of implicit number-to-string conversions, and for modified rules that apply to CREATE TABLE ... SELECT
statements.
The following rules describe how conversion occurs for comparison operations:
If one or both arguments are NULL
, the result of the comparison is NULL
, except for the NULL
-safe <=>
equality comparison operator. For NULL <=> NULL
, the result is true. No conversion is needed.
If both arguments in a comparison operation are strings, they are compared as strings.
If both arguments are integers, they are compared as integers.
Hexadecimal values are treated as binary strings if not compared to a number.
If one of the arguments is a TIMESTAMP
or DATETIME
column and the other argument is a constant, the constant is converted to a timestamp before the comparison is performed. This is done to be more ODBC-friendly. This is not done for the arguments to IN()
. To be safe, always use complete datetime, date, or time strings when doing comparisons. For example, to achieve best results when using BETWEEN
with date or time values, use CAST()
to explicitly convert the values to the desired data type.
A single-row subquery from a table or tables is not considered a constant. For example, if a subquery returns an integer to be compared to a DATETIME
value, the comparison is done as two integers. The integer is not converted to a temporal value. To compare the operands as DATETIME
values, use CAST()
to explicitly convert the subquery value to DATETIME
.
If one of the arguments is a decimal value, comparison depends on the other argument. The arguments are compared as decimal values if the other argument is a decimal or integer value, or as floating-point values if the other argument is a floating-point value.
In all other cases, the arguments are compared as floating-point (real) numbers.
For information about conversion of values from one temporal type to another, see Section 11.3.6, 「Conversion Between Date and Time Types」.
Comparison of JSON values takes place at two levels. The first level of comparison is based on the JSON types of the compared values. If the types differ, the comparison result is determined solely by which type has higher precedence. If the two values have the same JSON type, a second level of comparison occurs using type-specific rules. For comparison of JSON and non-JSON values, the non-JSON value is converted to JSON and the values compared as JSON values. For details, see Comparison and Ordering of JSON Values.
The following examples illustrate conversion of strings to numbers for comparison operations:
mysql> -> 0 mysql> -> 1 mysql> -> 0 mysql> -> 1 SELECT 1 > '6x';SELECT 7 > '6x';SELECT 0 > 'x6';SELECT 0 = 'x6';
For comparisons of a string column with a number, MySQL cannot use an index on the column to look up the value quickly. If str_col
is an indexed string column, the index cannot be used when performing the lookup in the following statement:
SELECT * FROM WHERE =1; tbl_namestr_col
The reason for this is that there are many different strings that may convert to the value 1
, such as '1'
, ' 1'
, or '1a'
.
Comparisons that use floating-point numbers (or values that are converted to floating-point numbers) are approximate because such numbers are inexact. This might lead to results that appear inconsistent:
mysql> -> 1 mysql> -> 0 SELECT '18015376320243458' = 18015376320243458;SELECT '18015376320243459' = 18015376320243459;
Such results can occur because the values are converted to floating-point numbers, which have only 53 bits of precision and are subject to rounding:
mysql> -> 1.8015376320243e+16 SELECT '18015376320243459'+0.0;
Furthermore, the conversion from string to floating-point and from integer to floating-point do not necessarily occur the same way. The integer may be converted to floating-point by the CPU, whereas the string is converted digit by digit in an operation that involves floating-point multiplications.
The results shown will vary on different systems, and can be affected by factors such as computer architecture or the compiler version or optimization level. One way to avoid such problems is to use CAST()
so that a value is not converted implicitly to a float-point number:
mysql> -> 1 SELECT CAST('18015376320243459' AS UNSIGNED) = 18015376320243459;
For more information about floating-point comparisons, see Section B.4.4.8, 「Problems with Floating-Point Values」.
The server includes dtoa
, a conversion library that provides the basis for improved conversion between string or DECIMAL
values and approximate-value (FLOAT
/DOUBLE
) numbers:
Consistent conversion results across platforms, which eliminates, for example, Unix versus Windows conversion differences.
Accurate representation of values in cases where results previously did not provide sufficient precision, such as for values close to IEEE limits.
Conversion of numbers to string format with the best possible precision. The precision of dtoa
is always the same or better than that of the standard C library functions.
Because the conversions produced by this library differ in some cases from non-dtoa
results, the potential exists for incompatibilities in applications that rely on previous results. For example, applications that depend on a specific exact result from previous conversions might need adjustment to accommodate additional precision.
The dtoa
library provides conversions with the following properties. D
represents a value with a DECIMAL
or string representation, and F
represents a floating-point number in native binary (IEEE) format.
F
-> D
conversion is done with the best possible precision, returning D
as the shortest string that yields F
when read back in and rounded to the nearest value in native binary format as specified by IEEE.
D
-> F
conversion is done such that F
is the nearest native binary number to the input decimal string D
.
These properties imply that F
-> D
-> F
conversions are lossless unless F
is -inf
, +inf
, or NaN
. The latter values are not supported because the SQL standard defines them as invalid values for FLOAT
or DOUBLE
.
For D
-> F
-> D
conversions, a sufficient condition for losslessness is that D
uses 15 or fewer digits of precision, is not a denormal value, -inf
, +inf
, or NaN
. In some cases, the conversion is lossless even if D
has more than 15 digits of precision, but this is not always the case.
Implicit conversion of a numeric or temporal value to string produces a value that has a character set and collation determined by the character_set_connection
and collation_connection
system variables. (These variables commonly are set with SET NAMES
. For information about connection character sets, see Section 10.4, 「Connection Character Sets and Collations」.)
This means that such a conversion results in a character (nonbinary) string (a CHAR
, VARCHAR
, or LONGTEXT
value), except in the case that the connection character set is set to binary
. In that case, the conversion result is a binary string (a BINARY
, VARBINARY
, or LONGBLOB
value).
For integer expressions, the preceding remarks about expression evaluation apply somewhat differently for expression assignment; for example, in a statement such as this:
CREATE TABLE t SELECT ; integer_expr
In this case, the table in the column resulting from the expression has type INT
or BIGINT
depending on the length of the integer expression. If the maximum length of the expression does not fit in an INT
, BIGINT
is used instead. The length is taken from the max_length
value of the SELECT
result set metadata (see Section 28.7.5, 「C API Data Structures」). This means that you can force a BIGINT
rather than INT
by use of a sufficiently long expression:
CREATE TABLE t SELECT 000000000000000000000;
Table 12.2 Operators
Name | Description |
---|---|
AND , && |
Logical AND |
= |
Assign a value (as part of a SET statement, or as part of the SET clause in an UPDATE statement) |
:= |
Assign a value |
BETWEEN ... AND ... |
Check whether a value is within a range of values |
BINARY |
Cast a string to a binary string |
& |
Bitwise AND |
~ |
Bitwise inversion |
| |
Bitwise OR |
^ |
Bitwise XOR |
CASE |
Case operator |
DIV |
Integer division |
/ |
Division operator |
= |
Equal operator |
<=> |
NULL-safe equal to operator |
> |
Greater than operator |
>= |
Greater than or equal operator |
IS |
Test a value against a boolean |
IS NOT |
Test a value against a boolean |
IS NOT NULL |
NOT NULL value test |
IS NULL |
NULL value test |
-> |
Return value from JSON column after evaluating path; equivalent to JSON_EXTRACT(). |
->> |
Return value from JSON column after evaluating path and unquoting the result; equivalent to JSON_UNQUOTE(JSON_EXTRACT()). |
<< |
Left shift |
< |
Less than operator |
<= |
Less than or equal operator |
LIKE |
Simple pattern matching |
- |
Minus operator |
% , MOD |
Modulo operator |
NOT , ! |
Negates value |
NOT BETWEEN ... AND ... |
Check whether a value is not within a range of values |
!= , <> |
Not equal operator |
NOT LIKE |
Negation of simple pattern matching |
NOT REGEXP |
Negation of REGEXP |
OR , || |
Logical OR |
+ |
Addition operator |
REGEXP |
Whether string matches regular expression |
>> |
Right shift |
RLIKE |
Whether string matches regular expression |
SOUNDS LIKE |
Compare sounds |
* |
Multiplication operator |
- |
Change the sign of the argument |
XOR |
Logical XOR |
Operator precedences are shown in the following list, from highest precedence to the lowest. Operators that are shown together on a line have the same precedence.
INTERVAL BINARY, COLLATE ! - (unary minus), ~ (unary bit inversion) ^ *, /, DIV, %, MOD -, + <<, >> & | = (comparison), <=>, >=, >, <=, <, <>, !=, IS, LIKE, REGEXP, IN BETWEEN, CASE, WHEN, THEN, ELSE NOT AND, && XOR OR, || = (assignment), :=
The precedence of =
depends on whether it is used as a comparison operator (=
) or as an assignment operator (=
). When used as a comparison operator, it has the same precedence as <=>
, >=
, >
, <=
, <
, <>
, !=
, IS
, LIKE
, REGEXP
, and IN
. When used as an assignment operator, it has the same precedence as :=
. Section 13.7.5.1, 「SET Syntax for Variable Assignment」, and Section 9.4, 「User-Defined Variables」, explain how MySQL determines which interpretation of =
should apply.
For operators that occur at the same precedence level within an expression, evaluation proceeds left to right, with the exception that assignments evaluate right to left.
The precedence and meaning of some operators depends on the SQL mode:
By default, ||
is a logical OR
operator. With PIPES_AS_CONCAT
enabled, ||
is string concatenation, with a precedence between ^
and the unary operators.
By default, !
has a higher precedence than NOT
. With HIGH_NOT_PRECEDENCE
enabled, !
and NOT
have the same precedence.
See Section 5.1.11, 「Server SQL Modes」.
The precedence of operators determines the order of evaluation of terms in an expression. To override this order and group terms explicitly, use parentheses. For example:
mysql> -> 7 mysql> -> 9 SELECT 1+2*3;SELECT (1+2)*3;
Table 12.3 Comparison Operators
Name | Description |
---|---|
BETWEEN ... AND ... |
Check whether a value is within a range of values |
COALESCE() |
Return the first non-NULL argument |
= |
Equal operator |
<=> |
NULL-safe equal to operator |
> |
Greater than operator |
>= |
Greater than or equal operator |
GREATEST() |
Return the largest argument |
IN() |
Check whether a value is within a set of values |
INTERVAL() |
Return the index of the argument that is less than the first argument |
IS |
Test a value against a boolean |
IS NOT |
Test a value against a boolean |
IS NOT NULL |
NOT NULL value test |
IS NULL |
NULL value test |
ISNULL() |
Test whether the argument is NULL |
LEAST() |
Return the smallest argument |
< |
Less than operator |
<= |
Less than or equal operator |
LIKE |
Simple pattern matching |
NOT BETWEEN ... AND ... |
Check whether a value is not within a range of values |
!= , <> |
Not equal operator |
NOT IN() |
Check whether a value is not within a set of values |
NOT LIKE |
Negation of simple pattern matching |
STRCMP() |
Compare two strings |
Comparison operations result in a value of 1
(TRUE
), 0
(FALSE
), or NULL
. These operations work for both numbers and strings. Strings are automatically converted to numbers and numbers to strings as necessary.
The following relational comparison operators can be used to compare not only scalar operands, but row operands:
= > < >= <= <> !=
The descriptions for those operators later in this section detail how they work with row operands. For additional examples of row comparisons in the context of row subqueries, see Section 13.2.11.5, 「Row Subqueries」.
Some of the functions in this section return values other than 1
(TRUE
), 0
(FALSE
), or NULL
. LEAST()
and GREATEST()
are examples of such functions; Section 12.2, 「Type Conversion in Expression Evaluation」, describes the rules for comparison operations performed by these and similar functions for determining their return values.
In previous versions of MySQL, when evaluating an expression containing LEAST()
or GREATEST()
, the server attempted to guess the context in which the function was used, and to coerce the function's arguments to the data type of the expression as a whole. For example, the arguments to LEAST("11", "45", "2")
are evaluated and sorted as strings, so that this expression returns "11"
. In MySQL 8.0.3 and earlier, when evaluating the expression LEAST("11", "45", "2") + 0
, the server converted the arguments to integers (anticipating the addition of integer 0 to the result) before sorting them, thus returning 2.
Beginning with MySQL 8.0.4, the server no longer attempts to infer context in this fashion. Instead, the function is executed using the arguments as provided, performing data type conversions to one or more of the arguments if and only if they are not all of the same type. Any type coercion mandated by an expression that makes use of the return value is now performed following function execution. This means that, in MySQl 8.0.4 and later, LEAST("11", "45", "2") + 0
evaluates to "11" + 0
and thus to integer 11. (Bug #83895, Bug #25123839)
To convert a value to a specific type for comparison purposes, you can use the CAST()
function. String values can be converted to a different character set using CONVERT()
. See Section 12.10, 「Cast Functions and Operators」.
By default, string comparisons are not case-sensitive and use the current character set. The default is utf8mb4
.
Equal:
mysql> -> 0 mysql> -> 1 mysql> -> 1 mysql> -> 0 mysql> -> 1 SELECT 1 = 0;SELECT '0' = 0;SELECT '0.0' = 0;SELECT '0.01' = 0;SELECT '.01' = 0.01;
For row comparisons, (a, b) = (x, y)
is equivalent to:
(a = x) AND (b = y)
NULL
-safe equal. This operator performs an equality comparison like the =
operator, but returns 1
rather than NULL
if both operands are NULL
, and 0
rather than NULL
if one operand is NULL
.
The <=>
operator is equivalent to the standard SQL IS NOT DISTINCT FROM
operator.
mysql> -> 1, 1, 0 mysql> -> 1, NULL, NULL SELECT 1 <=> 1, NULL <=> NULL, 1 <=> NULL;SELECT 1 = 1, NULL = NULL, 1 = NULL;
For row comparisons, (a, b) <=> (x, y)
is equivalent to:
(a <=> x) AND (b <=> y)
Not equal:
mysql> -> 1 mysql> -> 0 mysql> -> 1 SELECT '.01' <> '0.01';SELECT .01 <> '0.01';SELECT 'zapp' <> 'zappp';
For row comparisons, (a, b) <> (x, y)
and (a, b) != (x, y)
are equivalent to:
(a <> x) OR (b <> y)
Less than or equal:
mysql> -> 1 SELECT 0.1 <= 2;
For row comparisons, (a, b) <= (x, y)
is equivalent to:
(a < x) OR ((a = x) AND (b <= y))
Less than:
mysql> -> 0 SELECT 2 < 2;
For row comparisons, (a, b) < (x, y)
is equivalent to:
(a < x) OR ((a = x) AND (b < y))
Greater than or equal:
mysql> -> 1 SELECT 2 >= 2;
For row comparisons, (a, b) >= (x, y)
is equivalent to:
(a > x) OR ((a = x) AND (b >= y))
Greater than:
mysql> -> 0 SELECT 2 > 2;
For row comparisons, (a, b) > (x, y)
is equivalent to:
(a > x) OR ((a = x) AND (b > y))
Tests a value against a boolean value, where boolean_value
can be TRUE
, FALSE
, or UNKNOWN
.
mysql> -> 1, 1, 1 SELECT 1 IS TRUE, 0 IS FALSE, NULL IS UNKNOWN;
Tests a value against a boolean value, where boolean_value
can be TRUE
, FALSE
, or UNKNOWN
.
mysql> -> 1, 1, 0 SELECT 1 IS NOT UNKNOWN, 0 IS NOT UNKNOWN, NULL IS NOT UNKNOWN;
Tests whether a value is NULL
.
mysql> -> 0, 0, 1 SELECT 1 IS NULL, 0 IS NULL, NULL IS NULL;
To work well with ODBC programs, MySQL supports the following extra features when using IS NULL
:
If sql_auto_is_null
variable is set to 1, then after a statement that successfully inserts an automatically generated AUTO_INCREMENT
value, you can find that value by issuing a statement of the following form:
SELECT * FROM WHERE IS NULL tbl_nameauto_col
If the statement returns a row, the value returned is the same as if you invoked the LAST_INSERT_ID()
function. For details, including the return value after a multiple-row insert, see Section 12.15, 「Information Functions」. If no AUTO_INCREMENT
value was successfully inserted, the SELECT
statement returns no row.
The behavior of retrieving an AUTO_INCREMENT
value by using an IS NULL
comparison can be disabled by setting sql_auto_is_null = 0
. See Section 5.1.8, 「Server System Variables」.
The default value of sql_auto_is_null
is 0.
For DATE
and DATETIME
columns that are declared as NOT NULL
, you can find the special date '0000-00-00'
by using a statement like this:
SELECT * FROM WHERE IS NULL tbl_namedate_column
This is needed to get some ODBC applications to work because ODBC does not support a '0000-00-00'
date value.
See Obtaining Auto-Increment Values, and the description for the FLAG_AUTO_IS_NULL
option at Connector/ODBC Connection Parameters.
Tests whether a value is not NULL
.
mysql> -> 1, 1, 0 SELECT 1 IS NOT NULL, 0 IS NOT NULL, NULL IS NOT NULL;
If expr
is greater than or equal to min
and expr
is less than or equal to max
, BETWEEN
returns 1
, otherwise it returns 0
. This is equivalent to the expression (
if all the arguments are of the same type. Otherwise type conversion takes place according to the rules described in Section 12.2, 「Type Conversion in Expression Evaluation」, but applied to all the three arguments.min
<= expr
AND expr
<= max
)
mysql> -> 1, 0 mysql> -> 0 mysql> -> 1 mysql> -> 1 mysql> -> 0 SELECT 2 BETWEEN 1 AND 3, 2 BETWEEN 3 and 1;SELECT 1 BETWEEN 2 AND 3;SELECT 'b' BETWEEN 'a' AND 'c';SELECT 2 BETWEEN 2 AND '3';SELECT 2 BETWEEN 2 AND 'x-3';
For best results when using BETWEEN
with date or time values, use CAST()
to explicitly convert the values to the desired data type. Examples: If you compare a DATETIME
to two DATE
values, convert the DATE
values to DATETIME
values. If you use a string constant such as '2001-1-1'
in a comparison to a DATE
, cast the string to a DATE
.
This is the same as NOT (
.expr
BETWEEN min
AND max
)
Returns the first non-NULL
value in the list, or NULL
if there are no non-NULL
values.
The return type of COALESCE()
is the aggregated type of the argument types.
mysql> -> 1 mysql> -> NULL SELECT COALESCE(NULL,1);SELECT COALESCE(NULL,NULL,NULL);
With two or more arguments, returns the largest (maximum-valued) argument. The arguments are compared using the same rules as for LEAST()
.
mysql> -> 2 mysql> -> 767.0 mysql> -> 'C' SELECT GREATEST(2,0);SELECT GREATEST(34.0,3.0,5.0,767.0);SELECT GREATEST('B','A','C');
GREATEST()
returns NULL
if any argument is NULL
.
Returns 1
if expr
is equal to any of the values in the IN
list, else returns 0
. If all values are constants, they are evaluated according to the type of expr
and sorted. The search for the item then is done using a binary search. This means IN
is very quick if the IN
value list consists entirely of constants. Otherwise, type conversion takes place according to the rules described in Section 12.2, 「Type Conversion in Expression Evaluation」, but applied to all the arguments.
mysql> -> 0 mysql> -> 1 SELECT 2 IN (0,3,5,7);SELECT 'wefwf' IN ('wee','wefwf','weg');
IN
can be used to compare row constructors:
mysql> -> 1 mysql> -> 0 SELECT (3,4) IN ((1,2), (3,4));SELECT (3,4) IN ((1,2), (3,5));
You should never mix quoted and unquoted values in an IN
list because the comparison rules for quoted values (such as strings) and unquoted values (such as numbers) differ. Mixing types may therefore lead to inconsistent results. For example, do not write an IN
expression like this:
SELECT val1 FROM tbl1 WHERE val1 IN (1,2,'a');
Instead, write it like this:
SELECT val1 FROM tbl1 WHERE val1 IN ('1','2','a');
The number of values in the IN
list is only limited by the max_allowed_packet
value.
To comply with the SQL standard, IN
returns NULL
not only if the expression on the left hand side is NULL
, but also if no match is found in the list and one of the expressions in the list is NULL
.
IN()
syntax can also be used to write certain types of subqueries. See Section 13.2.11.3, 「Subqueries with ANY, IN, or SOME」.
This is the same as NOT (
.expr
IN (value
,...))
If expr
is NULL
, ISNULL()
returns 1
, otherwise it returns 0
.
mysql> -> 0 mysql> -> 1 SELECT ISNULL(1+1);SELECT ISNULL(1/0);
ISNULL()
can be used instead of =
to test whether a value is NULL
. (Comparing a value to NULL
using =
always yields NULL
.)
The ISNULL()
function shares some special behaviors with the IS NULL
comparison operator. See the description of IS NULL
.
Returns 0
if N
< N1
, 1
if N
< N2
and so on or -1
if N
is NULL
. All arguments are treated as integers. It is required that N1
< N2
< N3
< ...
< Nn
for this function to work correctly. This is because a binary search is used (very fast).
mysql> -> 3 mysql> -> 2 mysql> -> 0 SELECT INTERVAL(23, 1, 15, 17, 30, 44, 200);SELECT INTERVAL(10, 1, 10, 100, 1000);SELECT INTERVAL(22, 23, 30, 44, 200);
With two or more arguments, returns the smallest (minimum-valued) argument. The arguments are compared using the following rules:
If any argument is NULL
, the result is NULL
. No comparison is needed.
If all arguments are integer-valued, they are compared as integers.
If at least one argument is double precision, they are compared as double-precision values. Otherwise, if at least one argument is a DECIMAL
value, they are compared as DECIMAL
values.
If the arguments comprise a mix of numbers and strings, they are compared as strings.
If any argument is a nonbinary (character) string, the arguments are compared as nonbinary strings.
In all other cases, the arguments are compared as binary strings.
The return type of LEAST()
is the aggregated type of the comparison argument types.
mysql> -> 0 mysql> -> 3.0 mysql> -> 'A' SELECT LEAST(2,0);SELECT LEAST(34.0,3.0,5.0,767.0);SELECT LEAST('B','A','C');
In SQL, all logical operators evaluate to TRUE
, FALSE
, or NULL
(UNKNOWN
). In MySQL, these are implemented as 1 (TRUE
), 0 (FALSE
), and NULL
. Most of this is common to different SQL database servers, although some servers may return any nonzero value for TRUE
.
MySQL evaluates any nonzero, non-NULL
value to TRUE
. For example, the following statements all assess to TRUE
:
mysql> -> 1 mysql> -> 1 mysql> -> 1 SELECT 10 IS TRUE;SELECT -10 IS TRUE;SELECT 'string' IS NOT NULL;
Logical NOT. Evaluates to 1
if the operand is 0
, to 0
if the operand is nonzero, and NOT NULL
returns NULL
.
mysql> -> 0 mysql> -> 1 mysql> -> NULL mysql> -> 0 mysql> -> 1 SELECT NOT 10;SELECT NOT 0;SELECT NOT NULL;SELECT ! (1+1);SELECT ! 1+1;
The last example produces 1
because the expression evaluates the same way as (!1)+1
.
The !
, operator is a nonstandard MySQL extension. As of MySQL 8.0.17, this operator is deprecated and support for it will be removed in a future MySQL version. Applications should be adjusted to use the standard SQL NOT
operator.
Logical AND. Evaluates to 1
if all operands are nonzero and not NULL
, to 0
if one or more operands are 0
, otherwise NULL
is returned.
mysql> -> 1 mysql> -> 0 mysql> -> NULL mysql> -> 0 mysql> -> 0 SELECT 1 AND 1;SELECT 1 AND 0;SELECT 1 AND NULL;SELECT 0 AND NULL;SELECT NULL AND 0;
The &&
, operator is a nonstandard MySQL extension. As of MySQL 8.0.17, this operator is deprecated and support for it will be removed in a future MySQL version. Applications should be adjusted to use the standard SQL AND
operator.
Logical OR. When both operands are non-NULL
, the result is 1
if any operand is nonzero, and 0
otherwise. With a NULL
operand, the result is 1
if the other operand is nonzero, and NULL
otherwise. If both operands are NULL
, the result is NULL
.
mysql> -> 1 mysql> -> 1 mysql> -> 0 mysql> -> NULL mysql> -> 1 SELECT 1 OR 1;SELECT 1 OR 0;SELECT 0 OR 0;SELECT 0 OR NULL;SELECT 1 OR NULL;
If the PIPES_AS_CONCAT
SQL mode is enabled, ||
signifies the SQL-standard string concatenation operator (like CONCAT()
).
The ||
, operator is a nonstandard MySQL extension. As of MySQL 8.0.17, this operator is deprecated and support for it will be removed in a future MySQL version. Applications should be adjusted to use the standard SQL OR
operator. Exception: Deprecation does not apply if PIPES_AS_CONCAT
is enabled because, in that case, ||
signifies string concatentation.
Logical XOR. Returns NULL
if either operand is NULL
. For non-NULL
operands, evaluates to 1
if an odd number of operands is nonzero, otherwise 0
is returned.
mysql> -> 0 mysql> -> 1 mysql> -> NULL mysql> -> 1 SELECT 1 XOR 1;SELECT 1 XOR 0;SELECT 1 XOR NULL;SELECT 1 XOR 1 XOR 1;
a XOR b
is mathematically equal to (a AND (NOT b)) OR ((NOT a) and b)
.
Assignment operator. Causes the user variable on the left hand side of the operator to take on the value to its right. The value on the right hand side may be a literal value, another variable storing a value, or any legal expression that yields a scalar value, including the result of a query (provided that this value is a scalar value). You can perform multiple assignments in the same SET
statement. You can perform multiple assignments in the same statement.
Unlike =
, the :=
operator is never interpreted as a comparison operator. This means you can use :=
in any valid SQL statement (not just in SET
statements) to assign a value to a variable.
mysql> -> NULL, NULL mysql> -> 1, NULL mysql> -> 1, NULL mysql> -> 1, 1 mysql> -> 1, 1 mysql> -> 4 mysql> -> 4 SELECT @var1, @var2;SELECT @var1 := 1, @var2;SELECT @var1, @var2;SELECT @var1, @var2 := @var1;SELECT @var1, @var2;SELECT @var1:=COUNT(*) FROM t1;SELECT @var1;
You can make value assignments using :=
in other statements besides SELECT
, such as UPDATE
, as shown here:
mysql> -> 4 mysql> -> 1, 3, 5, 7 mysql> Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> -> 1 mysql> -> 2, 3, 5, 7 SELECT @var1;SELECT * FROM t1;UPDATE t1 SET c1 = 2 WHERE c1 = @var1:= 1;SELECT @var1;SELECT * FROM t1;
While it is also possible both to set and to read the value of the same variable in a single SQL statement using the :=
operator, this is not recommended. Section 9.4, 「User-Defined Variables」, explains why you should avoid doing this.
This operator is used to perform value assignments in two cases, described in the next two paragraphs.
Within a SET
statement, =
is treated as an assignment operator that causes the user variable on the left hand side of the operator to take on the value to its right. (In other words, when used in a SET
statement, =
is treated identically to :=
.) The value on the right hand side may be a literal value, another variable storing a value, or any legal expression that yields a scalar value, including the result of a query (provided that this value is a scalar value). You can perform multiple assignments in the same SET
statement.
In the SET
clause of an UPDATE
statement, =
also acts as an assignment operator; in this case, however, it causes the column named on the left hand side of the operator to assume the value given to the right, provided any WHERE
conditions that are part of the UPDATE
are met. You can make multiple assignments in the same SET
clause of an UPDATE
statement.
In any other context, =
is treated as a comparison operator.
mysql> -> NULL, NULL mysql> -> 1, NULL mysql> -> 1, NULL mysql> -> 1, 1 mysql> -> 1, 1 SELECT @var1, @var2;SELECT @var1 := 1, @var2;SELECT @var1, @var2;SELECT @var1, @var2 := @var1;SELECT @var1, @var2;
For more information, see Section 13.7.5.1, 「SET Syntax for Variable Assignment」, Section 13.2.12, 「UPDATE Syntax」, and Section 13.2.11, 「Subquery Syntax」.
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
The first CASE
syntax returns the result
for the first
comparison that is true. The second syntax returns the result for the first condition that is true. If no comparison or condition is true, the result after value
=compare_value
ELSE
is returned, or NULL
if there is no ELSE
part.
The syntax of the CASE
expr described here differs slightly from that of the SQL CASE
statement described in Section 13.6.5.1, 「CASE Syntax」, for use inside stored programs. The CASE
statement cannot have an ELSE NULL
clause, and it is terminated with END CASE
instead of END
.
The return type of a CASE
expression result is the aggregated type of all result values:
If all types are numeric, the aggregated type is also numeric:
If at least one argument is double precision, the result is double precision.
Otherwise, if at least one argument is DECIMAL
, the result is DECIMAL
.
Otherwise, the result is an integer type (with one exception):
If all integer types are all signed or all unsigned, the result is the same sign and the precision is the highest of all specified integer types (that is, TINYINT
, SMALLINT
, MEDIUMINT
, INT
, or BIGINT
).
If there is a combination of signed and unsigned integer types, the result is signed and the precision may be higher. For example, if the types are signed INT
and unsigned INT
, the result is signed BIGINT
.
The exception is unsigned BIGINT
combined with any signed integer type. The result is DECIMAL
with sufficient precision and scale 0.
If all types are BIT
, the result is BIT
. Otherwise, BIT
arguments are treated similar to BIGINT
.
If all types are YEAR
, the result is YEAR
. Otherwise, YEAR
arguments are treated similar to INT
.
If all types are character string (CHAR
or VARCHAR
), the result is VARCHAR
with maximum length determined by the longest character length of the operands.
If all types are character or binary string, the result is VARBINARY
.
SET
and ENUM
are treated similar to VARCHAR
; the result is VARCHAR
.
If all types are temporal, the result is temporal:
If all types are GEOMETRY
, the result is GEOMETRY
.
For all other type combinations, the result is VARCHAR
.
Literal NULL
operands are ignored for type aggregation.
mysql> -> -> 'one' mysql> -> 'true' mysql> -> -> NULL SELECT CASE 1 WHEN 1 THEN 'one'WHEN 2 THEN 'two' ELSE 'more' END;SELECT CASE WHEN 1>0 THEN 'true' ELSE 'false' END;SELECT CASE BINARY 'B'WHEN 'a' THEN 1 WHEN 'b' THEN 2 END;
If expr1
is TRUE
(
and expr1
<> 0
), expr1
<> NULLIF()
returns expr2
. Otherwise, it returns expr3
.
There is also an IF
statement, which differs from the IF()
function described here. See Section 13.6.5.2, 「IF Syntax」.
If only one of expr2
or expr3
is explicitly NULL
, the result type of the IF()
function is the type of the non-NULL
expression.
The default return type of IF()
(which may matter when it is stored into a temporary table) is calculated as follows:
If expr2
or expr3
produce a string, the result is a string.
If expr2
and expr3
are both strings, the result is case-sensitive if either string is case sensitive.
If expr2
or expr3
produce a floating-point value, the result is a floating-point value.
If expr2
or expr3
produce an integer, the result is an integer.
mysql> -> 3 mysql> -> 'yes' mysql> -> 'no' SELECT IF(1>2,2,3);SELECT IF(1<2,'yes','no');SELECT IF(STRCMP('test','test1'),'no','yes');
If expr1
is not NULL
, IFNULL()
returns expr1
; otherwise it returns expr2
.
mysql> -> 1 mysql> -> 10 mysql> -> 10 mysql> -> 'yes' SELECT IFNULL(1,0);SELECT IFNULL(NULL,10);SELECT IFNULL(1/0,10);SELECT IFNULL(1/0,'yes');
The default return type of IFNULL(
is the more 「general」 of the two expressions, in the order expr1
,expr2
)STRING
, REAL
, or INTEGER
. Consider the case of a table based on expressions or where MySQL must internally store a value returned by IFNULL()
in a temporary table:
mysql> mysql> +-------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+--------------+------+-----+---------+-------+ | test | varbinary(4) | NO | | | | +-------+--------------+------+-----+---------+-------+ CREATE TABLE tmp SELECT IFNULL(1,'test') AS test;DESCRIBE tmp;
In this example, the type of the test
column is VARBINARY(4)
(a string type).
Returns NULL
if
is true, otherwise returns expr1
= expr2
expr1
. This is the same as CASE WHEN
.expr1
= expr2
THEN NULL ELSE expr1
END
The return value has the same type as the first argument.
mysql> -> NULL mysql> -> 1 SELECT NULLIF(1,1);SELECT NULLIF(1,2);
MySQL evaluates expr1
twice if the arguments are not equal.
Table 12.7 String Operators
Name | Description |
---|---|
ASCII() |
Return numeric value of left-most character |
BIN() |
Return a string containing binary representation of a number |
BIT_LENGTH() |
Return length of argument in bits |
CHAR() |
Return the character for each integer passed |
CHAR_LENGTH() |
Return number of characters in argument |
CHARACTER_LENGTH() |
Synonym for CHAR_LENGTH() |
CONCAT() |
Return concatenated string |
CONCAT_WS() |
Return concatenate with separator |
ELT() |
Return string at index number |
EXPORT_SET() |
Return a string such that for every bit set in the value bits, you get an on string and for every unset bit, you get an off string |
FIELD() |
Index (position) of first argument in subsequent arguments |
FIND_IN_SET() |
Index (position) of first argument within second argument |
FORMAT() |
Return a number formatted to specified number of decimal places |
FROM_BASE64() |
Decode base64 encoded string and return result |
HEX() |
Hexadecimal representation of decimal or string value |
INSERT() |
Insert substring at specified position up to specified number of characters |
INSTR() |
Return the index of the first occurrence of substring |
LCASE() |
Synonym for LOWER() |
LEFT() |
Return the leftmost number of characters as specified |
LENGTH() |
Return the length of a string in bytes |
LIKE |
Simple pattern matching |
LOAD_FILE() |
Load the named file |
LOCATE() |
Return the position of the first occurrence of substring |
LOWER() |
Return the argument in lowercase |
LPAD() |
Return the string argument, left-padded with the specified string |
LTRIM() |
Remove leading spaces |
MAKE_SET() |
Return a set of comma-separated strings that have the corresponding bit in bits set |
MATCH |
Perform full-text search |
MID() |
Return a substring starting from the specified position |
NOT LIKE |
Negation of simple pattern matching |
NOT REGEXP |
Negation of REGEXP |
OCT() |
Return a string containing octal representation of a number |
OCTET_LENGTH() |
Synonym for LENGTH() |
ORD() |
Return character code for leftmost character of the argument |
POSITION() |
Synonym for LOCATE() |
QUOTE() |
Escape the argument for use in an SQL statement |
REGEXP |
Whether string matches regular expression |
REGEXP_INSTR() |
Starting index of substring matching regular expression |
REGEXP_LIKE() |
Whether string matches regular expression |
REGEXP_REPLACE() |
Replace substrings matching regular expression |
REGEXP_SUBSTR() |
Return substring matching regular expression |
REPEAT() |
Repeat a string the specified number of times |
REPLACE() |
Replace occurrences of a specified string |
REVERSE() |
Reverse the characters in a string |
RIGHT() |
Return the specified rightmost number of characters |
RLIKE |
Whether string matches regular expression |
RPAD() |
Append string the specified number of times |
RTRIM() |
Remove trailing spaces |
SOUNDEX() |
Return a soundex string |
SOUNDS LIKE |
Compare sounds |
SPACE() |
Return a string of the specified number of spaces |
STRCMP() |
Compare two strings |
SUBSTR() |
Return the substring as specified |
SUBSTRING() |
Return the substring as specified |
SUBSTRING_INDEX() |
Return a substring from a string before the specified number of occurrences of the delimiter |
TO_BASE64() |
Return the argument converted to a base-64 string |
TRIM() |
Remove leading and trailing spaces |
UCASE() |
Synonym for UPPER() |
UNHEX() |
Return a string containing hex representation of a number |
UPPER() |
Convert to uppercase |
WEIGHT_STRING() |
Return the weight string for a string |
String-valued functions return NULL
if the length of the result would be greater than the value of the max_allowed_packet
system variable. See Section 5.1.1, 「Configuring the Server」.
For functions that operate on string positions, the first position is numbered 1.
For functions that take length arguments, noninteger arguments are rounded to the nearest integer.
Returns the numeric value of the leftmost character of the string str
. Returns 0
if str
is the empty string. Returns NULL
if str
is NULL
. ASCII()
works for 8-bit characters.
mysql> -> 50 mysql> -> 50 mysql> -> 100 SELECT ASCII('2');SELECT ASCII(2);SELECT ASCII('dx');
See also the ORD()
function.
Returns a string representation of the binary value of N
, where N
is a longlong (BIGINT
) number. This is equivalent to CONV(
. Returns N
,10,2)NULL
if N
is NULL
.
mysql> -> '1100' SELECT BIN(12);
Returns the length of the string str
in bits.
mysql> -> 32 SELECT BIT_LENGTH('text');
CHAR(
N
,... [USING charset_name
])
CHAR()
interprets each argument N
as an integer and returns a string consisting of the characters given by the code values of those integers. NULL
values are skipped.
mysql> -> 'MySQL' mysql> -> 'MMM' SELECT CHAR(77,121,83,81,'76');SELECT CHAR(77,77.3,'77.3');
CHAR()
arguments larger than 255 are converted into multiple result bytes. For example, CHAR(256)
is equivalent to CHAR(1,0)
, and CHAR(256*256)
is equivalent to CHAR(1,0,0)
:
mysql> +----------------+----------------+ | HEX(CHAR(1,0)) | HEX(CHAR(256)) | +----------------+----------------+ | 0100 | 0100 | +----------------+----------------+ mysql> +------------------+--------------------+ | HEX(CHAR(1,0,0)) | HEX(CHAR(256*256)) | +------------------+--------------------+ | 010000 | 010000 | +------------------+--------------------+ SELECT HEX(CHAR(1,0)), HEX(CHAR(256));SELECT HEX(CHAR(1,0,0)), HEX(CHAR(256*256));
By default, CHAR()
returns a binary string. To produce a string in a given character set, use the optional USING
clause:
mysql> +----------------------+---------------------------------+ | CHARSET(CHAR(X'65')) | CHARSET(CHAR(X'65' USING utf8)) | +----------------------+---------------------------------+ | binary | utf8 | +----------------------+---------------------------------+ SELECT CHARSET(CHAR(X'65')), CHARSET(CHAR(X'65' USING utf8));
If USING
is given and the result string is illegal for the given character set, a warning is issued. Also, if strict SQL mode is enabled, the result from CHAR()
becomes NULL
.
Returns the length of the string str
, measured in characters. A multibyte character counts as a single character. This means that for a string containing five 2-byte characters, LENGTH()
returns 10
, whereas CHAR_LENGTH()
returns 5
.
CHARACTER_LENGTH()
is a synonym for CHAR_LENGTH()
.
Returns the string that results from concatenating the arguments. May have one or more arguments. If all arguments are nonbinary strings, the result is a nonbinary string. If the arguments include any binary strings, the result is a binary string. A numeric argument is converted to its equivalent nonbinary string form.
CONCAT()
returns NULL
if any argument is NULL
.
mysql> -> 'MySQL' mysql> -> NULL mysql> -> '14.3' SELECT CONCAT('My', 'S', 'QL');SELECT CONCAT('My', NULL, 'QL');SELECT CONCAT(14.3);
For quoted strings, concatenation can be performed by placing the strings next to each other:
mysql> -> 'MySQL' SELECT 'My' 'S' 'QL';
CONCAT_WS(
separator
,str1
,str2
,...)
CONCAT_WS()
stands for Concatenate With Separator and is a special form of CONCAT()
. The first argument is the separator for the rest of the arguments. The separator is added between the strings to be concatenated. The separator can be a string, as can the rest of the arguments. If the separator is NULL
, the result is NULL
.
mysql> -> 'First name,Second name,Last Name' mysql> -> 'First name,Last Name' SELECT CONCAT_WS(',','First name','Second name','Last Name');SELECT CONCAT_WS(',','First name',NULL,'Last Name');
CONCAT_WS()
does not skip empty strings. However, it does skip any NULL
values after the separator argument.
ELT()
returns the N
th element of the list of strings: str1
if N
= 1
, str2
if N
= 2
, and so on. Returns NULL
if N
is less than 1
or greater than the number of arguments. ELT()
is the complement of FIELD()
.
mysql> -> 'Aa' mysql> -> 'Dd' SELECT ELT(1, 'Aa', 'Bb', 'Cc', 'Dd');SELECT ELT(4, 'Aa', 'Bb', 'Cc', 'Dd');
EXPORT_SET(
bits
,on
,off
[,separator
[,number_of_bits
]])
Returns a string such that for every bit set in the value bits
, you get an on
string and for every bit not set in the value, you get an off
string. Bits in bits
are examined from right to left (from low-order to high-order bits). Strings are added to the result from left to right, separated by the separator
string (the default being the comma character ,
). The number of bits examined is given by number_of_bits
, which has a default of 64 if not specified. number_of_bits
is silently clipped to 64 if larger than 64. It is treated as an unsigned integer, so a value of −1 is effectively the same as 64.
mysql> -> 'Y,N,Y,N' mysql> -> '0,1,1,0,0,0,0,0,0,0' SELECT EXPORT_SET(5,'Y','N',',',4);SELECT EXPORT_SET(6,'1','0',',',10);
Returns the index (position) of str
in the str1
, str2
, str3
, ...
list. Returns 0
if str
is not found.
If all arguments to FIELD()
are strings, all arguments are compared as strings. If all arguments are numbers, they are compared as numbers. Otherwise, the arguments are compared as double.
If str
is NULL
, the return value is 0
because NULL
fails equality comparison with any value. FIELD()
is the complement of ELT()
.
mysql> -> 2 mysql> -> 0 SELECT FIELD('Bb', 'Aa', 'Bb', 'Cc', 'Dd', 'Ff');SELECT FIELD('Gg', 'Aa', 'Bb', 'Cc', 'Dd', 'Ff');
Returns a value in the range of 1 to N
if the string str
is in the string list strlist
consisting of N
substrings. A string list is a string composed of substrings separated by ,
characters. If the first argument is a constant string and the second is a column of type SET
, the FIND_IN_SET()
function is optimized to use bit arithmetic. Returns 0
if str
is not in strlist
or if strlist
is the empty string. Returns NULL
if either argument is NULL
. This function does not work properly if the first argument contains a comma (,
) character.
mysql> -> 2 SELECT FIND_IN_SET('b','a,b,c,d');
Formats the number X
to a format like '#,###,###.##'
, rounded to D
decimal places, and returns the result as a string. If D
is 0
, the result has no decimal point or fractional part.
The optional third parameter enables a locale to be specified to be used for the result number's decimal point, thousands separator, and grouping between separators. Permissible locale values are the same as the legal values for the lc_time_names
system variable (see Section 10.15, 「MySQL Server Locale Support」). If no locale is specified, the default is 'en_US'
.
mysql> -> '12,332.1235' mysql> -> '12,332.1000' mysql> -> '12,332' mysql> -> '12.332,20' SELECT FORMAT(12332.123456, 4);SELECT FORMAT(12332.1,4);SELECT FORMAT(12332.2,0);SELECT FORMAT(12332.2,2,'de_DE');
Takes a string encoded with the base-64 encoded rules used by TO_BASE64()
and returns the decoded result as a binary string. The result is NULL
if the argument is NULL
or not a valid base-64 string. See the description of TO_BASE64()
for details about the encoding and decoding rules.
mysql> -> 'JWJj', 'abc' SELECT TO_BASE64('abc'), FROM_BASE64(TO_BASE64('abc'));
For a string argument str
, HEX()
returns a hexadecimal string representation of str
where each byte of each character in str
is converted to two hexadecimal digits. (Multibyte characters therefore become more than two digits.) The inverse of this operation is performed by the UNHEX()
function.
For a numeric argument N
, HEX()
returns a hexadecimal string representation of the value of N
treated as a longlong (BIGINT
) number. This is equivalent to CONV(
. The inverse of this operation is performed by N
,10,16)CONV(HEX(
.N
),16,10)
mysql> -> 'abc', 616263, 'abc' mysql> -> 'FF', 255 SELECT X'616263', HEX('abc'), UNHEX(HEX('abc'));SELECT HEX(255), CONV(HEX(255),16,10);
Returns the string str
, with the substring beginning at position pos
and len
characters long replaced by the string newstr
. Returns the original string if pos
is not within the length of the string. Replaces the rest of the string from position pos
if len
is not within the length of the rest of the string. Returns NULL
if any argument is NULL
.
mysql> -> 'QuWhattic' mysql> -> 'Quadratic' mysql> -> 'QuWhat' SELECT INSERT('Quadratic', 3, 4, 'What');SELECT INSERT('Quadratic', -1, 4, 'What');SELECT INSERT('Quadratic', 3, 100, 'What');
This function is multibyte safe.
Returns the position of the first occurrence of substring substr
in string str
. This is the same as the two-argument form of LOCATE()
, except that the order of the arguments is reversed.
mysql> -> 4 mysql> -> 0 SELECT INSTR('foobarbar', 'bar');SELECT INSTR('xbar', 'foobar');
This function is multibyte safe, and is case-sensitive only if at least one argument is a binary string.
LCASE()
is a synonym for LOWER()
.
LCASE()
used in a view is rewritten as LOWER()
when storing the view's definition. (Bug #12844279)
Returns the leftmost len
characters from the string str
, or NULL
if any argument is NULL
.
mysql> -> 'fooba' SELECT LEFT('foobarbar', 5);
This function is multibyte safe.
Returns the length of the string str
, measured in bytes. A multibyte character counts as multiple bytes. This means that for a string containing five 2-byte characters, LENGTH()
returns 10
, whereas CHAR_LENGTH()
returns 5
.
mysql> -> 4 SELECT LENGTH('text');
The Length()
OpenGIS spatial function is named ST_Length()
in MySQL.
Reads the file and returns the file contents as a string. To use this function, the file must be located on the server host, you must specify the full path name to the file, and you must have the FILE
privilege. The file must be readable by the server and its size less than max_allowed_packet
bytes. If the secure_file_priv
system variable is set to a nonempty directory name, the file to be loaded must be located in that directory. (Prior to MySQL 8.0.17, the file must be readable by all, not just readable by the server.)
If the file does not exist or cannot be read because one of the preceding conditions is not satisfied, the function returns NULL
.
The character_set_filesystem
system variable controls interpretation of file names that are given as literal strings.
mysql> UPDATE tSET blob_col=LOAD_FILE('/tmp/picture')WHERE id=1;
LOCATE(
, substr
,str
)LOCATE(
substr
,str
,pos
)
The first syntax returns the position of the first occurrence of substring substr
in string str
. The second syntax returns the position of the first occurrence of substring substr
in string str
, starting at position pos
. Returns 0
if substr
is not in str
. Returns NULL
if any argument is NULL
.
mysql> -> 4 mysql> -> 0 mysql> -> 7 SELECT LOCATE('bar', 'foobarbar');SELECT LOCATE('xbar', 'foobar');SELECT LOCATE('bar', 'foobarbar', 5);
This function is multibyte safe, and is case-sensitive only if at least one argument is a binary string.
Returns the string str
with all characters changed to lowercase according to the current character set mapping. The default is utf8mb4
.
mysql> -> 'quadratically' SELECT LOWER('QUADRATICALLY');
LOWER()
(and UPPER()
) are ineffective when applied to binary strings (BINARY
, VARBINARY
, BLOB
). To perform lettercase conversion, convert the string to a nonbinary string:
mysql> mysql> +-------------+------------------------------------+ | LOWER(@str) | LOWER(CONVERT(@str USING utf8mb4)) | +-------------+------------------------------------+ | New York | new york | +-------------+------------------------------------+ SET @str = BINARY 'New York';SELECT LOWER(@str), LOWER(CONVERT(@str USING utf8mb4));
For collations of Unicode character sets, LOWER()
and UPPER()
work according to the Unicode Collation Algorithm (UCA) version in the collation name, if there is one, and UCA 4.0.0 if no version is specified. For example, utf8mb4_0900_ai_ci
and utf8_unicode_520_ci
work according to UCA 9.0.0 and 5.2.0, respectively, whereas utf8_unicode_ci
works according to UCA 4.0.0. See Section 10.10.1, 「Unicode Character Sets」.
This function is multibyte safe.
LCASE()
used within views is rewritten as LOWER()
.
Returns the string str
, left-padded with the string padstr
to a length of len
characters. If str
is longer than len
, the return value is shortened to len
characters.
mysql> -> '??hi' mysql> -> 'h' SELECT LPAD('hi',4,'??');SELECT LPAD('hi',1,'??');
Returns the string str
with leading space characters removed.
mysql> -> 'barbar' SELECT LTRIM(' barbar');
This function is multibyte safe.
Returns a set value (a string containing substrings separated by ,
characters) consisting of the strings that have the corresponding bit in bits
set. str1
corresponds to bit 0, str2
to bit 1, and so on. NULL
values in str1
, str2
, ...
are not appended to the result.
mysql> -> 'a' mysql> -> 'hello,world' mysql> -> 'hello' mysql> -> '' SELECT MAKE_SET(1,'a','b','c');SELECT MAKE_SET(1 | 4,'hello','nice','world');SELECT MAKE_SET(1 | 4,'hello','nice',NULL,'world');SELECT MAKE_SET(0,'a','b','c');
MID(
is a synonym for str
,pos
,len
)SUBSTRING(
.str
,pos
,len
)
Returns a string representation of the octal value of N
, where N
is a longlong (BIGINT
) number. This is equivalent to CONV(
. Returns N
,10,8)NULL
if N
is NULL
.
mysql> -> '14' SELECT OCT(12);
OCTET_LENGTH()
is a synonym for LENGTH()
.
If the leftmost character of the string str
is a multibyte character, returns the code for that character, calculated from the numeric values of its constituent bytes using this formula:
(1st byte code) + (2nd byte code * 256) + (3rd byte code * 256^2) ...
If the leftmost character is not a multibyte character, ORD()
returns the same value as the ASCII()
function.
mysql> -> 50 SELECT ORD('2');
POSITION(
is a synonym for substr
IN str
)LOCATE(
.substr
,str
)
Quotes a string to produce a result that can be used as a properly escaped data value in an SQL statement. The string is returned enclosed by single quotation marks and with each instance of backslash (\
), single quote ('
), ASCII NUL
, and Control+Z preceded by a backslash. If the argument is NULL
, the return value is the word 「NULL」 without enclosing single quotation marks.
mysql> -> 'Don\'t!' mysql> -> NULL SELECT QUOTE('Don\'t!');SELECT QUOTE(NULL);
For comparison, see the quoting rules for literal strings and within the C API in Section 9.1.1, 「String Literals」, and Section 28.7.7.56, 「mysql_real_escape_string_quote()」.
Returns a string consisting of the string str
repeated count
times. If count
is less than 1, returns an empty string. Returns NULL
if str
or count
are NULL
.
mysql> -> 'MySQLMySQLMySQL' SELECT REPEAT('MySQL', 3);
Returns the string str
with all occurrences of the string from_str
replaced by the string to_str
. REPLACE()
performs a case-sensitive match when searching for from_str
.
mysql> -> 'WwWwWw.mysql.com' SELECT REPLACE('www.mysql.com', 'w', 'Ww');
This function is multibyte safe.
Returns the string str
with the order of the characters reversed.
mysql> -> 'cba' SELECT REVERSE('abc');
This function is multibyte safe.
Returns the rightmost len
characters from the string str
, or NULL
if any argument is NULL
.
mysql> -> 'rbar' SELECT RIGHT('foobarbar', 4);
This function is multibyte safe.
Returns the string str
, right-padded with the string padstr
to a length of len
characters. If str
is longer than len
, the return value is shortened to len
characters.
mysql> -> 'hi???' mysql> -> 'h' SELECT RPAD('hi',5,'?');SELECT RPAD('hi',1,'?');
This function is multibyte safe.
Returns the string str
with trailing space characters removed.
mysql> -> 'barbar' SELECT RTRIM('barbar ');
This function is multibyte safe.
Returns a soundex string from str
. Two strings that sound almost the same should have identical soundex strings. A standard soundex string is four characters long, but the SOUNDEX()
function returns an arbitrarily long string. You can use SUBSTRING()
on the result to get a standard soundex string. All nonalphabetic characters in str
are ignored. All international alphabetic characters outside the A-Z range are treated as vowels.
When using SOUNDEX()
, you should be aware of the following limitations:
This function, as currently implemented, is intended to work well with strings that are in the English language only. Strings in other languages may not produce reliable results.
This function is not guaranteed to provide consistent results with strings that use multibyte character sets, including utf-8
. See Bug #22638 for more information.
mysql> -> 'H400' mysql> -> 'Q36324' SELECT SOUNDEX('Hello');SELECT SOUNDEX('Quadratically');
This function implements the original Soundex algorithm, not the more popular enhanced version (also described by D. Knuth). The difference is that original version discards vowels first and duplicates second, whereas the enhanced version discards duplicates first and vowels second.
This is the same as SOUNDEX(
.expr1
) = SOUNDEX(expr2
)
Returns a string consisting of N
space characters.
mysql> -> ' ' SELECT SPACE(6);
SUBSTR(
, str
,pos
)SUBSTR(
, str
FROM pos
)SUBSTR(
, str
,pos
,len
)SUBSTR(
str
FROM pos
FOR len
)
SUBSTR()
is a synonym for SUBSTRING()
.
SUBSTRING(
, str
,pos
)SUBSTRING(
, str
FROM pos
)SUBSTRING(
, str
,pos
,len
)SUBSTRING(
str
FROM pos
FOR len
)
The forms without a len
argument return a substring from string str
starting at position pos
. The forms with a len
argument return a substring len
characters long from string str
, starting at position pos
. The forms that use FROM
are standard SQL syntax. It is also possible to use a negative value for pos
. In this case, the beginning of the substring is pos
characters from the end of the string, rather than the beginning. A negative value may be used for pos
in any of the forms of this function.
For all forms of SUBSTRING()
, the position of the first character in the string from which the substring is to be extracted is reckoned as 1
.
mysql> -> 'ratically' mysql> -> 'barbar' mysql> -> 'ratica' mysql> -> 'ila' mysql> -> 'aki' mysql> -> 'ki' SELECT SUBSTRING('Quadratically',5);SELECT SUBSTRING('foobarbar' FROM 4);SELECT SUBSTRING('Quadratically',5,6);SELECT SUBSTRING('Sakila', -3);SELECT SUBSTRING('Sakila', -5, 3);SELECT SUBSTRING('Sakila' FROM -4 FOR 2);
This function is multibyte safe.
If len
is less than 1, the result is the empty string.
SUBSTRING_INDEX(
str
,delim
,count
)
Returns the substring from string str
before count
occurrences of the delimiter delim
. If count
is positive, everything to the left of the final delimiter (counting from the left) is returned. If count
is negative, everything to the right of the final delimiter (counting from the right) is returned. SUBSTRING_INDEX()
performs a case-sensitive match when searching for delim
.
mysql> -> 'www.mysql' mysql> -> 'mysql.com' SELECT SUBSTRING_INDEX('www.mysql.com', '.', 2);SELECT SUBSTRING_INDEX('www.mysql.com', '.', -2);
This function is multibyte safe.
Converts the string argument to base-64 encoded form and returns the result as a character string with the connection character set and collation. If the argument is not a string, it is converted to a string before conversion takes place. The result is NULL
if the argument is NULL
. Base-64 encoded strings can be decoded using the FROM_BASE64()
function.
mysql> -> 'JWJj', 'abc' SELECT TO_BASE64('abc'), FROM_BASE64(TO_BASE64('abc'));
Different base-64 encoding schemes exist. These are the encoding and decoding rules used by TO_BASE64()
and FROM_BASE64()
:
The encoding for alphabet value 62 is '+'
.
The encoding for alphabet value 63 is '/'
.
Encoded output consists of groups of 4 printable characters. Each 3 bytes of the input data are encoded using 4 characters. If the last group is incomplete, it is padded with '='
characters to a length of 4.
A newline is added after each 76 characters of encoded output to divide long output into multiple lines.
Decoding recognizes and ignores newline, carriage return, tab, and space.
TRIM([{BOTH | LEADING | TRAILING} [
, remstr
] FROM] str
)TRIM([
remstr
FROM] str
)
Returns the string str
with all remstr
prefixes or suffixes removed. If none of the specifiers BOTH
, LEADING
, or TRAILING
is given, BOTH
is assumed. remstr
is optional and, if not specified, spaces are removed.
mysql> -> 'bar' mysql> -> 'barxxx' mysql> -> 'bar' mysql> -> 'barx' SELECT TRIM(' bar ');SELECT TRIM(LEADING 'x' FROM 'xxxbarxxx');SELECT TRIM(BOTH 'x' FROM 'xxxbarxxx');SELECT TRIM(TRAILING 'xyz' FROM 'barxxyz');
This function is multibyte safe.
UCASE()
is a synonym for UPPER()
.
UCASE()
used within views is rewritten as UPPER()
.
For a string argument str
, UNHEX(
interprets each pair of characters in the argument as a hexadecimal number and converts it to the byte represented by the number. The return value is a binary string.str
)
mysql> -> 'MySQL' mysql> -> 'MySQL' mysql> -> 'string' mysql> -> '1267' SELECT UNHEX('4D7953514C');SELECT X'4D7953514C';SELECT UNHEX(HEX('string'));SELECT HEX(UNHEX('1267'));
The characters in the argument string must be legal hexadecimal digits: '0'
.. '9'
, 'A'
.. 'F'
, 'a'
.. 'f'
. If the argument contains any nonhexadecimal digits, the result is NULL
:
mysql> +-------------+ | UNHEX('GG') | +-------------+ | NULL | +-------------+ SELECT UNHEX('GG');
A NULL
result can occur if the argument to UNHEX()
is a BINARY
column, because values are padded with 0x00 bytes when stored but those bytes are not stripped on retrieval. For example, '41'
is stored into a CHAR(3)
column as '41 '
and retrieved as '41'
(with the trailing pad space stripped), so UNHEX()
for the column value returns 'A'
. By contrast '41'
is stored into a BINARY(3)
column as '41\0'
and retrieved as '41\0'
(with the trailing pad 0x00
byte not stripped). '\0'
is not a legal hexadecimal digit, so UNHEX()
for the column value returns NULL
.
For a numeric argument N
, the inverse of HEX(
is not performed by N
)UNHEX()
. Use CONV(HEX(
instead. See the description of N
),16,10)HEX()
.
Returns the string str
with all characters changed to uppercase according to the current character set mapping. The default is utf8mb4
.
mysql> -> 'HEJ' SELECT UPPER('Hej');
See the description of LOWER()
for information that also applies to UPPER()
. This included information about how to perform lettercase conversion of binary strings (BINARY
, VARBINARY
, BLOB
) for which these functions are ineffective, and information about case folding for Unicode character sets.
This function is multibyte safe.
UCASE()
used within views is rewritten as UPPER()
.
WEIGHT_STRING(
str
[AS {CHAR|BINARY}(N
)] [flags
])
This function returns the weight string for the input string. The return value is a binary string that represents the comparison and sorting value of the string. It has these properties:
If WEIGHT_STRING(
= str1
)WEIGHT_STRING(
, then str2
)
(str1
= str2
str1
and str2
are considered equal)
If WEIGHT_STRING(
< str1
)WEIGHT_STRING(
, then str2
)
(str1
< str2
str1
sorts before str2
)
WEIGHT_STRING()
is a debugging function intended for internal use. Its behavior can change without notice between MySQL versions. It can be used for testing and debugging of collations, especially if you are adding a new collation. See Section 10.13, 「Adding a Collation to a Character Set」.
This list briefly summarizes the arguments. More details are given in the discussion following the list.
str
: The input string expression.
AS
clause: Optional; cast the input string to a given type and length.
flags
: Optional; unused.
The input string, str
, is a string expression. If the input is a nonbinary (character) string such as a CHAR
, VARCHAR
, or TEXT
value, the return value contains the collation weights for the string. If the input is a binary (byte) string such as a BINARY
, VARBINARY
, or BLOB
value, the return value is the same as the input (the weight for each byte in a binary string is the byte value). If the input is NULL
, WEIGHT_STRING()
returns NULL
.
Examples:
mysql> mysql> +------+---------+------------------------+ | @s | HEX(@s) | HEX(WEIGHT_STRING(@s)) | +------+---------+------------------------+ | AB | 4142 | 1C471C60 | +------+---------+------------------------+ SET @s = _utf8mb4 'AB' COLLATE utf8mb4_0900_ai_ci;SELECT @s, HEX(@s), HEX(WEIGHT_STRING(@s));
mysql> mysql> +------+---------+------------------------+ | @s | HEX(@s) | HEX(WEIGHT_STRING(@s)) | +------+---------+------------------------+ | ab | 6162 | 1C471C60 | +------+---------+------------------------+ SET @s = _utf8mb4 'ab' COLLATE utf8mb4_0900_ai_ci;SELECT @s, HEX(@s), HEX(WEIGHT_STRING(@s));
mysql> mysql> +------+---------+------------------------+ | @s | HEX(@s) | HEX(WEIGHT_STRING(@s)) | +------+---------+------------------------+ | AB | 4142 | 4142 | +------+---------+------------------------+ SET @s = CAST('AB' AS BINARY);SELECT @s, HEX(@s), HEX(WEIGHT_STRING(@s));
mysql> mysql> +------+---------+------------------------+ | @s | HEX(@s) | HEX(WEIGHT_STRING(@s)) | +------+---------+------------------------+ | ab | 6162 | 6162 | +------+---------+------------------------+ SET @s = CAST('ab' AS BINARY);SELECT @s, HEX(@s), HEX(WEIGHT_STRING(@s));
The preceding examples use HEX()
to display the WEIGHT_STRING()
result. Because the result is a binary value, HEX()
can be especially useful when the result contains nonprinting values, to display it in printable form:
mysql> mysql> +------------------------+ | HEX(WEIGHT_STRING(@s)) | +------------------------+ | 0FEA0FEA | +------------------------+ SET @s = CONVERT(X'C39F' USING utf8) COLLATE utf8_czech_ci;SELECT HEX(WEIGHT_STRING(@s));
For non-NULL
return values, the data type of the value is VARBINARY
if its length is within the maximum length for VARBINARY
, otherwise the data type is BLOB
.
The AS
clause may be given to cast the input string to a nonbinary or binary string and to force it to a given length:
AS CHAR(
casts the string to a nonbinary string and pads it on the right with spaces to a length of N
)N
characters. N
must be at least 1. If N
is less than the length of the input string, the string is truncated to N
characters. No warning occurs for truncation.
AS BINARY(
is similar but casts the string to a binary string, N
)N
is measured in bytes (not characters), and padding uses 0x00
bytes (not spaces).
mysql> mysql> +-------------------------------------+ | HEX(WEIGHT_STRING('ab' AS CHAR(4))) | +-------------------------------------+ | 41422020 | +-------------------------------------+ mysql> mysql> +-------------------------------------+ | HEX(WEIGHT_STRING('ab' AS CHAR(4))) | +-------------------------------------+ | 0041004200200020 | +-------------------------------------+ SET NAMES 'latin1';SELECT HEX(WEIGHT_STRING('ab' AS CHAR(4)));SET NAMES 'utf8';SELECT HEX(WEIGHT_STRING('ab' AS CHAR(4)));
mysql> +---------------------------------------+ | HEX(WEIGHT_STRING('ab' AS BINARY(4))) | +---------------------------------------+ | 61620000 | +---------------------------------------+ SELECT HEX(WEIGHT_STRING('ab' AS BINARY(4)));
The flags
clause currently is unused.
If a string function is given a binary string as an argument, the resulting string is also a binary string. A number converted to a string is treated as a binary string. This affects only comparisons.
Normally, if any expression in a string comparison is case sensitive, the comparison is performed in case-sensitive fashion.
expr
LIKE pat
[ESCAPE 'escape_char
']
Pattern matching using an SQL pattern. Returns 1
(TRUE
) or 0
(FALSE
). If either expr
or pat
is NULL
, the result is NULL
.
The pattern need not be a literal string. For example, it can be specified as a string expression or table column.
Per the SQL standard, LIKE
performs matching on a per-character basis, thus it can produce results different from the =
comparison operator:
mysql> +-----------------------------------------+ | 'ä' LIKE 'ae' COLLATE latin1_german2_ci | +-----------------------------------------+ | 0 | +-----------------------------------------+ mysql> +--------------------------------------+ | 'ä' = 'ae' COLLATE latin1_german2_ci | +--------------------------------------+ | 1 | +--------------------------------------+ SELECT 'ä' LIKE 'ae' COLLATE latin1_german2_ci;SELECT 'ä' = 'ae' COLLATE latin1_german2_ci;
In particular, trailing spaces are significant, which is not true for CHAR
or VARCHAR
comparisons performed with the =
operator:
mysql> +------------+---------------+ | 'a' = 'a ' | 'a' LIKE 'a ' | +------------+---------------+ | 1 | 0 | +------------+---------------+ 1 row in set (0.00 sec) SELECT 'a' = 'a ', 'a' LIKE 'a ';
With LIKE
you can use the following two wildcard characters in the pattern:
%
matches any number of characters, even zero characters.
_
matches exactly one character.
mysql> -> 1 mysql> -> 1 SELECT 'David!' LIKE 'David_';SELECT 'David!' LIKE '%D%v%';
To test for literal instances of a wildcard character, precede it by the escape character. If you do not specify the ESCAPE
character, \
is assumed.
\%
matches one %
character.
\_
matches one _
character.
mysql> -> 0 mysql> -> 1 SELECT 'David!' LIKE 'David\_';SELECT 'David_' LIKE 'David\_';
To specify a different escape character, use the ESCAPE
clause:
mysql> -> 1 SELECT 'David_' LIKE 'David|_' ESCAPE '|';
The escape sequence should be empty or one character long. The expression must evaluate as a constant at execution time. If the NO_BACKSLASH_ESCAPES
SQL mode is enabled, the sequence cannot be empty.
The following two statements illustrate that string comparisons are not case-sensitive unless one of the operands is case-sensitive (uses a case-sensitive collation or is a binary string):
mysql> -> 1 mysql> -> 0 mysql> -> 0 mysql> -> 0 SELECT 'abc' LIKE 'ABC';SELECT 'abc' LIKE _utf8mb4 'ABC' COLLATE utf8mb4_0900_as_cs;SELECT 'abc' LIKE _utf8mb4 'ABC' COLLATE utf8mb4_bin;SELECT 'abc' LIKE BINARY 'ABC';
As an extension to standard SQL, MySQL permits LIKE
on numeric expressions.
mysql> -> 1 SELECT 10 LIKE '1%';
Because MySQL uses C escape syntax in strings (for example, \n
to represent a newline character), you must double any \
that you use in LIKE
strings. For example, to search for \n
, specify it as \\n
. To search for \
, specify it as \\\\
; this is because the backslashes are stripped once by the parser and again when the pattern match is made, leaving a single backslash to be matched against.
Exception: At the end of the pattern string, backslash can be specified as \\
. At the end of the string, backslash stands for itself because there is nothing following to escape. Suppose that a table contains the following values:
mysql> +--------------+ | filename | +--------------+ | C: | | C:\ | | C:\Programs | | C:\Programs\ | +--------------+ SELECT filename FROM t1;
To test for values that end with backslash, you can match the values using either of the following patterns:
mysql> +--------------+---------------------+ | filename | filename LIKE '%\\' | +--------------+---------------------+ | C: | 0 | | C:\ | 1 | | C:\Programs | 0 | | C:\Programs\ | 1 | +--------------+---------------------+ mysql> +--------------+-----------------------+ | filename | filename LIKE '%\\\\' | +--------------+-----------------------+ | C: | 0 | | C:\ | 1 | | C:\Programs | 0 | | C:\Programs\ | 1 | +--------------+-----------------------+ SELECT filename, filename LIKE '%\\' FROM t1;SELECT filename, filename LIKE '%\\\\' FROM t1;
expr
NOT LIKE pat
[ESCAPE 'escape_char
']
This is the same as NOT (
.expr
LIKE pat
[ESCAPE 'escape_char
'])
Aggregate queries involving NOT LIKE
comparisons with columns containing NULL
may yield unexpected results. For example, consider the following table and data:
CREATE TABLE foo (bar VARCHAR(10)); INSERT INTO foo VALUES (NULL), (NULL);
The query SELECT COUNT(*) FROM foo WHERE bar LIKE '%baz%';
returns 0
. You might assume that SELECT COUNT(*) FROM foo WHERE bar NOT LIKE '%baz%';
would return 2
. However, this is not the case: The second query returns 0
. This is because NULL NOT LIKE
always returns expr
NULL
, regardless of the value of expr
. The same is true for aggregate queries involving NULL
and comparisons using NOT RLIKE
or NOT REGEXP
. In such cases, you must test explicitly for NOT NULL
using OR
(and not AND
), as shown here:
SELECT COUNT(*) FROM foo WHERE bar NOT LIKE '%baz%' OR bar IS NULL;
STRCMP()
returns 0
if the strings are the same, -1
if the first argument is smaller than the second according to the current sort order, and 1
otherwise.
mysql> -> -1 mysql> -> 1 mysql> -> 0 SELECT STRCMP('text', 'text2');SELECT STRCMP('text2', 'text');SELECT STRCMP('text', 'text');
STRCMP()
performs the comparison using the collation of the arguments.
mysql> mysql> mysql> mysql> mysql> +------------------+------------------+ | STRCMP(@s1, @s2) | STRCMP(@s3, @s4) | +------------------+------------------+ | 0 | -1 | +------------------+------------------+ SET @s1 = _utf8mb4 'x' COLLATE utf8mb4_0900_ai_ci;SET @s2 = _utf8mb4 'X' COLLATE utf8mb4_0900_ai_ci;SET @s3 = _utf8mb4 'x' COLLATE utf8mb4_0900_as_cs;SET @s4 = _utf8mb4 'X' COLLATE utf8mb4_0900_as_cs;SELECT STRCMP(@s1, @s2), STRCMP(@s3, @s4);
If the collations are incompatible, one of the arguments must be converted to be compatible with the other. See Section 10.8.4, 「Collation Coercibility in Expressions」.
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> ERROR 1267 (HY000): Illegal mix of collations (utf8mb4_0900_ai_ci,IMPLICIT) and (utf8mb4_0900_as_cs,IMPLICIT) for operation 'strcmp' mysql> +---------------------------------------------+ | STRCMP(@s1, @s3 COLLATE utf8mb4_0900_ai_ci) | +---------------------------------------------+ | 0 | +---------------------------------------------+ SELECT STRCMP(@s1, @s3);SELECT STRCMP(@s1, @s3 COLLATE utf8mb4_0900_ai_ci);
Table 12.9 Regular Expression Functions and Operators
Name | Description |
---|---|
NOT REGEXP |
Negation of REGEXP |
REGEXP |
Whether string matches regular expression |
REGEXP_INSTR() |
Starting index of substring matching regular expression |
REGEXP_LIKE() |
Whether string matches regular expression |
REGEXP_REPLACE() |
Replace substrings matching regular expression |
REGEXP_SUBSTR() |
Return substring matching regular expression |
RLIKE |
Whether string matches regular expression |
A regular expression is a powerful way of specifying a pattern for a complex search. This section discusses the functions and operators available for regular expression matching and illustrates, with examples, some of the special characters and constructs that can be used for regular expression operations. See also Section 3.3.4.7, 「Pattern Matching」.
MySQL implements regular expression support using International Components for Unicode (ICU), which provides full Unicode support and is multibyte safe. (Prior to MySQL 8.0.4, MySQL used Henry Spencer's implementation of regular expressions, which operates in byte-wise fashion and is not multibyte safe. For information about ways in which applications that use regular expressions may be affected by the implementation change, see Regular Expression Compatibility Considerations.)
, expr
NOT REGEXP pat
expr
NOT RLIKE pat
This is the same as NOT (
. expr
REGEXP pat
)
, expr
REGEXP pat
expr
RLIKE pat
Returns 1 if the string expr
matches the regular expression specified by the pattern pat
, 0 otherwise. If expr
or pat
is NULL
, the return value is NULL
.
REGEXP
and RLIKE
are synonyms for REGEXP_LIKE()
.
For additional information about how matching occurs, see the description for REGEXP_LIKE()
.
mysql> +------------------------+ | 'Michael!' REGEXP '.*' | +------------------------+ | 1 | +------------------------+ mysql> +---------------------------------------+ | 'new*\n*line' REGEXP 'new\\*.\\*line' | +---------------------------------------+ | 0 | +---------------------------------------+ mysql> +---------------------+ | 'a' REGEXP '^[a-d]' | +---------------------+ | 1 | +---------------------+ mysql> +----------------+-----------------------+ | 'a' REGEXP 'A' | 'a' REGEXP BINARY 'A' | +----------------+-----------------------+ | 1 | 0 | +----------------+-----------------------+ SELECT 'Michael!' REGEXP '.*';SELECT 'new*\n*line' REGEXP 'new\\*.\\*line';SELECT 'a' REGEXP '^[a-d]';SELECT 'a' REGEXP 'A', 'a' REGEXP BINARY 'A';
REGEXP_INSTR(
expr
, pat
[, pos
[, occurrence
[, return_option
[, match_type
]]]])
Returns the starting index of the substring of the string expr
that matches the regular expression specified by the pattern pat
, 0 if there is no match. If expr
or pat
is NULL
, the return value is NULL
. Character indexes begin at 1.
REGEXP_INSTR()
takes these optional arguments:
pos
: The position in expr
at which to start the search. If omitted, the default is 1.
occurrence
: Which occurrence of a match to search for. If omitted, the default is 1.
return_option
: Which type of position to return. If this value is 0, REGEXP_INSTR()
returns the position of the matched substring's first character. If this value is 1, REGEXP_INSTR()
returns the position following the matched substring. If omitted, the default is 0.
match_type
: A string that specifies how to perform matching. The meaning is as described for REGEXP_LIKE()
.
For additional information about how matching occurs, see the description for REGEXP_LIKE()
.
mysql> +------------------------------------+ | REGEXP_INSTR('dog cat dog', 'dog') | +------------------------------------+ | 1 | +------------------------------------+ mysql> +---------------------------------------+ | REGEXP_INSTR('dog cat dog', 'dog', 2) | +---------------------------------------+ | 9 | +---------------------------------------+ mysql> +-------------------------------------+ | REGEXP_INSTR('aa aaa aaaa', 'a{2}') | +-------------------------------------+ | 1 | +-------------------------------------+ mysql> +-------------------------------------+ | REGEXP_INSTR('aa aaa aaaa', 'a{4}') | +-------------------------------------+ | 8 | +-------------------------------------+ SELECT REGEXP_INSTR('dog cat dog', 'dog');SELECT REGEXP_INSTR('dog cat dog', 'dog', 2);SELECT REGEXP_INSTR('aa aaa aaaa', 'a{2}');SELECT REGEXP_INSTR('aa aaa aaaa', 'a{4}');
REGEXP_LIKE(
expr
, pat
[, match_type
])
Returns 1 if the string expr
matches the regular expression specified by the pattern pat
, 0 otherwise. If expr
or pat
is NULL
, the return value is NULL
.
The pattern can be an extended regular expression, the syntax for which is discussed in Regular Expression Syntax. The pattern need not be a literal string. For example, it can be specified as a string expression or table column.
The optional match_type
argument is a string that may contain any or all the following characters specifying how to perform matching:
c
: Case sensitive matching.
i
: Case insensitive matching.
m
: Multiple-line mode. Recognize line terminators within the string. The default behavior is to match line terminators only at the start and end of the string expression.
n
: The .
character matches line terminators. The default is for .
matching to stop at the end of a line.
u
: Unix-only line endings. Only the newline character is recognized as a line ending by the .
, ^
, and $
match operators.
If characters specifying contradictory options are specified within match_type
, the rightmost one takes precedence.
By default, regular expression operations use the character set and collation of the expr
and pat
arguments when deciding the type of a character and performing the comparison. If the arguments have different character sets or collations, coercibility rules apply as described in Section 10.8.4, 「Collation Coercibility in Expressions」. Arguments may be specified with explicit collation indicators to change comparison behavior.
mysql> +---------------------------------------+ | REGEXP_LIKE('CamelCase', 'CAMELCASE') | +---------------------------------------+ | 1 | +---------------------------------------+ mysql> +------------------------------------------------------------------+ | REGEXP_LIKE('CamelCase', 'CAMELCASE' COLLATE utf8mb4_0900_as_cs) | +------------------------------------------------------------------+ | 0 | +------------------------------------------------------------------+ SELECT REGEXP_LIKE('CamelCase', 'CAMELCASE');SELECT REGEXP_LIKE('CamelCase', 'CAMELCASE' COLLATE utf8mb4_0900_as_cs);
match_type
may be specified with the c
or i
characters to override the default case sensitivity. Exception: If either argument is a binary string, the arguments are handled in case-sensitive fashion as binary strings, even if match_type
contains the i
character.
Because MySQL uses the C escape syntax in strings (for example, \n
to represent the newline character), you must double any \
that you use in your expr
and pat
arguments.
mysql> +-------------------------------+ | REGEXP_LIKE('Michael!', '.*') | +-------------------------------+ | 1 | +-------------------------------+ mysql> +----------------------------------------------+ | REGEXP_LIKE('new*\n*line', 'new\\*.\\*line') | +----------------------------------------------+ | 0 | +----------------------------------------------+ mysql> +----------------------------+ | REGEXP_LIKE('a', '^[a-d]') | +----------------------------+ | 1 | +----------------------------+ mysql> +-----------------------+------------------------------+ | REGEXP_LIKE('a', 'A') | REGEXP_LIKE('a', BINARY 'A') | +-----------------------+------------------------------+ | 1 | 0 | +-----------------------+------------------------------+ SELECT REGEXP_LIKE('Michael!', '.*');SELECT REGEXP_LIKE('new*\n*line', 'new\\*.\\*line');SELECT REGEXP_LIKE('a', '^[a-d]');SELECT REGEXP_LIKE('a', 'A'), REGEXP_LIKE('a', BINARY 'A');
mysql> +---------------------------+ | REGEXP_LIKE('abc', 'ABC') | +---------------------------+ | 1 | +---------------------------+ mysql> +--------------------------------+ | REGEXP_LIKE('abc', 'ABC', 'c') | +--------------------------------+ | 0 | +--------------------------------+ SELECT REGEXP_LIKE('abc', 'ABC');SELECT REGEXP_LIKE('abc', 'ABC', 'c');
REGEXP_REPLACE(
expr
, pat
, repl
[, pos
[, occurrence
[, match_type
]]])
Replaces occurrences in the string expr
that match the regular expression specified by the pattern pat
with the replacement string repl
, and returns the resulting string. If expr
, pat
, or repl
is NULL
, the return value is NULL
.
REGEXP_REPLACE()
takes these optional arguments:
pos
: The position in expr
at which to start the search. If omitted, the default is 1.
occurrence
: Which occurrence of a match to replace. If omitted, the default is 0 (which means 「replace all occurrences」).
match_type
: A string that specifies how to perform matching. The meaning is as described for REGEXP_LIKE()
.
Prior to MySQL 8.0.17, the result returned by this function used the UTF-16
character set; in MySQL 8.0.17 and later, the character set and collation of the expression searched for matches is used. (Bug #94203, Bug #29308212)
For additional information about how matching occurs, see the description for REGEXP_LIKE()
.
mysql> +-----------------------------------+ | REGEXP_REPLACE('a b c', 'b', 'X') | +-----------------------------------+ | a X c | +-----------------------------------+ mysql> +----------------------------------------------------+ | REGEXP_REPLACE('abc def ghi', '[a-z]+', 'X', 1, 3) | +----------------------------------------------------+ | abc def X | +----------------------------------------------------+ SELECT REGEXP_REPLACE('a b c', 'b', 'X');SELECT REGEXP_REPLACE('abc def ghi', '[a-z]+', 'X', 1, 3);
REGEXP_SUBSTR(
expr
, pat
[, pos
[, occurrence
[, match_type
]]])
Returns the substring of the string expr
that matches the regular expression specified by the pattern pat
, NULL
if there is no match. If expr
or pat
is NULL
, the return value is NULL
.
REGEXP_SUBSTR()
takes these optional arguments:
pos
: The position in expr
at which to start the search. If omitted, the default is 1.
occurrence
: Which occurrence of a match to search for. If omitted, the default is 1.
match_type
: A string that specifies how to perform matching. The meaning is as described for REGEXP_LIKE()
.
Prior to MySQL 8.0.17, the result returned by this function used the UTF-16
character set; in MySQL 8.0.17 and later, the character set and collation of the expression searched for matches is used. (Bug #94203, Bug #29308212)
For additional information about how matching occurs, see the description for REGEXP_LIKE()
.
mysql> +----------------------------------------+ | REGEXP_SUBSTR('abc def ghi', '[a-z]+') | +----------------------------------------+ | abc | +----------------------------------------+ mysql> +----------------------------------------------+ | REGEXP_SUBSTR('abc def ghi', '[a-z]+', 1, 3) | +----------------------------------------------+ | ghi | +----------------------------------------------+ SELECT REGEXP_SUBSTR('abc def ghi', '[a-z]+');SELECT REGEXP_SUBSTR('abc def ghi', '[a-z]+', 1, 3);
A regular expression describes a set of strings. The simplest regular expression is one that has no special characters in it. For example, the regular expression hello
matches hello
and nothing else.
Nontrivial regular expressions use certain special constructs so that they can match more than one string. For example, the regular expression hello|world
contains the |
alternation operator and matches either the hello
or world
.
As a more complex example, the regular expression B[an]*s
matches any of the strings Bananas
, Baaaaas
, Bs
, and any other string starting with a B
, ending with an s
, and containing any number of a
or n
characters in between.
The following list covers some of the basic special characters and constructs that can be used in regular expressions. For information about the full regular expression syntax supported by the ICU library used to implement regular expression support, visit the International Components for Unicode website.
^
Match the beginning of a string.
mysql> -> 0 mysql> -> 1 SELECT REGEXP_LIKE('fo\nfo', '^fo$');SELECT REGEXP_LIKE('fofo', '^fo');
$
Match the end of a string.
mysql> -> 1 mysql> -> 0 SELECT REGEXP_LIKE('fo\no', '^fo\no$');SELECT REGEXP_LIKE('fo\no', '^fo$');
.
Match any character (including carriage return and newline, although to match these in the middle of a string, the m
(multiple line) match-control character or the (?m)
within-pattern modifier must be given).
mysql> -> 1 mysql> -> 0 mysql> -> 1 mysql> -> 1 SELECT REGEXP_LIKE('fofo', '^f.*$');SELECT REGEXP_LIKE('fo\r\nfo', '^f.*$');SELECT REGEXP_LIKE('fo\r\nfo', '^f.*$', 'm');SELECT REGEXP_LIKE('fo\r\nfo', '(?m)^f.*$');
a*
Match any sequence of zero or more a
characters.
mysql> -> 1 mysql> -> 1 mysql> -> 1 SELECT REGEXP_LIKE('Ban', '^Ba*n');SELECT REGEXP_LIKE('Baaan', '^Ba*n');SELECT REGEXP_LIKE('Bn', '^Ba*n');
a+
Match any sequence of one or more a
characters.
mysql> -> 1 mysql> -> 0 SELECT REGEXP_LIKE('Ban', '^Ba+n');SELECT REGEXP_LIKE('Bn', '^Ba+n');
a?
Match either zero or one a
character.
mysql> -> 1 mysql> -> 1 mysql> -> 0 SELECT REGEXP_LIKE('Bn', '^Ba?n');SELECT REGEXP_LIKE('Ban', '^Ba?n');SELECT REGEXP_LIKE('Baan', '^Ba?n');
de|abc
Alternation; match either of the sequences de
or abc
.
mysql> -> 1 mysql> -> 0 mysql> -> 1 mysql> -> 1 mysql> -> 1 mysql> -> 0 SELECT REGEXP_LIKE('pi', 'pi|apa');SELECT REGEXP_LIKE('axe', 'pi|apa');SELECT REGEXP_LIKE('apa', 'pi|apa');SELECT REGEXP_LIKE('apa', '^(pi|apa)$');SELECT REGEXP_LIKE('pi', '^(pi|apa)$');SELECT REGEXP_LIKE('pix', '^(pi|apa)$');
(abc)*
Match zero or more instances of the sequence abc
.
mysql> -> 1 mysql> -> 0 mysql> -> 1 SELECT REGEXP_LIKE('pi', '^(pi)*$');SELECT REGEXP_LIKE('pip', '^(pi)*$');SELECT REGEXP_LIKE('pipi', '^(pi)*$');
{1}
, {2,3}
Repetition; {
and n
}{
notation provide a more general way of writing regular expressions that match many occurrences of the previous atom (or 「piece」) of the pattern. m
,n
}m
and n
are integers.
a*
Can be written as a{0,}
.
a+
Can be written as a{1,}
.
a?
Can be written as a{0,1}
.
To be more precise, a{
matches exactly n
}n
instances of a
. a{
matches n
,}n
or more instances of a
. a{
matches m
,n
}m
through n
instances of a
, inclusive. If both m
and n
are given, m
must be less than or equal to n
.
mysql> -> 0 mysql> -> 1 mysql> -> 1 SELECT REGEXP_LIKE('abcde', 'a[bcd]{2}e');SELECT REGEXP_LIKE('abcde', 'a[bcd]{3}e');SELECT REGEXP_LIKE('abcde', 'a[bcd]{1,10}e');
[a-dX]
, [^a-dX]
Matches any character that is (or is not, if ^
is used) either a
, b
, c
, d
or X
. A -
character between two other characters forms a range that matches all characters from the first character to the second. For example, [0-9]
matches any decimal digit. To include a literal ]
character, it must immediately follow the opening bracket [
. To include a literal -
character, it must be written first or last. Any character that does not have a defined special meaning inside a []
pair matches only itself.
mysql> -> 1 mysql> -> 0 mysql> -> 1 mysql> -> 0 mysql> -> 1 mysql> -> 0 SELECT REGEXP_LIKE('aXbc', '[a-dXYZ]');SELECT REGEXP_LIKE('aXbc', '^[a-dXYZ]$');SELECT REGEXP_LIKE('aXbc', '^[a-dXYZ]+$');SELECT REGEXP_LIKE('aXbc', '^[^a-dXYZ]+$');SELECT REGEXP_LIKE('gheis', '^[^a-dXYZ]+$');SELECT REGEXP_LIKE('gheisa', '^[^a-dXYZ]+$');
[=character_class=]
Within a bracket expression (written using [
and ]
), [=character_class=]
represents an equivalence class. It matches all characters with the same collation value, including itself. For example, if o
and (+)
are the members of an equivalence class, [[=o=]]
, [[=(+)=]]
, and [o(+)]
are all synonymous. An equivalence class may not be used as an endpoint of a range.
[:character_class:]
Within a bracket expression (written using [
and ]
), [:character_class:]
represents a character class that matches all characters belonging to that class. The following table lists the standard class names. These names stand for the character classes defined in the ctype(3)
manual page. A particular locale may provide other class names. A character class may not be used as an endpoint of a range.
Character Class Name | Meaning |
---|---|
alnum |
Alphanumeric characters |
alpha |
Alphabetic characters |
blank |
Whitespace characters |
cntrl |
Control characters |
digit |
Digit characters |
graph |
Graphic characters |
lower |
Lowercase alphabetic characters |
print |
Graphic or space characters |
punct |
Punctuation characters |
space |
Space, tab, newline, and carriage return |
upper |
Uppercase alphabetic characters |
xdigit |
Hexadecimal digit characters |
mysql> -> 1 mysql> -> 0 SELECT REGEXP_LIKE('justalnums', '[[:alnum:]]+');SELECT REGEXP_LIKE('!!', '[[:alnum:]]+');
To use a literal instance of a special character in a regular expression, precede it by two backslash (\) characters. The MySQL parser interprets one of the backslashes, and the regular expression library interprets the other. For example, to match the string 1+2
that contains the special +
character, only the last of the following regular expressions is the correct one:
mysql> -> 0 mysql> -> 0 mysql> -> 1 SELECT REGEXP_LIKE('1+2', '1+2');SELECT REGEXP_LIKE('1+2', '1\+2');SELECT REGEXP_LIKE('1+2', '1\\+2');
REGEXP_LIKE()
and similar functions use resources that can be controlled by setting system variables:
The match engine uses memory for its internal stack. To control the maximum available memory for the stack in bytes, set the regexp_stack_limit
system variable.
The match engine operates in steps. To control the maximum number of steps performed by the engine (and thus indirectly the execution time), set the regexp_time_limit
system variable. Because this limit is expressed as number of steps, it affects execution time only indirectly. Typically, it is on the order of milliseconds.
Prior to MySQL 8.0.4, MySQL used the Henry Spencer regular expression library to support regular expression operations, rather than International Components for Unicode (ICU). The following discussion describes differences between the Spencer and ICU libraries that may affect applications:
With the Spencer library, the REGEXP
and RLIKE
operators work in byte-wise fashion, so they are not multibyte safe and may produce unexpected results with multibyte character sets. In addition, these operators compare characters by their byte values and accented characters may not compare as equal even if a given collation treats them as equal.
ICU has full Unicode support and is multibyte safe. Its regular expression functions treat all strings as UTF-16
. You should keep in mind that positional indexes are based on 16-bit chunks and not on code points. This means that, when passed to such functions, characters using more than one chunk may produce unanticipated results, such as those shown here:
mysql> +--------------------------+ | REGEXP_INSTR('??b', 'b') | +--------------------------+ | 5 | +--------------------------+ 1 row in set (0.00 sec) mysql> +--------------------------------+ | REGEXP_INSTR('??bxxx', 'b', 4) | +--------------------------------+ | 5 | +--------------------------------+ 1 row in set (0.00 sec) SELECT REGEXP_INSTR('🍣🍣b', 'b');SELECT REGEXP_INSTR('🍣🍣bxxx', 'b', 4);
Characters within the Unicode Basic Multilingual Plane, which includes characters used by most modern languages, are safe in this regard:
mysql> +----------------------------+ | REGEXP_INSTR('бжb', 'b') | +----------------------------+ | 3 | +----------------------------+ 1 row in set (0.00 sec) mysql> +----------------------------+ | REGEXP_INSTR('עבb', 'b') | +----------------------------+ | 3 | +----------------------------+ 1 row in set (0.00 sec) mysql> +------------------------------------+ | REGEXP_INSTR('µå周çб', '周') | +------------------------------------+ | 3 | +------------------------------------+ 1 row in set (0.00 sec) SELECT REGEXP_INSTR('бжb', 'b');SELECT REGEXP_INSTR('עבb', 'b');SELECT REGEXP_INSTR('µå周çб', '周');
Emoji, such as the 「sushi」 character 🍣
(U+1F363) used in the first two examples, are not included in the Basic Multilingual Plane, but rather in Unicode's Supplementary Multilingual Plane. Another issue can arise with emoji and other 4-byte characters when REGEXP_SUBSTR()
or a similar function begins searching in the middle of a character. Each of the two statements in the following example starts from the second 2-byte position in the first argument. The first statement works on a string consisting solely of 2-byte (BMP) characters. The second statement contains 4-byte characters which are incorrectly interpreted in the result because the first two bytes are stripped off and so the remainder of the character data is misaligned.
mysql> +----------------------------------------+ | REGEXP_SUBSTR('週週週週', '.*', 2) | +----------------------------------------+ | 週週周 | +----------------------------------------+ 1 row in set (0.00 sec) mysql> +--------------------------------+ | REGEXP_SUBSTR('????', '.*', 2) | +--------------------------------+ | ?㳟揘㳟揘㳟揘 | +--------------------------------+ 1 row in set (0.00 sec) SELECT REGEXP_SUBSTR('週週週週', '.*', 2);SELECT REGEXP_SUBSTR('🍣🍣🍣🍣', '.*', 2);
For the .
operator, the Spencer library matches line-terminator characters (carriage return, newline) anywhere in string expressions, including in the middle. To match line terminator characters in the middle of strings with ICU, specify the m
match-control character.
The Spencer library supports word-beginning and word-end boundary markers ([[:<:]]
and [[:>:]]
notation). ICU does not. For ICU, you can use \b
to match word boundaries; double the backslash because MySQL interprets it as the escape character within strings.
The Spencer library supports collating element bracket expressions ([.characters.]
notation). ICU does not.
For repetition counts ({n}
and {m,n}
notation), the Spencer library has a maximum of 255. ICU has no such limit, although the maximum number of match engine steps can be limited by setting the regexp_time_limit
system variable.
ICU interprets parentheses as metacharacters. To specify a literal open parenthesis (
in a regular expression, it must be escaped:
mysql> ERROR 3692 (HY000): Mismatched parenthesis in regular expression. mysql> +-------------------------+ | REGEXP_LIKE('(', '\\(') | +-------------------------+ | 1 | +-------------------------+ SELECT REGEXP_LIKE('(', '(');SELECT REGEXP_LIKE('(', '\\(');
MySQL has many operators and functions that return a string. This section answers the question: What is the character set and collation of such a string?
For simple functions that take string input and return a string result as output, the output's character set and collation are the same as those of the principal input value. For example, UPPER(
returns a string with the same character string and collation as X
)X
. The same applies for INSTR()
, LCASE()
, LOWER()
, LTRIM()
, MID()
, REPEAT()
, REPLACE()
, REVERSE()
, RIGHT()
, RPAD()
, RTRIM()
, SOUNDEX()
, SUBSTRING()
, TRIM()
, UCASE()
, and UPPER()
.
The REPLACE()
function, unlike all other functions, always ignores the collation of the string input and performs a case-sensitive comparison.
If a string input or function result is a binary string, the string has the binary
character set and collation. This can be checked by using the CHARSET()
and COLLATION()
functions, both of which return binary
for a binary string argument:
mysql> +---------------------+-----------------------+ | CHARSET(BINARY 'a') | COLLATION(BINARY 'a') | +---------------------+-----------------------+ | binary | binary | +---------------------+-----------------------+ SELECT CHARSET(BINARY 'a'), COLLATION(BINARY 'a');
For operations that combine multiple string inputs and return a single string output, the 「aggregation rules」 of standard SQL apply for determining the collation of the result:
If an explicit COLLATE
occurs, use Y
Y
.
If explicit COLLATE
and Y
COLLATE
occur, raise an error.Z
Otherwise, if all collations are Y
, use Y
.
Otherwise, the result has no collation.
For example, with CASE ... WHEN a THEN b WHEN b THEN c COLLATE
, the resulting collation is X
ENDX
. The same applies for UNION
, ||
, CONCAT()
, ELT()
, GREATEST()
, IF()
, and LEAST()
.
For operations that convert to character data, the character set and collation of the strings that result from the operations are defined by the character_set_connection
and collation_connection
system variables that determine the default connection character set and collation (see Section 10.4, 「Connection Character Sets and Collations」). This applies only to BIN_TO_UUID()
, CAST()
, CONV()
, FORMAT()
, HEX()
, and SPACE()
.
An exception to the preceding priniciple occurs for expressions for virtual generated columns. In such expressions, the table character set is used for BIN_TO_UUID()
, CONV()
, or HEX()
results, regardless of connection character set.
If there is any question about the character set or collation of the result returned by a string function, use the CHARSET()
or COLLATION()
function to find out:
mysql> +----------------+-----------------+-------------------+ | USER() | CHARSET(USER()) | COLLATION(USER()) | +----------------+-----------------+-------------------+ | test@localhost | utf8 | utf8_general_ci | +----------------+-----------------+-------------------+ mysql> +--------------------------+----------------------------+ | CHARSET(COMPRESS('abc')) | COLLATION(COMPRESS('abc')) | +--------------------------+----------------------------+ | binary | binary | +--------------------------+----------------------------+ SELECT USER(), CHARSET(USER()), COLLATION(USER());SELECT CHARSET(COMPRESS('abc')), COLLATION(COMPRESS('abc'));
Table 12.10 Numeric Functions and Operators
Name | Description |
---|---|
ABS() |
Return the absolute value |
ACOS() |
Return the arc cosine |
ASIN() |
Return the arc sine |
ATAN() |
Return the arc tangent |
ATAN2() , ATAN() |
Return the arc tangent of the two arguments |
CEIL() |
Return the smallest integer value not less than the argument |
CEILING() |
Return the smallest integer value not less than the argument |
CONV() |
Convert numbers between different number bases |
COS() |
Return the cosine |
COT() |
Return the cotangent |
CRC32() |
Compute a cyclic redundancy check value |
DEGREES() |
Convert radians to degrees |
DIV |
Integer division |
/ |
Division operator |
EXP() |
Raise to the power of |
FLOOR() |
Return the largest integer value not greater than the argument |
LN() |
Return the natural logarithm of the argument |
LOG() |
Return the natural logarithm of the first argument |
LOG10() |
Return the base-10 logarithm of the argument |
LOG2() |
Return the base-2 logarithm of the argument |
- |
Minus operator |
MOD() |
Return the remainder |
% , MOD |
Modulo operator |
PI() |
Return the value of pi |
+ |
Addition operator |
POW() |
Return the argument raised to the specified power |
POWER() |
Return the argument raised to the specified power |
RADIANS() |
Return argument converted to radians |
RAND() |
Return a random floating-point value |
ROUND() |
Round the argument |
SIGN() |
Return the sign of the argument |
SIN() |
Return the sine of the argument |
SQRT() |
Return the square root of the argument |
TAN() |
Return the tangent of the argument |
* |
Multiplication operator |
TRUNCATE() |
Truncate to specified number of decimal places |
- |
Change the sign of the argument |
The usual arithmetic operators are available. The result is determined according to the following rules:
In the case of -
, +
, and *
, the result is calculated with BIGINT
(64-bit) precision if both operands are integers.
If both operands are integers and any of them are unsigned, the result is an unsigned integer. For subtraction, if the NO_UNSIGNED_SUBTRACTION
SQL mode is enabled, the result is signed even if any operand is unsigned.
If any of the operands of a +
, -
, /
, *
, %
is a real or string value, the precision of the result is the precision of the operand with the maximum precision.
In division performed with /
, the scale of the result when using two exact-value operands is the scale of the first operand plus the value of the div_precision_increment
system variable (which is 4 by default). For example, the result of the expression 5.05 / 0.014
has a scale of six decimal places (360.714286
).
These rules are applied for each operation, such that nested calculations imply the precision of each component. Hence, (14620 / 9432456) / (24250 / 9432456)
, resolves first to (0.0014) / (0.0026)
, with the final result having 8 decimal places (0.60288653
).
Because of these rules and the way they are applied, care should be taken to ensure that components and subcomponents of a calculation use the appropriate level of precision. See Section 12.10, 「Cast Functions and Operators」.
For information about handling of overflow in numeric expression evaluation, see Section 11.2.6, 「Out-of-Range and Overflow Handling」.
Arithmetic operators apply to numbers. For other types of values, alternative operations may be available. For example, to add date values, use DATE_ADD()
; see Section 12.7, 「Date and Time Functions」.
Addition:
mysql> -> 8 SELECT 3+5;
Subtraction:
mysql> -> -2 SELECT 3-5;
Unary minus. This operator changes the sign of the operand.
mysql> -> -2 SELECT - 2;
Multiplication:
mysql> -> 15 mysql> -> 324518553658426726783156020576256.0 mysql> -> out-of-range error SELECT 3*5;SELECT 18014398509481984*18014398509481984.0;SELECT 18014398509481984*18014398509481984;
The last expression produces an error because the result of the integer multiplication exceeds the 64-bit range of BIGINT
calculations. (See Section 11.2, 「Numeric Types」.)
Division:
mysql> -> 0.60 SELECT 3/5;
Division by zero produces a NULL
result:
mysql> -> NULL SELECT 102/(1-1);
A division is calculated with BIGINT
arithmetic only if performed in a context where its result is converted to an integer.
Integer division. Discards from the division result any fractional part to the right of the decimal point.
If either operand has a noninteger type, the operands are converted to DECIMAL
and divided using DECIMAL
arithmetic before converting the result to BIGINT
. If the result exceeds BIGINT
range, an error occurs.
mysql> -> 2, -2, -2, 2 SELECT 5 DIV 2, -5 DIV 2, 5 DIV -2, -5 DIV -2;
Modulo operation. Returns the remainder of N
divided by M
. For more information, see the description for the MOD()
function in Section 12.6.2, 「Mathematical Functions」.
Table 12.12 Mathematical Functions
Name | Description |
---|---|
ABS() |
Return the absolute value |
ACOS() |
Return the arc cosine |
ASIN() |
Return the arc sine |
ATAN() |
Return the arc tangent |
ATAN2() , ATAN() |
Return the arc tangent of the two arguments |
CEIL() |
Return the smallest integer value not less than the argument |
CEILING() |
Return the smallest integer value not less than the argument |
CONV() |
Convert numbers between different number bases |
COS() |
Return the cosine |
COT() |
Return the cotangent |
CRC32() |
Compute a cyclic redundancy check value |
DEGREES() |
Convert radians to degrees |
EXP() |
Raise to the power of |
FLOOR() |
Return the largest integer value not greater than the argument |
LN() |
Return the natural logarithm of the argument |
LOG() |
Return the natural logarithm of the first argument |
LOG10() |
Return the base-10 logarithm of the argument |
LOG2() |
Return the base-2 logarithm of the argument |
MOD() |
Return the remainder |
PI() |
Return the value of pi |
POW() |
Return the argument raised to the specified power |
POWER() |
Return the argument raised to the specified power |
RADIANS() |
Return argument converted to radians |
RAND() |
Return a random floating-point value |
ROUND() |
Round the argument |
SIGN() |
Return the sign of the argument |
SIN() |
Return the sine of the argument |
SQRT() |
Return the square root of the argument |
TAN() |
Return the tangent of the argument |
TRUNCATE() |
Truncate to specified number of decimal places |
All mathematical functions return NULL
in the event of an error.
Returns the absolute value of X
.
mysql> -> 2 mysql> -> 32 SELECT ABS(2);SELECT ABS(-32);
This function is safe to use with BIGINT
values.
Returns the arc cosine of X
, that is, the value whose cosine is X
. Returns NULL
if X
is not in the range -1
to 1
.
mysql> -> 0 mysql> -> NULL mysql> -> 1.5707963267949 SELECT ACOS(1);SELECT ACOS(1.0001);SELECT ACOS(0);
Returns the arc sine of X
, that is, the value whose sine is X
. Returns NULL
if X
is not in the range -1
to 1
.
mysql> -> 0.20135792079033 mysql> +-------------+ | ASIN('foo') | +-------------+ | 0 | +-------------+ 1 row in set, 1 warning (0.00 sec) mysql> +---------+------+-----------------------------------------+ | Level | Code | Message | +---------+------+-----------------------------------------+ | Warning | 1292 | Truncated incorrect DOUBLE value: 'foo' | +---------+------+-----------------------------------------+ SELECT ASIN(0.2);SELECT ASIN('foo');SHOW WARNINGS;
Returns the arc tangent of X
, that is, the value whose tangent is X
.
mysql> -> 1.1071487177941 mysql> -> -1.1071487177941 SELECT ATAN(2);SELECT ATAN(-2);
Returns the arc tangent of the two variables X
and Y
. It is similar to calculating the arc tangent of
, except that the signs of both arguments are used to determine the quadrant of the result.Y
/ X
mysql> -> -0.78539816339745 mysql> -> 1.5707963267949 SELECT ATAN(-2,2);SELECT ATAN2(PI(),0);
Returns the smallest integer value not less than X
.
mysql> -> 2 mysql> -> -1 SELECT CEILING(1.23);SELECT CEILING(-1.23);
For exact-value numeric arguments, the return value has an exact-value numeric type. For string or floating-point arguments, the return value has a floating-point type.
Converts numbers between different number bases. Returns a string representation of the number N
, converted from base from_base
to base to_base
. Returns NULL
if any argument is NULL
. The argument N
is interpreted as an integer, but may be specified as an integer or a string. The minimum base is 2
and the maximum base is 36
. If from_base
is a negative number, N
is regarded as a signed number. Otherwise, N
is treated as unsigned. CONV()
works with 64-bit precision.
mysql> -> '1010' mysql> -> '172' mysql> -> '-H' mysql> -> '40' SELECT CONV('a',16,2);SELECT CONV('6E',18,8);SELECT CONV(-17,10,-18);SELECT CONV(10+'10'+'10'+X'0a',10,10);
Returns the cosine of X
, where X
is given in radians.
mysql> -> -1 SELECT COS(PI());
Returns the cotangent of X
.
mysql> -> -1.5726734063977 mysql> -> out-of-range error SELECT COT(12);SELECT COT(0);
Computes a cyclic redundancy check value and returns a 32-bit unsigned value. The result is NULL
if the argument is NULL
. The argument is expected to be a string and (if possible) is treated as one if it is not.
mysql> -> 3259397556 mysql> -> 2501908538 SELECT CRC32('MySQL');SELECT CRC32('mysql');
Returns the argument X
, converted from radians to degrees.
mysql> -> 180 mysql> -> 90 SELECT DEGREES(PI());SELECT DEGREES(PI() / 2);
Returns the value of e (the base of natural logarithms) raised to the power of X
. The inverse of this function is LOG()
(using a single argument only) or LN()
.
mysql> -> 7.3890560989307 mysql> -> 0.13533528323661 mysql> -> 1 SELECT EXP(2);SELECT EXP(-2);SELECT EXP(0);
Returns the largest integer value not greater than X
.
mysql> -> 1, -2 SELECT FLOOR(1.23), FLOOR(-1.23);
For exact-value numeric arguments, the return value has an exact-value numeric type. For string or floating-point arguments, the return value has a floating-point type.
Formats the number X
to a format like '#,###,###.##'
, rounded to D
decimal places, and returns the result as a string. For details, see Section 12.5, 「String Functions」.
This function can be used to obtain a hexadecimal representation of a decimal number or a string; the manner in which it does so varies according to the argument's type. See this function's description in Section 12.5, 「String Functions」, for details.
Returns the natural logarithm of X
; that is, the base-e logarithm of X
. If X
is less than or equal to 0.0E0, the function returns NULL
and a warning 「Invalid argument for logarithm」 is reported.
mysql> -> 0.69314718055995 mysql> -> NULL SELECT LN(2);SELECT LN(-2);
This function is synonymous with LOG(
. The inverse of this function is the X
)EXP()
function.
If called with one parameter, this function returns the natural logarithm of X
. If X
is less than or equal to 0.0E0, the function returns NULL
and a warning 「Invalid argument for logarithm」 is reported.
The inverse of this function (when called with a single argument) is the EXP()
function.
mysql> -> 0.69314718055995 mysql> -> NULL SELECT LOG(2);SELECT LOG(-2);
If called with two parameters, this function returns the logarithm of X
to the base B
. If X
is less than or equal to 0, or if B
is less than or equal to 1, then NULL
is returned.
mysql> -> 16 mysql> -> 2 mysql> -> NULL SELECT LOG(2,65536);SELECT LOG(10,100);SELECT LOG(1,100);
LOG(
is equivalent to B
,X
)LOG(
.X
) / LOG(B
)
Returns the base-2 logarithm of
. If X
X
is less than or equal to 0.0E0, the function returns NULL
and a warning 「Invalid argument for logarithm」 is reported.
mysql> -> 16 mysql> -> NULL SELECT LOG2(65536);SELECT LOG2(-100);
LOG2()
is useful for finding out how many bits a number requires for storage. This function is equivalent to the expression LOG(
.X
) / LOG(2)
Returns the base-10 logarithm of X
. If X
is less than or equal to 0.0E0, the function returns NULL
and a warning 「Invalid argument for logarithm」 is reported.
mysql> -> 0.30102999566398 mysql> -> 2 mysql> -> NULL SELECT LOG10(2);SELECT LOG10(100);SELECT LOG10(-100);
Modulo operation. Returns the remainder of N
divided by M
.
mysql> -> 4 mysql> -> 1 mysql> -> 2 mysql> -> 2 SELECT MOD(234, 10);SELECT 253 % 7;SELECT MOD(29,9);SELECT 29 MOD 9;
This function is safe to use with BIGINT
values.
MOD()
also works on values that have a fractional part and returns the exact remainder after division:
mysql> -> 1.5 SELECT MOD(34.5,3);
MOD(
returns N
,0)NULL
.
Returns the value of π (pi). The default number of decimal places displayed is seven, but MySQL uses the full double-precision value internally.
mysql> -> 3.141593 mysql> -> 3.141592653589793116 SELECT PI();SELECT PI()+0.000000000000000000;
Returns the value of X
raised to the power of Y
.
mysql> -> 4 mysql> -> 0.25 SELECT POW(2,2);SELECT POW(2,-2);
This is a synonym for POW()
.
Returns the argument X
, converted from degrees to radians. (Note that π radians equals 180 degrees.)
mysql> -> 1.5707963267949 SELECT RADIANS(90);
Returns a random floating-point value v
in the range 0
<= v
< 1.0
. To obtain a random integer R
in the range i
<= R
< j
, use the expression FLOOR(
− i
+ RAND() * (j
. For example, to obtain a random integer in the range the range i
))7
<= R
< 12
, use the following statement:
SELECT FLOOR(7 + (RAND() * 5));
If an integer argument N
is specified, it is used as the seed value:
With a constant initializer argument, the seed is initialized once when the statement is prepared, prior to execution.
With a nonconstant initializer argument (such as a column name), the seed is initialized with the value for each invocation of RAND()
.
One implication of this behavior is that for equal argument values, RAND(
returns the same value each time, and thus produces a repeatable sequence of column values. In the following example, the sequence of values produced by N
)RAND(3)
is the same both places it occurs.
mysql> Query OK, 0 rows affected (0.42 sec) mysql> Query OK, 3 rows affected (0.00 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql> +------+------------------+ | i | RAND() | +------+------------------+ | 1 | 0.61914388706828 | | 2 | 0.93845168309142 | | 3 | 0.83482678498591 | +------+------------------+ 3 rows in set (0.00 sec) mysql> +------+------------------+ | i | RAND(3) | +------+------------------+ | 1 | 0.90576975597606 | | 2 | 0.37307905813035 | | 3 | 0.14808605345719 | +------+------------------+ 3 rows in set (0.00 sec) mysql> +------+------------------+ | i | RAND() | +------+------------------+ | 1 | 0.35877890638893 | | 2 | 0.28941420772058 | | 3 | 0.37073435016976 | +------+------------------+ 3 rows in set (0.00 sec) mysql> +------+------------------+ | i | RAND(3) | +------+------------------+ | 1 | 0.90576975597606 | | 2 | 0.37307905813035 | | 3 | 0.14808605345719 | +------+------------------+ 3 rows in set (0.01 sec) CREATE TABLE t (i INT);INSERT INTO t VALUES(1),(2),(3);SELECT i, RAND() FROM t;SELECT i, RAND(3) FROM t;SELECT i, RAND() FROM t;SELECT i, RAND(3) FROM t;
RAND()
in a WHERE
clause is evaluated for every row (when selecting from one table) or combination of rows (when selecting from a multiple-table join). Thus, for optimizer purposes, RAND()
is not a constant value and cannot be used for index optimizations. For more information, see Section 8.2.1.19, 「Function Call Optimization」.
Use of a column with RAND()
values in an ORDER BY
or GROUP BY
clause may yield unexpected results because for either clause a RAND()
expression can be evaluated multiple times for the same row, each time returning a different result. If the goal is to retrieve rows in random order, you can use a statement like this:
SELECT * FROM ORDER BY RAND(); tbl_name
To select a random sample from a set of rows, combine ORDER BY RAND()
with LIMIT
:
SELECT * FROM table1, table2 WHERE a=b AND c<d ORDER BY RAND() LIMIT 1000;
RAND()
is not meant to be a perfect random generator. It is a fast way to generate random numbers on demand that is portable between platforms for the same MySQL version.
This function is unsafe for statement-based replication. A warning is logged if you use this function when binlog_format
is set to STATEMENT
.
Rounds the argument X
to D
decimal places. The rounding algorithm depends on the data type of X
. D
defaults to 0 if not specified. D
can be negative to cause D
digits left of the decimal point of the value X
to become zero.
mysql> -> -1 mysql> -> -2 mysql> -> 2 mysql> -> 1.3 mysql> -> 1 mysql> -> 20 SELECT ROUND(-1.23);SELECT ROUND(-1.58);SELECT ROUND(1.58);SELECT ROUND(1.298, 1);SELECT ROUND(1.298, 0);SELECT ROUND(23.298, -1);
The return value has the same type as the first argument (assuming that it is integer, double, or decimal). This means that for an integer argument, the result is an integer (no decimal places):
mysql> +------------------+--------------+ | ROUND(150.000,2) | ROUND(150,2) | +------------------+--------------+ | 150.00 | 150 | +------------------+--------------+ SELECT ROUND(150.000,2), ROUND(150,2);
ROUND()
uses the following rules depending on the type of the first argument:
For exact-value numbers, ROUND()
uses the 「round half away from zero」 or 「round toward nearest」 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.
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 halfway between two integers is rounded to the nearest even integer.
The following example shows how rounding differs for exact and approximate values:
mysql> +------------+--------------+ | ROUND(2.5) | ROUND(25E-1) | +------------+--------------+ | 3 | 2 | +------------+--------------+ SELECT ROUND(2.5), ROUND(25E-1);
For more information, see Section 12.25, 「Precision Math」.
Returns the sign of the argument as -1
, 0
, or 1
, depending on whether X
is negative, zero, or positive.
mysql> -> -1 mysql> -> 0 mysql> -> 1 SELECT SIGN(-32);SELECT SIGN(0);SELECT SIGN(234);
Returns the sine of X
, where X
is given in radians.
mysql> -> 1.2246063538224e-16 mysql> -> 0 SELECT SIN(PI());SELECT ROUND(SIN(PI()));
Returns the square root of a nonnegative number X
.
mysql> -> 2 mysql> -> 4.4721359549996 mysql> -> NULL SELECT SQRT(4);SELECT SQRT(20);SELECT SQRT(-16);
Returns the tangent of X
, where X
is given in radians.
mysql> -> -1.2246063538224e-16 mysql> -> 1.5574077246549 SELECT TAN(PI());SELECT TAN(PI()+1);
Returns the number X
, truncated to D
decimal places. If D
is 0
, the result has no decimal point or fractional part. D
can be negative to cause D
digits left of the decimal point of the value X
to become zero.
mysql> -> 1.2 mysql> -> 1.9 mysql> -> 1 mysql> -> -1.9 mysql> -> 100 mysql> -> 1028 SELECT TRUNCATE(1.223,1);SELECT TRUNCATE(1.999,1);SELECT TRUNCATE(1.999,0);SELECT TRUNCATE(-1.999,1);SELECT TRUNCATE(122,-2);SELECT TRUNCATE(10.28*100,0);
All numbers are rounded toward zero.
This section describes the functions that can be used to manipulate temporal values. See Section 11.3, 「Date and Time Types」, for a description of the range of values each date and time type has and the valid formats in which values may be specified.
Table 12.13 Date and Time Functions
Name | Description |
---|---|
ADDDATE() |
Add time values (intervals) to a date value |
ADDTIME() |
Add time |
CONVERT_TZ() |
Convert from one time zone to another |
CURDATE() |
Return the current date |
CURRENT_DATE() , CURRENT_DATE |
Synonyms for CURDATE() |
CURRENT_TIME() , CURRENT_TIME |
Synonyms for CURTIME() |
CURRENT_TIMESTAMP() , CURRENT_TIMESTAMP |
Synonyms for NOW() |
CURTIME() |
Return the current time |
DATE() |
Extract the date part of a date or datetime expression |
DATE_ADD() |
Add time values (intervals) to a date value |
DATE_FORMAT() |
Format date as specified |
DATE_SUB() |
Subtract a time value (interval) from a date |
DATEDIFF() |
Subtract two dates |
DAY() |
Synonym for DAYOFMONTH() |
DAYNAME() |
Return the name of the weekday |
DAYOFMONTH() |
Return the day of the month (0-31) |
DAYOFWEEK() |
Return the weekday index of the argument |
DAYOFYEAR() |
Return the day of the year (1-366) |
EXTRACT() |
Extract part of a date |
FROM_DAYS() |
Convert a day number to a date |
FROM_UNIXTIME() |
Format Unix timestamp as a date |
GET_FORMAT() |
Return a date format string |
HOUR() |
Extract the hour |
LAST_DAY |
Return the last day of the month for the argument |
LOCALTIME() , LOCALTIME |
Synonym for NOW() |
LOCALTIMESTAMP , LOCALTIMESTAMP() |
Synonym for NOW() |
MAKEDATE() |
Create a date from the year and day of year |
MAKETIME() |
Create time from hour, minute, second |
MICROSECOND() |
Return the microseconds from argument |
MINUTE() |
Return the minute from the argument |
MONTH() |
Return the month from the date passed |
MONTHNAME() |
Return the name of the month |
NOW() |
Return the current date and time |
PERIOD_ADD() |
Add a period to a year-month |
PERIOD_DIFF() |
Return the number of months between periods |
QUARTER() |
Return the quarter from a date argument |
SEC_TO_TIME() |
Converts seconds to 'hh:mm:ss' format |
SECOND() |
Return the second (0-59) |
STR_TO_DATE() |
Convert a string to a date |
SUBDATE() |
Synonym for DATE_SUB() when invoked with three arguments |
SUBTIME() |
Subtract times |
SYSDATE() |
Return the time at which the function executes |
TIME() |
Extract the time portion of the expression passed |
TIME_FORMAT() |
Format as time |
TIME_TO_SEC() |
Return the argument converted to seconds |
TIMEDIFF() |
Subtract time |
TIMESTAMP() |
With a single argument, this function returns the date or datetime expression; with two arguments, the sum of the arguments |
TIMESTAMPADD() |
Add an interval to a datetime expression |
TIMESTAMPDIFF() |
Subtract an interval from a datetime expression |
TO_DAYS() |
Return the date argument converted to days |
TO_SECONDS() |
Return the date or datetime argument converted to seconds since Year 0 |
UNIX_TIMESTAMP() |
Return a Unix timestamp |
UTC_DATE() |
Return the current UTC date |
UTC_TIME() |
Return the current UTC time |
UTC_TIMESTAMP() |
Return the current UTC date and time |
WEEK() |
Return the week number |
WEEKDAY() |
Return the weekday index |
WEEKOFYEAR() |
Return the calendar week of the date (1-53) |
YEAR() |
Return the year |
YEARWEEK() |
Return the year and week |
Here is an example that uses date functions. The following query selects all rows with a date_col
value from within the last 30 days:
mysql> -> SELECTsomething
FROMtbl_name
somethingtbl_nameWHERE DATE_SUB(CURDATE(),INTERVAL 30 DAY) <=date_col
;date_col
The query also selects rows with dates that lie in the future.
Functions that expect date values usually accept datetime values and ignore the time part. Functions that expect time values usually accept datetime values and ignore the date part.
Functions that return the current date or time each are evaluated only once per query at the start of query execution. This means that multiple references to a function such as NOW()
within a single query always produce the same result. (For our purposes, a single query also includes a call to a stored program (stored routine, trigger, or event) and all subprograms called by that program.) This principle also applies to CURDATE()
, CURTIME()
, UTC_DATE()
, UTC_TIME()
, UTC_TIMESTAMP()
, and to any of their synonyms.
The CURRENT_TIMESTAMP()
, CURRENT_TIME()
, CURRENT_DATE()
, and FROM_UNIXTIME()
functions return values in the current session time zone, which is available as the session value of the time_zone
system variable. In addition, UNIX_TIMESTAMP()
assumes that its argument is a datetime value in the session time zone. See Section 5.1.13, 「MySQL Server Time Zone Support」.
Some date functions can be used with 「zero」 dates or incomplete dates such as '2001-11-00'
, whereas others cannot. Functions that extract parts of dates typically work with incomplete dates and thus can return 0 when you might otherwise expect a nonzero value. For example:
mysql> -> 0, 0 SELECT DAYOFMONTH('2001-11-00'), MONTH('2005-00-00');
Other functions expect complete dates and return NULL
for incomplete dates. These include functions that perform date arithmetic or that map parts of dates to names. For example:
mysql> -> NULL mysql> -> NULL SELECT DATE_ADD('2006-05-00',INTERVAL 1 DAY);SELECT DAYNAME('2006-05-00');
Several functions are more strict when passed a DATE()
function value as their argument and reject incomplete dates with a day part of zero. These functions are affected: CONVERT_TZ()
, DATE_ADD()
, DATE_SUB()
, DAYOFYEAR()
, LAST_DAY()
(permits a day part of zero), TIMESTAMPDIFF()
, TO_DAYS()
, TO_SECONDS()
, WEEK()
, WEEKDAY()
, WEEKOFYEAR()
, YEARWEEK()
.
Fractional seconds for TIME
, DATETIME
, and TIMESTAMP
values are supported, with up to microsecond precision. Functions that take temporal arguments accept values with fractional seconds. Return values from temporal functions include fractional seconds as appropriate.
ADDDATE(
, date
,INTERVAL expr
unit
)ADDDATE(
expr
,days
)
When invoked with the INTERVAL
form of the second argument, ADDDATE()
is a synonym for DATE_ADD()
. The related function SUBDATE()
is a synonym for DATE_SUB()
. For information on the INTERVAL
unit
argument, see Temporal Intervals.
mysql> -> '2008-02-02' mysql> -> '2008-02-02' SELECT DATE_ADD('2008-01-02', INTERVAL 31 DAY);SELECT ADDDATE('2008-01-02', INTERVAL 31 DAY);
When invoked with the days
form of the second argument, MySQL treats it as an integer number of days to be added to expr
.
mysql> -> '2008-02-02' SELECT ADDDATE('2008-01-02', 31);
ADDTIME()
adds expr2
to expr1
and returns the result. expr1
is a time or datetime expression, and expr2
is a time expression.
mysql> -> '2008-01-02 01:01:01.000001' mysql> -> '03:00:01.999997' SELECT ADDTIME('2007-12-31 23:59:59.999999', '1 1:1:1.000002');SELECT ADDTIME('01:00:00.999999', '02:00:00.999998');
CONVERT_TZ()
converts a datetime value dt
from the time zone given by from_tz
to the time zone given by to_tz
and returns the resulting value. Time zones are specified as described in Section 5.1.13, 「MySQL Server Time Zone Support」. This function returns NULL
if the arguments are invalid.
If the value falls out of the supported range of the TIMESTAMP
type when converted from from_tz
to UTC, no conversion occurs. The TIMESTAMP
range is described in Section 11.1.2, 「Date and Time Type Overview」.
mysql> -> '2004-01-01 13:00:00' mysql> -> '2004-01-01 22:00:00' SELECT CONVERT_TZ('2004-01-01 12:00:00','GMT','MET');SELECT CONVERT_TZ('2004-01-01 12:00:00','+00:00','+10:00');
To use named time zones such as 'MET'
or 'Europe/Amsterdam'
, the time zone tables must be properly set up. For instructions, see Section 5.1.13, 「MySQL Server Time Zone Support」.
Returns the current date as a value in 'YYYY-MM-DD'
or YYYYMMDD
format, depending on whether the function is used in a string or numeric context.
mysql> -> '2008-06-13' mysql> -> 20080613 SELECT CURDATE();SELECT CURDATE() + 0;
CURRENT_DATE
and CURRENT_DATE()
are synonyms for CURDATE()
.
CURRENT_TIME
, CURRENT_TIME([
fsp
])
CURRENT_TIME
and CURRENT_TIME()
are synonyms for CURTIME()
.
CURRENT_TIMESTAMP
, CURRENT_TIMESTAMP([
fsp
])
CURRENT_TIMESTAMP
and CURRENT_TIMESTAMP()
are synonyms for NOW()
.
Returns the current time as a value in 'hh:mm:ss'
or hhmmss
format, depending on whether the function is used in a string or numeric context. The value is expressed in the session time zone.
If the fsp
argument is given to specify a fractional seconds precision from 0 to 6, the return value includes a fractional seconds part of that many digits.
mysql> -> '23:50:26' mysql> -> 235026.000000 SELECT CURTIME();SELECT CURTIME() + 0;
Extracts the date part of the date or datetime expression expr
.
mysql> -> '2003-12-31' SELECT DATE('2003-12-31 01:02:03');
DATEDIFF()
returns expr1
− expr2
expressed as a value in days from one date to the other. expr1
and expr2
are date or date-and-time expressions. Only the date parts of the values are used in the calculation.
mysql> -> 1 mysql> -> -31 SELECT DATEDIFF('2007-12-31 23:59:59','2007-12-30');SELECT DATEDIFF('2010-11-30 23:59:59','2010-12-31');
DATE_ADD(
, date
,INTERVAL expr
unit
)DATE_SUB(
date
,INTERVAL expr
unit
)
These functions perform date arithmetic. The date
argument specifies the starting date or datetime value. expr
is an expression specifying the interval value to be added or subtracted from the starting date. expr
is evaluated as a string; it may start with a -
for negative intervals. unit
is a keyword indicating the units in which the expression should be interpreted.
For more information about temporal interval syntax, including a full list of unit
specifiers, the expected form of the expr
argument for each unit
value, and rules for operand interpretation in temporal arithmetic, see Temporal Intervals.
The return value depends on the arguments:
DATE
if the date
argument is a DATE
value and your calculations involve only YEAR
, MONTH
, and DAY
parts (that is, no time parts).
DATETIME
if the first argument is a DATETIME
(or TIMESTAMP
) value, or if the first argument is a DATE
and the unit
value uses HOURS
, MINUTES
, or SECONDS
.
String otherwise.
To ensure that the result is DATETIME
, you can use CAST()
to convert the first argument to DATETIME
.
mysql> -> '2018-05-02' mysql> -> '2017-05-01' mysql> -> -> '2021-01-01 00:00:00' mysql> -> -> '2019-01-01 23:59:59' mysql> -> -> '2101-01-01 00:01:00' mysql> -> -> '2024-12-30 22:58:59' mysql> -> -> '1899-12-30 14:00:00' mysql> -> '1997-12-02' mysql> -> -> '1993-01-01 00:00:01.000001' SELECT DATE_ADD('2018-05-01',INTERVAL 1 DAY);SELECT DATE_SUB('2018-05-01',INTERVAL 1 YEAR);SELECT DATE_ADD('2020-12-31 23:59:59',INTERVAL 1 SECOND);SELECT DATE_ADD('2018-12-31 23:59:59',INTERVAL 1 DAY);SELECT DATE_ADD('2100-12-31 23:59:59',INTERVAL '1:1' MINUTE_SECOND);SELECT DATE_SUB('2025-01-01 00:00:00',INTERVAL '1 1:1:1' DAY_SECOND);SELECT DATE_ADD('1900-01-01 00:00:00',INTERVAL '-1 10' DAY_HOUR);SELECT DATE_SUB('1998-01-02', INTERVAL 31 DAY);SELECT DATE_ADD('1992-12-31 23:59:59.000002',INTERVAL '1.999999' SECOND_MICROSECOND);
Formats the date
value according to the format
string.
The specifiers shown in the following table may be used in the format
string. The %
character is required before format specifier characters. The specifiers apply to other functions as well: STR_TO_DATE()
, TIME_FORMAT()
, UNIX_TIMESTAMP()
.
Specifier | Description |
---|---|
%a |
Abbreviated weekday name (Sun ..Sat ) |
%b |
Abbreviated month name (Jan ..Dec ) |
%c |
Month, numeric (0 ..12 ) |
%D |
Day of the month with English suffix (0th , 1st , 2nd , 3rd , …) |
%d |
Day of the month, numeric (00 ..31 ) |
%e |
Day of the month, numeric (0 ..31 ) |
%f |
Microseconds (000000 ..999999 ) |
%H |
Hour (00 ..23 ) |
%h |
Hour (01 ..12 ) |
%I |
Hour (01 ..12 ) |
%i |
Minutes, numeric (00 ..59 ) |
%j |
Day of year (001 ..366 ) |
%k |
Hour (0 ..23 ) |
%l |
Hour (1 ..12 ) |
%M |
Month name (January ..December ) |
%m |
Month, numeric (00 ..12 ) |
%p |
AM or PM |
%r |
Time, 12-hour (hh:mm:ss followed by AM or PM ) |
%S |
Seconds (00 ..59 ) |
%s |
Seconds (00 ..59 ) |
%T |
Time, 24-hour (hh:mm:ss ) |
%U |
Week (00 ..53 ), where Sunday is the first day of the week; WEEK() mode 0 |
%u |
Week (00 ..53 ), where Monday is the first day of the week; WEEK() mode 1 |
%V |
Week (01 ..53 ), where Sunday is the first day of the week; WEEK() mode 2; used with %X |
%v |
Week (01 ..53 ), where Monday is the first day of the week; WEEK() mode 3; used with %x |
%W |
Weekday name (Sunday ..Saturday ) |
%w |
Day of the week (0 =Sunday..6 =Saturday) |
%X |
Year for the week where Sunday is the first day of the week, numeric, four digits; used with %V |
%x |
Year for the week, where Monday is the first day of the week, numeric, four digits; used with %v |
%Y |
Year, numeric, four digits |
%y |
Year, numeric (two digits) |
%% |
A literal % character |
% |
x , for any 「x 」 not listed above |
Ranges for the month and day specifiers begin with zero due to the fact that MySQL permits the storing of incomplete dates such as '2014-00-00'
.
The language used for day and month names and abbreviations is controlled by the value of the lc_time_names
system variable (Section 10.15, 「MySQL Server Locale Support」).
For the %U
, %u
, %V
, and %v
specifiers, see the description of the WEEK()
function for information about the mode values. The mode affects how week numbering occurs.
DATE_FORMAT()
returns a string with a character set and collation given by character_set_connection
and collation_connection
so that it can return month and weekday names containing non-ASCII characters.
mysql> -> 'Sunday October 2009' mysql> -> '22:23:00' mysql> -> -> '4th 00 Thu 04 10 Oct 277' mysql> -> -> '22 22 10 10:23:00 PM 22:23:00 00 6' mysql> -> '1998 52' mysql> -> '00' SELECT DATE_FORMAT('2009-10-04 22:23:00', '%W %M %Y');SELECT DATE_FORMAT('2007-10-04 22:23:00', '%H:%i:%s');SELECT DATE_FORMAT('1900-10-04 22:23:00','%D %y %a %d %m %b %j');SELECT DATE_FORMAT('1997-10-04 22:23:00','%H %k %I %r %T %S %w');SELECT DATE_FORMAT('1999-01-01', '%X %V');SELECT DATE_FORMAT('2006-06-00', '%d');
DATE_SUB(
date
,INTERVAL expr
unit
)
See the description for DATE_ADD()
.
DAY()
is a synonym for DAYOFMONTH()
.
Returns the name of the weekday for date
. The language used for the name is controlled by the value of the lc_time_names
system variable (Section 10.15, 「MySQL Server Locale Support」).
mysql> -> 'Saturday' SELECT DAYNAME('2007-02-03');
Returns the day of the month for date
, in the range 1
to 31
, or 0
for dates such as '0000-00-00'
or '2008-00-00'
that have a zero day part.
mysql> -> 3 SELECT DAYOFMONTH('2007-02-03');
Returns the weekday index for date
(1
= Sunday, 2
= Monday, …, 7
= Saturday). These index values correspond to the ODBC standard.
mysql> -> 7 SELECT DAYOFWEEK('2007-02-03');
Returns the day of the year for date
, in the range 1
to 366
.
mysql> -> 34 SELECT DAYOFYEAR('2007-02-03');
The EXTRACT()
function uses the same kinds of unit
specifiers as DATE_ADD()
or DATE_SUB()
, but extracts parts from the date rather than performing date arithmetic. For information on the unit
argument, see Temporal Intervals.
mysql> -> 2019 mysql> -> 201907 mysql> -> 20102 mysql> -> -> 123 SELECT EXTRACT(YEAR FROM '2019-07-02');SELECT EXTRACT(YEAR_MONTH FROM '2019-07-02 01:02:03');SELECT EXTRACT(DAY_MINUTE FROM '2019-07-02 01:02:03');SELECT EXTRACT(MICROSECONDFROM '2003-01-02 10:30:00.000123');
Given a day number N
, returns a DATE
value.
mysql> -> '2000-07-03' SELECT FROM_DAYS(730669);
Use FROM_DAYS()
with caution on old dates. It is not intended for use with values that precede the advent of the Gregorian calendar (1582). See Section 12.8, 「What Calendar Is Used By MySQL?」.
FROM_UNIXTIME(
unix_timestamp
[,format
])
Returns a representation of the unix_timestamp
argument as a value in 'YYYY-MM-DD hh:mm:ss'
or YYYYMMDDhhmmss.uuuuuu
format, depending on whether the function is used in a string or numeric context. unix_timestamp
is an internal timestamp value representing seconds since '1970-01-01 00:00:00'
UTC, such as produced by the UNIX_TIMESTAMP()
function.
The return value is expressed in the session time zone. (Clients can set the session time zone as described in Section 5.1.13, 「MySQL Server Time Zone Support」.) The format
string, if given, is used to format the result the same way as described in the entry for the DATE_FORMAT()
function.
mysql> -> '2015-11-13 10:08:01' mysql> -> 20151113100801 mysql> -> -> '2015 13th November 10:08:01 2015' SELECT FROM_UNIXTIME(1447430881);SELECT FROM_UNIXTIME(1447430881) + 0;SELECT FROM_UNIXTIME(1447430881,'%Y %D %M %h:%i:%s %x');
If you use UNIX_TIMESTAMP()
and FROM_UNIXTIME()
to convert between values in a non-UTC time zone and Unix timestamp values, the conversion is lossy because the mapping is not one-to-one in both directions. For details, see the description of the UNIX_TIMESTAMP()
function.
GET_FORMAT({DATE|TIME|DATETIME}, {'EUR'|'USA'|'JIS'|'ISO'|'INTERNAL'})
Returns a format string. This function is useful in combination with the DATE_FORMAT()
and the STR_TO_DATE()
functions.
The possible values for the first and second arguments result in several possible format strings (for the specifiers used, see the table in the DATE_FORMAT()
function description). ISO format refers to ISO 9075, not ISO 8601.
Function Call | Result |
---|---|
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
can also be used as the first argument to GET_FORMAT()
, in which case the function returns the same values as for DATETIME
.
mysql> -> '03.10.2003' mysql> -> '2003-10-31' SELECT DATE_FORMAT('2003-10-03',GET_FORMAT(DATE,'EUR'));SELECT STR_TO_DATE('10.31.2003',GET_FORMAT(DATE,'USA'));
Returns the hour for time
. The range of the return value is 0
to 23
for time-of-day values. However, the range of TIME
values actually is much larger, so HOUR
can return values greater than 23
.
mysql> -> 10 mysql> -> 272 SELECT HOUR('10:05:03');SELECT HOUR('272:59:59');
Takes a date or datetime value and returns the corresponding value for the last day of the month. Returns NULL
if the argument is invalid.
mysql> -> '2003-02-28' mysql> -> '2004-02-29' mysql> -> '2004-01-31' mysql> -> NULL SELECT LAST_DAY('2003-02-05');SELECT LAST_DAY('2004-02-05');SELECT LAST_DAY('2004-01-01 01:01:01');SELECT LAST_DAY('2003-03-32');
LOCALTIME
and LOCALTIME()
are synonyms for NOW()
.
LOCALTIMESTAMP
, LOCALTIMESTAMP([
fsp
])
LOCALTIMESTAMP
and LOCALTIMESTAMP()
are synonyms for NOW()
.
Returns a date, given year and day-of-year values. dayofyear
must be greater than 0 or the result is NULL
.
mysql> -> '2011-01-31', '2011-02-01' mysql> -> '2011-12-31', '2014-12-31' mysql> -> NULL SELECT MAKEDATE(2011,31), MAKEDATE(2011,32);SELECT MAKEDATE(2011,365), MAKEDATE(2014,365);SELECT MAKEDATE(2011,0);
Returns a time value calculated from the hour
, minute
, and second
arguments.
The second
argument can have a fractional part.
mysql> -> '12:15:30' SELECT MAKETIME(12,15,30);
Returns the microseconds from the time or datetime expression expr
as a number in the range from 0
to 999999
.
mysql> -> 123456 mysql> -> 10 SELECT MICROSECOND('12:00:00.123456');SELECT MICROSECOND('2019-12-31 23:59:59.000010');
Returns the minute for time
, in the range 0
to 59
.
mysql> -> 5 SELECT MINUTE('2008-02-03 10:05:03');
Returns the month for date
, in the range 1
to 12
for January to December, or 0
for dates such as '0000-00-00'
or '2008-00-00'
that have a zero month part.
mysql> -> 2 SELECT MONTH('2008-02-03');
Returns the full name of the month for date
. The language used for the name is controlled by the value of the lc_time_names
system variable (Section 10.15, 「MySQL Server Locale Support」).
mysql> -> 'February' SELECT MONTHNAME('2008-02-03');
Returns the current date and time as a value in 'YYYY-MM-DD hh:mm:ss'
or YYYYMMDDhhmmss
format, depending on whether the function is used in a string or numeric context. The value is expressed in the session time zone.
If the fsp
argument is given to specify a fractional seconds precision from 0 to 6, the return value includes a fractional seconds part of that many digits.
mysql> -> '2007-12-15 23:50:26' mysql> -> 20071215235026.000000 SELECT NOW();SELECT NOW() + 0;
NOW()
returns a constant time that indicates the time at which the statement began to execute. (Within a stored function or trigger, NOW()
returns the time at which the function or triggering statement began to execute.) This differs from the behavior for SYSDATE()
, which returns the exact time at which it executes.
mysql> +---------------------+----------+---------------------+ | NOW() | SLEEP(2) | NOW() | +---------------------+----------+---------------------+ | 2006-04-12 13:47:36 | 0 | 2006-04-12 13:47:36 | +---------------------+----------+---------------------+ mysql> +---------------------+----------+---------------------+ | SYSDATE() | SLEEP(2) | SYSDATE() | +---------------------+----------+---------------------+ | 2006-04-12 13:47:44 | 0 | 2006-04-12 13:47:46 | +---------------------+----------+---------------------+ SELECT NOW(), SLEEP(2), NOW();SELECT SYSDATE(), SLEEP(2), SYSDATE();
In addition, the SET TIMESTAMP
statement affects the value returned by NOW()
but not by SYSDATE()
. This means that timestamp settings in the binary log have no effect on invocations of SYSDATE()
. Setting the timestamp to a nonzero value causes each subsequent invocation of NOW()
to return that value. Setting the timestamp to zero cancels this effect so that NOW()
once again returns the current date and time.
See the description for SYSDATE()
for additional information about the differences between the two functions.
Adds N
months to period P
(in the format YYMM
or YYYYMM
). Returns a value in the format YYYYMM
.
The period argument P
is not a date value.
mysql> -> 200803 SELECT PERIOD_ADD(200801,2);
Returns the number of months between periods P1
and P2
. P1
and P2
should be in the format YYMM
or YYYYMM
. Note that the period arguments P1
and P2
are not date values.
mysql> -> 11 SELECT PERIOD_DIFF(200802,200703);
Returns the quarter of the year for date
, in the range 1
to 4
.
mysql> -> 2 SELECT QUARTER('2008-04-01');
Returns the second for time
, in the range 0
to 59
.
mysql> -> 3 SELECT SECOND('10:05:03');
Returns the seconds
argument, converted to hours, minutes, and seconds, as a TIME
value. The range of the result is constrained to that of the TIME
data type. A warning occurs if the argument corresponds to a value outside that range.
mysql> -> '00:39:38' mysql> -> 3938 SELECT SEC_TO_TIME(2378);SELECT SEC_TO_TIME(2378) + 0;
This is the inverse of the DATE_FORMAT()
function. It takes a string str
and a format string format
. STR_TO_DATE()
returns a DATETIME
value if the format string contains both date and time parts, or a DATE
or TIME
value if the string contains only date or time parts. If the date, time, or datetime value extracted from str
is illegal, STR_TO_DATE()
returns NULL
and produces a warning.
The server scans str
attempting to match format
to it. The format string can contain literal characters and format specifiers beginning with %
. Literal characters in format
must match literally in str
. Format specifiers in format
must match a date or time part in str
. For the specifiers that can be used in format
, see the DATE_FORMAT()
function description.
mysql> -> '2013-05-01' mysql> -> '2013-05-01' SELECT STR_TO_DATE('01,5,2013','%d,%m,%Y');SELECT STR_TO_DATE('May 1, 2013','%M %d,%Y');
Scanning starts at the beginning of str
and fails if format
is found not to match. Extra characters at the end of str
are ignored.
mysql> -> '09:30:17' mysql> -> NULL mysql> -> '09:30:17' SELECT STR_TO_DATE('a09:30:17','a%h:%i:%s');SELECT STR_TO_DATE('a09:30:17','%h:%i:%s');SELECT STR_TO_DATE('09:30:17a','%h:%i:%s');
Unspecified date or time parts have a value of 0, so incompletely specified values in str
produce a result with some or all parts set to 0:
mysql> -> '0000-00-00' mysql> -> '0000-09-00' mysql> -> '00:00:09' SELECT STR_TO_DATE('abc','abc');SELECT STR_TO_DATE('9','%m');SELECT STR_TO_DATE('9','%s');
Range checking on the parts of date values is as described in Section 11.3.1, 「The DATE, DATETIME, and TIMESTAMP Types」. This means, for example, that 「zero」 dates or dates with part values of 0 are permitted unless the SQL mode is set to disallow such values.
mysql> -> '0000-00-00' mysql> -> '2004-04-31' SELECT STR_TO_DATE('00/00/0000', '%m/%d/%Y');SELECT STR_TO_DATE('04/31/2004', '%m/%d/%Y');
If the NO_ZERO_DATE
or NO_ZERO_IN_DATE
SQL mode is enabled, zero dates or part of dates are disallowed. In that case, STR_TO_DATE()
returns NULL
and generates a warning:
mysql> mysql> +-------------------------------------+ | STR_TO_DATE('15:35:00', '%H:%i:%s') | +-------------------------------------+ | 15:35:00 | +-------------------------------------+ mysql> mysql> +-------------------------------------+ | STR_TO_DATE('15:35:00', '%h:%i:%s') | +-------------------------------------+ | NULL | +-------------------------------------+ mysql> *************************** 1. row *************************** Level: Warning Code: 1411 Message: Incorrect datetime value: '15:35:00' for function str_to_date SET sql_mode = '';SELECT STR_TO_DATE('15:35:00', '%H:%i:%s');SET sql_mode = 'NO_ZERO_IN_DATE';SELECT STR_TO_DATE('15:35:00', '%h:%i:%s');SHOW WARNINGS\G
You cannot use format "%X%V"
to convert a year-week string to a date because the combination of a year and week does not uniquely identify a year and month if the week crosses a month boundary. To convert a year-week to a date, you should also specify the weekday:
mysql> -> '2004-10-18' SELECT STR_TO_DATE('200442 Monday', '%X%V %W');
SUBDATE(
, date
,INTERVAL expr
unit
)SUBDATE(
expr
,days
)
When invoked with the INTERVAL
form of the second argument, SUBDATE()
is a synonym for DATE_SUB()
. For information on the INTERVAL
unit
argument, see the discussion for DATE_ADD()
.
mysql> -> '2007-12-02' mysql> -> '2007-12-02' SELECT DATE_SUB('2008-01-02', INTERVAL 31 DAY);SELECT SUBDATE('2008-01-02', INTERVAL 31 DAY);
The second form enables the use of an integer value for days
. In such cases, it is interpreted as the number of days to be subtracted from the date or datetime expression expr
.
mysql> -> '2007-12-02 12:00:00' SELECT SUBDATE('2008-01-02 12:00:00', 31);
SUBTIME()
returns expr1
− expr2
expressed as a value in the same format as expr1
. expr1
is a time or datetime expression, and expr2
is a time expression.
mysql> -> '2007-12-30 22:58:58.999997' mysql> -> '-00:59:59.999999' SELECT SUBTIME('2007-12-31 23:59:59.999999','1 1:1:1.000002');SELECT SUBTIME('01:00:00.999999', '02:00:00.999998');
Returns the current date and time as a value in 'YYYY-MM-DD hh:mm:ss'
or YYYYMMDDhhmmss
format, depending on whether the function is used in a string or numeric context.
If the fsp
argument is given to specify a fractional seconds precision from 0 to 6, the return value includes a fractional seconds part of that many digits.
SYSDATE()
returns the time at which it executes. This differs from the behavior for NOW()
, which returns a constant time that indicates the time at which the statement began to execute. (Within a stored function or trigger, NOW()
returns the time at which the function or triggering statement began to execute.)
mysql> +---------------------+----------+---------------------+ | NOW() | SLEEP(2) | NOW() | +---------------------+----------+---------------------+ | 2006-04-12 13:47:36 | 0 | 2006-04-12 13:47:36 | +---------------------+----------+---------------------+ mysql> +---------------------+----------+---------------------+ | SYSDATE() | SLEEP(2) | SYSDATE() | +---------------------+----------+---------------------+ | 2006-04-12 13:47:44 | 0 | 2006-04-12 13:47:46 | +---------------------+----------+---------------------+ SELECT NOW(), SLEEP(2), NOW();SELECT SYSDATE(), SLEEP(2), SYSDATE();
In addition, the SET TIMESTAMP
statement affects the value returned by NOW()
but not by SYSDATE()
. This means that timestamp settings in the binary log have no effect on invocations of SYSDATE()
.
Because SYSDATE()
can return different values even within the same statement, and is not affected by SET TIMESTAMP
, it is nondeterministic and therefore unsafe for replication if statement-based binary logging is used. If that is a problem, you can use row-based logging.
Alternatively, you can use the --sysdate-is-now
option to cause SYSDATE()
to be an alias for NOW()
. This works if the option is used on both the master and the slave.
The nondeterministic nature of SYSDATE()
also means that indexes cannot be used for evaluating expressions that refer to it.
Extracts the time part of the time or datetime expression expr
and returns it as a string.
This function is unsafe for statement-based replication. A warning is logged if you use this function when binlog_format
is set to STATEMENT
.
mysql> -> '01:02:03' mysql> -> '01:02:03.000123' SELECT TIME('2003-12-31 01:02:03');SELECT TIME('2003-12-31 01:02:03.000123');
TIMEDIFF()
returns expr1
− expr2
expressed as a time value. expr1
and expr2
are time or date-and-time expressions, but both must be of the same type.
The result returned by TIMEDIFF()
is limited to the range allowed for TIME
values. Alternatively, you can use either of the functions TIMESTAMPDIFF()
and UNIX_TIMESTAMP()
, both of which return integers.
mysql> -> -> '-00:00:00.000001' mysql> -> -> '46:58:57.999999' SELECT TIMEDIFF('2000:01:01 00:00:00','2000:01:01 00:00:00.000001');SELECT TIMEDIFF('2008-12-31 23:59:59.000001','2008-12-30 01:01:01.000002');
TIMESTAMP(
, expr
)TIMESTAMP(
expr1
,expr2
)
With a single argument, this function returns the date or datetime expression expr
as a datetime value. With two arguments, it adds the time expression expr2
to the date or datetime expression expr1
and returns the result as a datetime value.
mysql> -> '2003-12-31 00:00:00' mysql> -> '2004-01-01 00:00:00' SELECT TIMESTAMP('2003-12-31');SELECT TIMESTAMP('2003-12-31 12:00:00','12:00:00');
TIMESTAMPADD(
unit
,interval
,datetime_expr
)
Adds the integer expression interval
to the date or datetime expression datetime_expr
. The unit for interval
is given by the unit
argument, which should be one of the following values: MICROSECOND
(microseconds), SECOND
, MINUTE
, HOUR
, DAY
, WEEK
, MONTH
, QUARTER
, or YEAR
.
The unit
value may be specified using one of keywords as shown, or with a prefix of SQL_TSI_
. For example, DAY
and SQL_TSI_DAY
both are legal.
mysql> -> '2003-01-02 00:01:00' mysql> -> '2003-01-09' SELECT TIMESTAMPADD(MINUTE,1,'2003-01-02');SELECT TIMESTAMPADD(WEEK,1,'2003-01-02');
TIMESTAMPDIFF(
unit
,datetime_expr1
,datetime_expr2
)
Returns datetime_expr2
− datetime_expr1
, where datetime_expr1
and datetime_expr2
are date or datetime expressions. One expression may be a date and the other a datetime; a date value is treated as a datetime having the time part '00:00:00'
where necessary. The unit for the result (an integer) is given by the unit
argument. The legal values for unit
are the same as those listed in the description of the TIMESTAMPADD()
function.
mysql> -> 3 mysql> -> -1 mysql> -> 128885 SELECT TIMESTAMPDIFF(MONTH,'2003-02-01','2003-05-01');SELECT TIMESTAMPDIFF(YEAR,'2002-05-01','2001-01-01');SELECT TIMESTAMPDIFF(MINUTE,'2003-02-01','2003-05-01 12:05:55');
The order of the date or datetime arguments for this function is the opposite of that used with the TIMESTAMP()
function when invoked with 2 arguments.
This is used like the DATE_FORMAT()
function, but the format
string may contain format specifiers only for hours, minutes, seconds, and microseconds. Other specifiers produce a NULL
value or 0
.
If the time
value contains an hour part that is greater than 23
, the %H
and %k
hour format specifiers produce a value larger than the usual range of 0..23
. The other hour format specifiers produce the hour value modulo 12.
mysql> -> '100 100 04 04 4' SELECT TIME_FORMAT('100:00:00', '%H %k %h %I %l');
Returns the time
argument, converted to seconds.
mysql> -> 80580 mysql> -> 2378 SELECT TIME_TO_SEC('22:23:00');SELECT TIME_TO_SEC('00:39:38');
Given a date date
, returns a day number (the number of days since year 0).
mysql> -> 728779 mysql> -> 733321 SELECT TO_DAYS(950501);SELECT TO_DAYS('2007-10-07');
TO_DAYS()
is not intended for use with values that precede the advent of the Gregorian calendar (1582), because it does not take into account the days that were lost when the calendar was changed. For dates before 1582 (and possibly a later year in other locales), results from this function are not reliable. See Section 12.8, 「What Calendar Is Used By MySQL?」, for details.
Remember that MySQL converts two-digit year values in dates to four-digit form using the rules in Section 11.3, 「Date and Time Types」. For example, '2008-10-07'
and '08-10-07'
are seen as identical dates:
mysql> -> 733687, 733687 SELECT TO_DAYS('2008-10-07'), TO_DAYS('08-10-07');
In MySQL, the zero date is defined as '0000-00-00'
, even though this date is itself considered invalid. This means that, for '0000-00-00'
and '0000-01-01'
, TO_DAYS()
returns the values shown here:
mysql> +-----------------------+ | to_days('0000-00-00') | +-----------------------+ | NULL | +-----------------------+ 1 row in set, 1 warning (0.00 sec) mysql> +---------+------+----------------------------------------+ | Level | Code | Message | +---------+------+----------------------------------------+ | Warning | 1292 | Incorrect datetime value: '0000-00-00' | +---------+------+----------------------------------------+ 1 row in set (0.00 sec) mysql> +-----------------------+ | to_days('0000-01-01') | +-----------------------+ | 1 | +-----------------------+ 1 row in set (0.00 sec) SELECT TO_DAYS('0000-00-00');SHOW WARNINGS;SELECT TO_DAYS('0000-01-01');
This is true whether or not the ALLOW_INVALID_DATES
SQL server mode is enabled.
Given a date or datetime expr
, returns the number of seconds since the year 0. If expr
is not a valid date or datetime value, returns NULL
.
mysql> -> 62966505600 mysql> -> 63426672000 mysql> -> 63426721412 mysql> -> 63426721458 SELECT TO_SECONDS(950501);SELECT TO_SECONDS('2009-11-29');SELECT TO_SECONDS('2009-11-29 13:43:32');SELECT TO_SECONDS( NOW() );
Like TO_DAYS()
, TO_SECONDS()
is not intended for use with values that precede the advent of the Gregorian calendar (1582), because it does not take into account the days that were lost when the calendar was changed. For dates before 1582 (and possibly a later year in other locales), results from this function are not reliable. See Section 12.8, 「What Calendar Is Used By MySQL?」, for details.
Like TO_DAYS()
, TO_SECONDS()
, converts two-digit year values in dates to four-digit form using the rules in Section 11.3, 「Date and Time Types」.
In MySQL, the zero date is defined as '0000-00-00'
, even though this date is itself considered invalid. This means that, for '0000-00-00'
and '0000-01-01'
, TO_SECONDS()
returns the values shown here:
mysql> +--------------------------+ | TO_SECONDS('0000-00-00') | +--------------------------+ | NULL | +--------------------------+ 1 row in set, 1 warning (0.00 sec) mysql> +---------+------+----------------------------------------+ | Level | Code | Message | +---------+------+----------------------------------------+ | Warning | 1292 | Incorrect datetime value: '0000-00-00' | +---------+------+----------------------------------------+ 1 row in set (0.00 sec) mysql> +--------------------------+ | TO_SECONDS('0000-01-01') | +--------------------------+ | 86400 | +--------------------------+ 1 row in set (0.00 sec) SELECT TO_SECONDS('0000-00-00');SHOW WARNINGS;SELECT TO_SECONDS('0000-01-01');
This is true whether or not the ALLOW_INVALID_DATES
SQL server mode is enabled.
If UNIX_TIMESTAMP()
is called with no date
argument, it returns a Unix timestamp representing seconds since '1970-01-01 00:00:00'
UTC.
If UNIX_TIMESTAMP()
is called with a date
argument, it returns the value of the argument as seconds since '1970-01-01 00:00:00'
UTC. The server interprets date
as a value in the session time zone and converts it to an internal Unix timestamp value in UTC. (Clients can set the session time zone as described in Section 5.1.13, 「MySQL Server Time Zone Support」.) The date
argument may be a DATE
, DATETIME
, or TIMESTAMP
string, or a number in YYMMDD
, YYMMDDhhmmss
, YYYYMMDD
, or YYYYMMDDhhmmss
format. If the argument includes a time part, it may optionally include a fractional seconds part.
The return value is an integer if no argument is given or the argument does not include a fractional seconds part, or DECIMAL
if an argument is given that includes a fractional seconds part.
When the date
argument is a TIMESTAMP
column, UNIX_TIMESTAMP()
returns the internal timestamp value directly, with no implicit 「string-to-Unix-timestamp」 conversion.
The valid range of argument values is the same as for the TIMESTAMP
data type: '1970-01-01 00:00:01.000000'
UTC to '2038-01-19 03:14:07.999999'
UTC. If you pass an out-of-range date to UNIX_TIMESTAMP()
, it returns 0
.
mysql> -> 1447431666 mysql> -> 1447431619 mysql> -> 1447431619.012 SELECT UNIX_TIMESTAMP();SELECT UNIX_TIMESTAMP('2015-11-13 10:20:19');SELECT UNIX_TIMESTAMP('2015-11-13 10:20:19.012');
If you use UNIX_TIMESTAMP()
and FROM_UNIXTIME()
to convert between values in a non-UTC time zone and Unix timestamp values, the conversion is lossy because the mapping is not one-to-one in both directions. For example, due to conventions for local time zone changes such as Daylight Saving Time (DST), it is possible for UNIX_TIMESTAMP()
to map two values that are distinct in a non-UTC time zone to the same Unix timestamp value. FROM_UNIXTIME()
will map that value back to only one of the original values. Here is an example, using values that are distinct in the MET
time zone:
mysql> mysql> +---------------------------------------+ | UNIX_TIMESTAMP('2005-03-27 03:00:00') | +---------------------------------------+ | 1111885200 | +---------------------------------------+ mysql> +---------------------------------------+ | UNIX_TIMESTAMP('2005-03-27 02:00:00') | +---------------------------------------+ | 1111885200 | +---------------------------------------+ mysql> +---------------------------+ | FROM_UNIXTIME(1111885200) | +---------------------------+ | 2005-03-27 03:00:00 | +---------------------------+ SET time_zone = 'MET';SELECT UNIX_TIMESTAMP('2005-03-27 03:00:00');SELECT UNIX_TIMESTAMP('2005-03-27 02:00:00');SELECT FROM_UNIXTIME(1111885200);
To use named time zones such as 'MET'
or 'Europe/Amsterdam'
, the time zone tables must be properly set up. For instructions, see Section 5.1.13, 「MySQL Server Time Zone Support」.
If you want to subtract UNIX_TIMESTAMP()
columns, you might want to cast them to signed integers. See Section 12.10, 「Cast Functions and Operators」.
Returns the current UTC date as a value in 'YYYY-MM-DD'
or YYYYMMDD
format, depending on whether the function is used in a string or numeric context.
mysql> -> '2003-08-14', 20030814 SELECT UTC_DATE(), UTC_DATE() + 0;
Returns the current UTC time as a value in 'hh:mm:ss'
or hhmmss
format, depending on whether the function is used in a string or numeric context.
If the fsp
argument is given to specify a fractional seconds precision from 0 to 6, the return value includes a fractional seconds part of that many digits.
mysql> -> '18:07:53', 180753.000000 SELECT UTC_TIME(), UTC_TIME() + 0;
UTC_TIMESTAMP
, UTC_TIMESTAMP([
fsp
])
Returns the current UTC date and time as a value in 'YYYY-MM-DD hh:mm:ss'
or YYYYMMDDhhmmss
format, depending on whether the function is used in a string or numeric context.
If the fsp
argument is given to specify a fractional seconds precision from 0 to 6, the return value includes a fractional seconds part of that many digits.
mysql> -> '2003-08-14 18:08:04', 20030814180804.000000 SELECT UTC_TIMESTAMP(), UTC_TIMESTAMP() + 0;
This function returns the week number for date
. The two-argument form of WEEK()
enables you to specify whether the week starts on Sunday or Monday and whether the return value should be in the range from 0
to 53
or from 1
to 53
. If the mode
argument is omitted, the value of the default_week_format
system variable is used. See Section 5.1.8, 「Server System Variables」.
The following table describes how the mode
argument works.
Mode | First day of week | Range | Week 1 is the first week … |
---|---|---|---|
0 | Sunday | 0-53 | with a Sunday in this year |
1 | Monday | 0-53 | with 4 or more days this year |
2 | Sunday | 1-53 | with a Sunday in this year |
3 | Monday | 1-53 | with 4 or more days this year |
4 | Sunday | 0-53 | with 4 or more days this year |
5 | Monday | 0-53 | with a Monday in this year |
6 | Sunday | 1-53 | with 4 or more days this year |
7 | Monday | 1-53 | with a Monday in this year |
For mode
values with a meaning of 「with 4 or more days this year,」 weeks are numbered according to ISO 8601:1988:
If the week containing January 1 has 4 or more days in the new year, it is week 1.
Otherwise, it is the last week of the previous year, and the next week is week 1.
mysql> -> 7 mysql> -> 7 mysql> -> 8 mysql> -> 53 SELECT WEEK('2008-02-20');SELECT WEEK('2008-02-20',0);SELECT WEEK('2008-02-20',1);SELECT WEEK('2008-12-31',1);
If a date falls in the last week of the previous year, MySQL returns 0
if you do not use 2
, 3
, 6
, or 7
as the optional mode
argument:
mysql> -> 2000, 0 SELECT YEAR('2000-01-01'), WEEK('2000-01-01',0);
One might argue that WEEK()
should return 52
because the given date actually occurs in the 52nd week of 1999. WEEK()
returns 0
instead so that the return value is 「the week number in the given year.」 This makes use of the WEEK()
function reliable when combined with other functions that extract a date part from a date.
If you prefer a result evaluated with respect to the year that contains the first day of the week for the given date, use 0
, 2
, 5
, or 7
as the optional mode
argument.
mysql> -> 52 SELECT WEEK('2000-01-01',2);
Alternatively, use the YEARWEEK()
function:
mysql> -> 199952 mysql> -> '52' SELECT YEARWEEK('2000-01-01');SELECT MID(YEARWEEK('2000-01-01'),5,2);
Returns the weekday index for date
(0
= Monday, 1
= Tuesday, … 6
= Sunday).
mysql> -> 6 mysql> -> 1 SELECT WEEKDAY('2008-02-03 22:23:00');SELECT WEEKDAY('2007-11-06');
Returns the calendar week of the date as a number in the range from 1
to 53
. WEEKOFYEAR()
is a compatibility function that is equivalent to WEEK(
.date
,3)
mysql> -> 8 SELECT WEEKOFYEAR('2008-02-20');
Returns the year for date
, in the range 1000
to 9999
, or 0
for the 「zero」 date.
mysql> -> 1987 SELECT YEAR('1987-01-01');
YEARWEEK(
, date
)YEARWEEK(
date
,mode
)
Returns year and week for a date. The year in the result may be different from the year in the date argument for the first and the last week of the year.
The mode
argument works exactly like the mode
argument to WEEK()
. For the single-argument syntax, a mode
value of 0 is used. Unlike WEEK()
, the value of default_week_format
does not influence YEARWEEK()
.
mysql> -> 198652 SELECT YEARWEEK('1987-01-01');
The week number is different from what the WEEK()
function would return (0
) for optional arguments 0
or 1
, as WEEK()
then returns the week in the context of the given year.
MySQL uses what is known as a proleptic Gregorian calendar.
Every country that has switched from the Julian to the Gregorian calendar has had to discard at least ten days during the switch. To see how this works, consider the month of October 1582, when the first Julian-to-Gregorian switch occurred.
Monday | Tuesday | Wednesday | Thursday | Friday | Saturday | Sunday |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
There are no dates between October 4 and October 15. This discontinuity is called the cutover. Any dates before the cutover are Julian, and any dates following the cutover are Gregorian. Dates during a cutover are nonexistent.
A calendar applied to dates when it was not actually in use is called proleptic. Thus, if we assume there was never a cutover and Gregorian rules always rule, we have a proleptic Gregorian calendar. This is what is used by MySQL, as is required by standard SQL. For this reason, dates prior to the cutover stored as MySQL DATE
or DATETIME
values must be adjusted to compensate for the difference. It is important to realize that the cutover did not occur at the same time in all countries, and that the later it happened, the more days were lost. For example, in Great Britain, it took place in 1752, when Wednesday September 2 was followed by Thursday September 14. Russia remained on the Julian calendar until 1918, losing 13 days in the process, and what is popularly referred to as its 「October Revolution」 occurred in November according to the Gregorian calendar.
MATCH (
col1
,col2
,...) AGAINST (expr
[search_modifier
])
{ IN NATURAL LANGUAGE MODE | IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION | IN BOOLEAN MODE | WITH QUERY EXPANSION } search_modifier:
MySQL has support for full-text indexing and searching:
A full-text index in MySQL is an index of type FULLTEXT
.
Full-text indexes can be used only with InnoDB
or MyISAM
tables, and can be created only for CHAR
, VARCHAR
, or TEXT
columns.
MySQL
provides a built-in full-text ngram parser that supports Chinese, Japanese, and Korean (CJK), and an installable MeCab full-text parser plugin for Japanese. Parsing differences are outlined in Section 12.9.8, 「ngram Full-Text Parser」, and Section 12.9.9, 「MeCab Full-Text Parser Plugin」.
A FULLTEXT
index definition can be given in the CREATE TABLE
statement when a table is created, or added later using ALTER TABLE
or CREATE INDEX
.
For large data sets, it is much faster to load your data into a table that has no FULLTEXT
index and then create the index after that, than to load data into a table that has an existing FULLTEXT
index.
Full-text searching is performed using MATCH() ... AGAINST
syntax. MATCH()
takes a comma-separated list that names the columns to be searched. AGAINST
takes a string to search for, and an optional modifier that indicates what type of search to perform. The search string must be a string value that is constant during query evaluation. This rules out, for example, a table column because that can differ for each row.
There are three types of full-text searches:
A natural language search interprets the search string as a phrase in natural human language (a phrase in free text). There are no special operators, with the exception of double quote (") characters. The stopword list applies. For more information about stopword lists, see Section 12.9.4, 「Full-Text Stopwords」.
Full-text searches are natural language searches if the IN NATURAL LANGUAGE MODE
modifier is given or if no modifier is given. For more information, see Section 12.9.1, 「Natural Language Full-Text Searches」.
A boolean search interprets the search string using the rules of a special query language. The string contains the words to search for. It can also contain operators that specify requirements such that a word must be present or absent in matching rows, or that it should be weighted higher or lower than usual. Certain common words (stopwords) are omitted from the search index and do not match if present in the search string. The IN BOOLEAN MODE
modifier specifies a boolean search. For more information, see Section 12.9.2, 「Boolean Full-Text Searches」.
A query expansion search is a modification of a natural language search. The search string is used to perform a natural language search. Then words from the most relevant rows returned by the search are added to the search string and the search is done again. The query returns the rows from the second search. The IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION
or WITH QUERY EXPANSION
modifier specifies a query expansion search. For more information, see Section 12.9.3, 「Full-Text Searches with Query Expansion」.
For information about FULLTEXT
query performance, see Section 8.3.5, 「Column Indexes」.
For more information about InnoDB
FULLTEXT
indexes, see Section 15.6.2.4, 「InnoDB FULLTEXT Indexes」.
Constraints on full-text searching are listed in Section 12.9.5, 「Full-Text Restrictions」.
The myisam_ftdump utility dumps the contents of a MyISAM
full-text index. This may be helpful for debugging full-text queries. See Section 4.6.3, 「myisam_ftdump — Display Full-Text Index information」.
By default or with the IN NATURAL LANGUAGE MODE
modifier, the MATCH()
function performs a natural language search for a string against a text collection. A collection is a set of one or more columns included in a FULLTEXT
index. The search string is given as the argument to AGAINST()
. For each row in the table, MATCH()
returns a relevance value; that is, a similarity measure between the search string and the text in that row in the columns named in the MATCH()
list.
mysql> Query OK, 0 rows affected (0.08 sec) mysql> Query OK, 6 rows affected (0.01 sec) Records: 6 Duplicates: 0 Warnings: 0 mysql> +----+-------------------+------------------------------------------+ | id | title | body | +----+-------------------+------------------------------------------+ | 1 | MySQL Tutorial | DBMS stands for DataBase ... | | 5 | MySQL vs. YourSQL | In the following database comparison ... | +----+-------------------+------------------------------------------+ 2 rows in set (0.00 sec) CREATE TABLE articles (id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,title VARCHAR(200),body TEXT,FULLTEXT (title,body)) ENGINE=InnoDB;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 ...');SELECT * FROM articlesWHERE MATCH (title,body)AGAINST ('database' IN NATURAL LANGUAGE MODE);
By default, the search is performed in case-insensitive fashion. To perform a case-sensitive full-text search, use a case-sensitive or binary collation for the indexed columns. For example, a column that uses the utf8mb4
character set of can be assigned a collation of utf8mb4_0900_as_cs
or utf8mb4_bin
to make it case-sensitive for full-text searches.
When MATCH()
is used in a WHERE
clause, as in the example shown earlier, the rows returned are automatically sorted with the highest relevance first. Relevance values are nonnegative floating-point numbers. Zero relevance means no similarity. Relevance is computed based on the number of words in the row (document), the number of unique words in the row, the total number of words in the collection, and the number of rows that contain a particular word.
The term 「document」 may be used interchangeably with the term 「row」, and both terms refer to the indexed part of the row. The term 「collection」 refers to the indexed columns and encompasses all rows.
To simply count matches, you could use a query like this:
mysql> +----------+ | COUNT(*) | +----------+ | 2 | +----------+ 1 row in set (0.00 sec) SELECT COUNT(*) FROM articlesWHERE MATCH (title,body)AGAINST ('database' IN NATURAL LANGUAGE MODE);
You might find it quicker to rewrite the query as follows:
mysql> +-------+ | count | +-------+ | 2 | +-------+ 1 row in set (0.03 sec) SELECTCOUNT(IF(MATCH (title,body) AGAINST ('database' IN NATURAL LANGUAGE MODE), 1, NULL))AS countFROM articles;
The first query does some extra work (sorting the results by relevance) but also can use an index lookup based on the WHERE
clause. The index lookup might make the first query faster if the search matches few rows. The second query performs a full table scan, which might be faster than the index lookup if the search term was present in most rows.
For natural-language full-text searches, the columns named in the MATCH()
function must be the same columns included in some FULLTEXT
index in your table. For the preceding query, note that the columns named in the MATCH()
function (title
and body
) are the same as those named in the definition of the article
table's FULLTEXT
index. To search the title
or body
separately, you would create separate FULLTEXT
indexes for each column.
You can also perform a boolean search or a search with query expansion. These search types are described in Section 12.9.2, 「Boolean Full-Text Searches」, and Section 12.9.3, 「Full-Text Searches with Query Expansion」.
A full-text search that uses an index can name columns only from a single table in the MATCH()
clause because an index cannot span multiple tables. For MyISAM
tables, a boolean search can be done in the absence of an index (albeit more slowly), in which case it is possible to name columns from multiple tables.
The preceding example is a basic illustration that shows how to use the MATCH()
function where rows are returned in order of decreasing relevance. The next example shows how to retrieve the relevance values explicitly. Returned rows are not ordered because the SELECT
statement includes neither WHERE
nor ORDER BY
clauses:
mysql> +----+---------------------+ | id | score | +----+---------------------+ | 1 | 0.22764469683170319 | | 2 | 0 | | 3 | 0.22764469683170319 | | 4 | 0 | | 5 | 0 | | 6 | 0 | +----+---------------------+ 6 rows in set (0.00 sec) SELECT id, MATCH (title,body)AGAINST ('Tutorial' IN NATURAL LANGUAGE MODE) AS scoreFROM articles;
The following example is more complex. The query returns the relevance values and it also sorts the rows in order of decreasing relevance. To achieve this result, specify MATCH()
twice: once in the SELECT
list and once in the WHERE
clause. This causes no additional overhead, because the MySQL optimizer notices that the two MATCH()
calls are identical and invokes the full-text search code only once.
mysql> +----+-------------------------------------+-----------------+ | id | body | score | +----+-------------------------------------+-----------------+ | 4 | 1. Never run mysqld as root. 2. ... | 1.5219271183014 | | 6 | When configured properly, MySQL ... | 1.3114095926285 | +----+-------------------------------------+-----------------+ 2 rows in set (0.00 sec) SELECT id, body, MATCH (title,body) AGAINST('Security implications of running MySQL as root'IN NATURAL LANGUAGE MODE) AS scoreFROM articles WHERE MATCH (title,body) AGAINST('Security implications of running MySQL as root'IN NATURAL LANGUAGE MODE);
A phrase that is enclosed within double quote ("
) characters matches only rows that contain the phrase literally, as it was typed. The full-text engine splits the phrase into words and performs a search in the FULLTEXT
index for the words. Nonword characters need not be matched exactly: Phrase searching requires only that matches contain exactly the same words as the phrase and in the same order. For example, "test phrase"
matches "test, phrase"
. If the phrase contains no words that are in the index, the result is empty. For example, if all words are either stopwords or shorter than the minimum length of indexed words, the result is empty.
The MySQL FULLTEXT
implementation regards any sequence of true word characters (letters, digits, and underscores) as a word. That sequence may also contain apostrophes ('
), but not more than one in a row. This means that aaa'bbb
is regarded as one word, but aaa''bbb
is regarded as two words. Apostrophes at the beginning or the end of a word are stripped by the FULLTEXT
parser; 'aaa'bbb'
would be parsed as aaa'bbb
.
The built-in FULLTEXT
parser determines where words start and end by looking for certain delimiter characters; for example,
(space), ,
(comma), and .
(period). If words are not separated by delimiters (as in, for example, Chinese), the built-in FULLTEXT
parser cannot determine where a word begins or ends. To be able to add words or other indexed terms in such languages to a FULLTEXT
index that uses the built-in FULLTEXT
parser, you must preprocess them so that they are separated by some arbitrary delimiter. Alternatively, you can create FULLTEXT
indexes using the ngram parser plugin (for Chinese, Japanese, or Korean) or the MeCab parser plugin (for Japanese).
It is possible to write a plugin that replaces the built-in full-text parser. For details, see Section 29.2, 「The MySQL Plugin API」. For example parser plugin source code, see the plugin/fulltext
directory of a MySQL source distribution.
Some words are ignored in full-text searches:
Any word that is too short is ignored. The default minimum length of words that are found by full-text searches is three characters for InnoDB
search indexes, or four characters for MyISAM
. You can control the cutoff by setting a configuration option before creating the index: innodb_ft_min_token_size
configuration option for InnoDB
search indexes, or ft_min_word_len
for MyISAM
.
This behavior does not apply to FULLTEXT
indexes that use the ngram parser. For the ngram parser, token length is defined by the ngram_token_size
option.
Words in the stopword list are ignored. A stopword is a word such as 「the」 or 「some」 that is so common that it is considered to have zero semantic value. There is a built-in stopword list, but it can be overridden by a user-defined list. The stopword lists and related configuration options are different for InnoDB
search indexes and MyISAM
ones. Stopword processing is controlled by the configuration options innodb_ft_enable_stopword
, innodb_ft_server_stopword_table
, and innodb_ft_user_stopword_table
for InnoDB
search indexes, and ft_stopword_file
for MyISAM
ones.
See Section 12.9.4, 「Full-Text Stopwords」 to view default stopword lists and how to change them. The default minimum word length can be changed as described in Section 12.9.6, 「Fine-Tuning MySQL Full-Text Search」.
Every correct word in the collection and in the query is weighted according to its significance in the collection or query. Thus, a word that is present in many documents has a lower weight, because it has lower semantic value in this particular collection. Conversely, if the word is rare, it receives a higher weight. The weights of the words are combined to compute the relevance of the row. This technique works best with large collections.
For very small tables, word distribution does not adequately reflect their semantic value, and this model may sometimes produce bizarre results for search indexes on MyISAM
tables. For example, although the word 「MySQL」 is present in every row of the articles
table shown earlier, a search for the word in a MyISAM
search index produces no results:
mysql> Empty set (0.00 sec) SELECT * FROM articlesWHERE MATCH (title,body)AGAINST ('MySQL' IN NATURAL LANGUAGE MODE);
The search result is empty because the word 「MySQL」 is present in at least 50% of the rows, and so is effectively treated as a stopword. This filtering technique is more suitable for large data sets, where you might not want the result set to return every second row from a 1GB table, than for small data sets where it might cause poor results for popular terms.
The 50% threshold can surprise you when you first try full-text searching to see how it works, and makes InnoDB
tables more suited to experimentation with full-text searches. If you create a MyISAM
table and insert only one or two rows of text into it, every word in the text occurs in at least 50% of the rows. As a result, no search returns any results until the table contains more rows. Users who need to bypass the 50% limitation can build search indexes on InnoDB
tables, or use the boolean search mode explained in Section 12.9.2, 「Boolean Full-Text Searches」.
MySQL can perform boolean full-text searches using the IN BOOLEAN MODE
modifier. With this modifier, certain characters have special meaning at the beginning or end of words in the search string. In the following query, the +
and -
operators indicate that a word must be present or absent, respectively, for a match to occur. Thus, the query retrieves all the rows that contain the word 「MySQL」 but that do not contain the word 「YourSQL」:
mysql> +----+-----------------------+-------------------------------------+ | id | title | body | +----+-----------------------+-------------------------------------+ | 1 | MySQL Tutorial | DBMS stands for DataBase ... | | 2 | How To Use MySQL Well | After you went through a ... | | 3 | Optimizing MySQL | In this tutorial we will show ... | | 4 | 1001 MySQL Tricks | 1. Never run mysqld as root. 2. ... | | 6 | MySQL Security | When configured properly, MySQL ... | +----+-----------------------+-------------------------------------+ SELECT * FROM articles WHERE MATCH (title,body)AGAINST ('+MySQL -YourSQL' IN BOOLEAN MODE);
In implementing this feature, MySQL uses what is sometimes referred to as implied Boolean logic, in which
+
stands for AND
-
stands for NOT
[no operator] implies OR
Boolean full-text searches have these characteristics:
They do not automatically sort rows in order of decreasing relevance.
InnoDB
tables require a FULLTEXT
index on all columns of the MATCH()
expression to perform boolean queries. Boolean queries against a MyISAM
search index can work even without a FULLTEXT
index, although a search executed in this fashion would be quite slow.
The minimum and maximum word length full-text parameters apply to FULLTEXT
indexes created using the built-in FULLTEXT
parser and MeCab parser plugin. innodb_ft_min_token_size
and innodb_ft_max_token_size
are used for InnoDB
search indexes. ft_min_word_len
and ft_max_word_len
are used for MyISAM
search indexes.
Minimum and maximum word length full-text parameters do not apply to FULLTEXT
indexes created using the ngram parser. ngram token size is defined by the ngram_token_size
option.
The stopword list applies, controlled by innodb_ft_enable_stopword
, innodb_ft_server_stopword_table
, and innodb_ft_user_stopword_table
for InnoDB
search indexes, and ft_stopword_file
for MyISAM
ones.
InnoDB
full-text search does not support the use of multiple operators on a single search word, as in this example: '++apple'
. Use of multiple operators on a single search word returns a syntax error to standard out. MyISAM full-text search will successfully process the same search ignoring all operators except for the operator immediately adjacent to the search word.
InnoDB
full-text search only supports leading plus or minus signs. For example, InnoDB
supports '+apple'
but does not support 'apple+'
. Specifying a trailing plus or minus sign causes InnoDB
to report a syntax error.
InnoDB
full-text search does not support the use of a leading plus sign with wildcard ('+*'
), a plus and minus sign combination ('+-'
), or leading a plus and minus sign combination ('+-apple'
). These invalid queries return a syntax error.
InnoDB
full-text search does not support the use of the @
symbol in boolean full-text searches. The @
symbol is reserved for use by the @distance
proximity search operator.
They do not use the 50% threshold that applies to MyISAM
search indexes.
The boolean full-text search capability supports the following operators:
+
A leading or trailing plus sign indicates that this word must be present in each row that is returned. InnoDB
only supports leading plus signs.
-
A leading or trailing minus sign indicates that this word must not be present in any of the rows that are returned. InnoDB
only supports leading minus signs.
Note: The -
operator acts only to exclude rows that are otherwise matched by other search terms. Thus, a boolean-mode search that contains only terms preceded by -
returns an empty result. It does not return 「all rows except those containing any of the excluded terms.」
(no operator)
By default (when neither +
nor -
is specified), the word is optional, but the rows that contain it are rated higher. This mimics the behavior of MATCH() ... AGAINST()
without the IN BOOLEAN MODE
modifier.
@
distance
This operator works on InnoDB
tables only. It tests whether two or more words all start within a specified distance from each other, measured in words. Specify the search words within a double-quoted string immediately before the @
operator, for example, distance
MATCH(col1) AGAINST('"word1 word2 word3" @8' IN BOOLEAN MODE)
> <
These two operators are used to change a word's contribution to the relevance value that is assigned to a row. The >
operator increases the contribution and the <
operator decreases it. See the example following this list.
( )
Parentheses group words into subexpressions. Parenthesized groups can be nested.
~
A leading tilde acts as a negation operator, causing the word's contribution to the row's relevance to be negative. This is useful for marking 「noise」 words. A row containing such a word is rated lower than others, but is not excluded altogether, as it would be with the -
operator.
*
The asterisk serves as the truncation (or wildcard) operator. Unlike the other operators, it is appended to the word to be affected. Words match if they begin with the word preceding the *
operator.
If a word is specified with the truncation operator, it is not stripped from a boolean query, even if it is too short or a stopword. Whether a word is too short is determined from the innodb_ft_min_token_size
setting for InnoDB
tables, or ft_min_word_len
for MyISAM
tables. These options are not applicable to FULLTEXT
indexes that use the ngram parser.
The wildcarded word is considered as a prefix that must be present at the start of one or more words. If the minimum word length is 4, a search for '+
could return fewer rows than a search for word
+the*''+
, because the second query ignores the too-short search term word
+the'the
.
"
A phrase that is enclosed within double quote ("
) characters matches only rows that contain the phrase literally, as it was typed. The full-text engine splits the phrase into words and performs a search in the FULLTEXT
index for the words. Nonword characters need not be matched exactly: Phrase searching requires only that matches contain exactly the same words as the phrase and in the same order. For example, "test phrase"
matches "test, phrase"
.
If the phrase contains no words that are in the index, the result is empty. The words might not be in the index because of a combination of factors: if they do not exist in the text, are stopwords, or are shorter than the minimum length of indexed words.
The following examples demonstrate some search strings that use boolean full-text operators:
'apple banana'
Find rows that contain at least one of the two words.
'+apple +juice'
Find rows that contain both words.
'+apple macintosh'
Find rows that contain the word 「apple」, but rank rows higher if they also contain 「macintosh」.
'+apple -macintosh'
Find rows that contain the word 「apple」 but not 「macintosh」.
'+apple ~macintosh'
Find rows that contain the word 「apple」, but if the row also contains the word 「macintosh」, rate it lower than if row does not. This is 「softer」 than a search for '+apple -macintosh'
, for which the presence of 「macintosh」 causes the row not to be returned at all.
'+apple +(>turnover <strudel)'
Find rows that contain the words 「apple」 and 「turnover」, or 「apple」 and 「strudel」 (in any order), but rank 「apple turnover」 higher than 「apple strudel」.
'apple*'
Find rows that contain words such as 「apple」, 「apples」, 「applesauce」, or 「applet」.
'"some words"'
Find rows that contain the exact phrase 「some words」 (for example, rows that contain 「some words of wisdom」 but not 「some noise words」). Note that the "
characters that enclose the phrase are operator characters that delimit the phrase. They are not the quotation marks that enclose the search string itself.
InnoDB
full-text search is modeled on the Sphinx full-text search engine, and the algorithms used are based on BM25 and TF-IDF ranking algorithms. For these reasons, relevancy rankings for InnoDB
boolean full-text search may differ from MyISAM
relevancy rankings.
InnoDB
uses a variation of the 「term frequency-inverse document frequency」 (TF-IDF
) weighting system to rank a document's relevance for a given full-text search query. The TF-IDF
weighting is based on how frequently a word appears in a document, offset by how frequently the word appears in all documents in the collection. In other words, the more frequently a word appears in a document, and the less frequently the word appears in the document collection, the higher the document is ranked.
The term frequency (TF
) value is the number of times that a word appears in a document. The inverse document frequency (IDF
) value of a word is calculated using the following formula, where total_records
is the number of records in the collection, and matching_records
is the number of records that the search term appears in.
${IDF} = log10( ${total_records} / ${matching_records} )
When a document contains a word multiple times, the IDF value is multiplied by the TF value:
${TF} * ${IDF}
Using the TF
and IDF
values, the relevancy ranking for a document is calculated using this formula:
${rank} = ${TF} * ${IDF} * ${IDF}
The formula is demonstrated in the following examples.
This example demonstrates the relevancy ranking calculation for a single-word search.
mysql> CREATE TABLE articles ( id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, title VARCHAR(200), body TEXT, FULLTEXT (title,body) ) ENGINE=InnoDB; Query OK, 0 rows affected (1.04 sec) mysql> INSERT INTO articles (title,body) VALUES ('MySQL Tutorial','This database tutorial ...'), ("How To Use MySQL",'After you went through a ...'), ('Optimizing Your Database','In this database tutorial ...'), ('MySQL vs. YourSQL','When comparing databases ...'), ('MySQL Security','When configured properly, MySQL ...'), ('Database, Database, Database','database database database'), ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'), ('MySQL Full-Text Indexes', 'MySQL fulltext indexes use a ..'); Query OK, 8 rows affected (0.06 sec) Records: 8 Duplicates: 0 Warnings: 0 mysql> SELECT id, title, body, MATCH (title,body) AGAINST ('database' IN BOOLEAN MODE) AS score FROM articles ORDER BY score DESC; +----+------------------------------+-------------------------------------+---------------------+ | id | title | body | score | +----+------------------------------+-------------------------------------+---------------------+ | 6 | Database, Database, Database | database database database | 1.0886961221694946 | | 3 | Optimizing Your Database | In this database tutorial ... | 0.36289870738983154 | | 1 | MySQL Tutorial | This database tutorial ... | 0.18144935369491577 | | 2 | How To Use MySQL | After you went through a ... | 0 | | 4 | MySQL vs. YourSQL | When comparing databases ... | 0 | | 5 | MySQL Security | When configured properly, MySQL ... | 0 | | 7 | 1001 MySQL Tricks | 1. Never run mysqld as root. 2. ... | 0 | | 8 | MySQL Full-Text Indexes | MySQL fulltext indexes use a .. | 0 | +----+------------------------------+-------------------------------------+---------------------+ 8 rows in set (0.00 sec)
There are 8 records in total, with 3 that match the 「database」 search term. The first record (id 6
) contains the search term 6 times and has a relevancy ranking of 1.0886961221694946
. This ranking value is calculated using a TF
value of 6 (the 「database」 search term appears 6 times in record id 6
) and an IDF
value of 0.42596873216370745, which is calculated as follows (where 8 is the total number of records and 3 is the number of records that the search term appears in):
${IDF} = log10( 8 / 3 ) = 0.42596873216370745
The TF
and IDF
values are then entered into the ranking formula:
${rank} = ${TF} * ${IDF} * ${IDF}
Performing the calculation in the MySQL command-line client returns a ranking value of 1.088696164686938.
mysql> SELECT 6*log10(8/3)*log10(8/3); +-------------------------+ | 6*log10(8/3)*log10(8/3) | +-------------------------+ | 1.088696164686938 | +-------------------------+ 1 row in set (0.00 sec)
You may notice a slight difference in the ranking values returned by the SELECT ... MATCH ... AGAINST
statement and the MySQL command-line client (1.0886961221694946
versus 1.088696164686938
). The difference is due to how the casts between integers and floats/doubles are performed internally by InnoDB
(along with related precision and rounding decisions), and how they are performed elsewhere, such as in the MySQL command-line client or other types of calculators.
This example demonstrates the relevancy ranking calculation for a multiple-word full-text search based on the articles
table and data used in the previous example.
If you search on more than one word, the relevancy ranking value is a sum of the relevancy ranking value for each word, as shown in this formula:
${rank} = ${TF} * ${IDF} * ${IDF} + ${TF} * ${IDF} * ${IDF}
Performing a search on two terms ('mysql tutorial') returns the following results:
mysql> SELECT id, title, body, MATCH (title,body) AGAINST ('mysql tutorial' IN BOOLEAN MODE) AS score FROM articles ORDER BY score DESC; +----+------------------------------+-------------------------------------+----------------------+ | id | title | body | score | +----+------------------------------+-------------------------------------+----------------------+ | 1 | MySQL Tutorial | This database tutorial ... | 0.7405621409416199 | | 3 | Optimizing Your Database | In this database tutorial ... | 0.3624762296676636 | | 5 | MySQL Security | When configured properly, MySQL ... | 0.031219376251101494 | | 8 | MySQL Full-Text Indexes | MySQL fulltext indexes use a .. | 0.031219376251101494 | | 2 | How To Use MySQL | After you went through a ... | 0.015609688125550747 | | 4 | MySQL vs. YourSQL | When comparing databases ... | 0.015609688125550747 | | 7 | 1001 MySQL Tricks | 1. Never run mysqld as root. 2. ... | 0.015609688125550747 | | 6 | Database, Database, Database | database database database | 0 | +----+------------------------------+-------------------------------------+----------------------+ 8 rows in set (0.00 sec)
In the first record (id 8
), 'mysql' appears once and 'tutorial' appears twice. There are six matching records for 'mysql' and two matching records for 'tutorial'. The MySQL command-line client returns the expected ranking value when inserting these values into the ranking formula for a multiple word search:
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 row in set (0.00 sec)
The slight difference in the ranking values returned by the SELECT ... MATCH ... AGAINST
statement and the MySQL command-line client is explained in the preceding example.
Full-text search supports query expansion (and in particular, its variant 「blind query expansion」). This is generally useful when a search phrase is too short, which often means that the user is relying on implied knowledge that the full-text search engine lacks. For example, a user searching for 「database」 may really mean that 「MySQL」, 「Oracle」, 「DB2」, and 「RDBMS」 all are phrases that should match 「databases」 and should be returned, too. This is implied knowledge.
Blind query expansion (also known as automatic relevance feedback) is enabled by adding WITH QUERY EXPANSION
or IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION
following the search phrase. It works by performing the search twice, where the search phrase for the second search is the original search phrase concatenated with the few most highly relevant documents from the first search. Thus, if one of these documents contains the word 「databases」 and the word 「MySQL」, the second search finds the documents that contain the word 「MySQL」 even if they do not contain the word 「database」. The following example shows this difference:
mysql> +----+-------------------+------------------------------------------+ | id | title | body | +----+-------------------+------------------------------------------+ | 1 | MySQL Tutorial | DBMS stands for DataBase ... | | 5 | MySQL vs. YourSQL | In the following database comparison ... | +----+-------------------+------------------------------------------+ 2 rows in set (0.00 sec) mysql> +----+-----------------------+------------------------------------------+ | id | title | body | +----+-----------------------+------------------------------------------+ | 5 | MySQL vs. YourSQL | In the following database comparison ... | | 1 | MySQL Tutorial | DBMS stands for DataBase ... | | 3 | Optimizing MySQL | In this tutorial we will show ... | | 6 | MySQL Security | When configured properly, MySQL ... | | 2 | How To Use MySQL Well | After you went through a ... | | 4 | 1001 MySQL Tricks | 1. Never run mysqld as root. 2. ... | +----+-----------------------+------------------------------------------+ 6 rows in set (0.00 sec) SELECT * FROM articlesWHERE MATCH (title,body)AGAINST ('database' IN NATURAL LANGUAGE MODE);SELECT * FROM articlesWHERE MATCH (title,body)AGAINST ('database' WITH QUERY EXPANSION);
Another example could be searching for books by Georges Simenon about Maigret, when a user is not sure how to spell 「Maigret」. A search for 「Megre and the reluctant witnesses」 finds only 「Maigret and the Reluctant Witnesses」 without query expansion. A search with query expansion finds all books with the word 「Maigret」 on the second pass.
Because blind query expansion tends to increase noise significantly by returning nonrelevant documents, use it only when a search phrase is short.
The stopword list is loaded and searched for full-text queries using the server character set and collation (the values of the character_set_server
and collation_server
system variables). False hits or misses might occur for stopword lookups if the stopword file or columns used for full-text indexing or searches have a character set or collation different from character_set_server
or collation_server
.
Case sensitivity of stopword lookups depends on the server collation. For example, lookups are case insensitive if the collation is utf8mb4_0900_ai_ci
, whereas lookups are case-sensitive if the collation is utf8mb4_0900_as_cs
or utf8mb4_bin
.
InnoDB
has a relatively short list of default stopwords, because documents from technical, literary, and other sources often use short words as keywords or in significant phrases. For example, you might search for 「to be or not to be」 and expect to get a sensible result, rather than having all those words ignored.
To see the default InnoDB
stopword list, query the INFORMATION_SCHEMA.INNODB_FT_DEFAULT_STOPWORD
table.
mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_DEFAULT_STOPWORD; +-------+ | value | +-------+ | a | | about | | an | | are | | as | | at | | be | | by | | com | | de | | en | | for | | from | | how | | i | | in | | is | | it | | la | | of | | on | | or | | that | | the | | this | | to | | was | | what | | when | | where | | who | | will | | with | | und | | the | | www | +-------+ 36 rows in set (0.00 sec)
To define your own stopword list for all InnoDB
tables, define a table with the same structure as the INNODB_FT_DEFAULT_STOPWORD
table, populate it with stopwords, and set the value of the innodb_ft_server_stopword_table
option to a value in the form
before creating the full-text index. The stopword table must have a single db_name
/table_name
VARCHAR
column named value
. The following example demonstrates creating and configuring a new global stopword table for InnoDB
.
-- Create a new stopword table mysql> CREATE TABLE my_stopwords(value VARCHAR(30)) ENGINE = INNODB; Query OK, 0 rows affected (0.01 sec) -- Insert stopwords (for simplicity, a single stopword is used in this example) mysql> INSERT INTO my_stopwords(value) VALUES ('Ishmael'); Query OK, 1 row affected (0.00 sec) -- Create the table mysql> CREATE TABLE opening_lines ( id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, opening_line TEXT(500), author VARCHAR(200), title VARCHAR(200) ) ENGINE=InnoDB; Query OK, 0 rows affected (0.01 sec) -- Insert data into the table mysql> INSERT INTO opening_lines(opening_line,author,title) VALUES ('Call me Ishmael.','Herman Melville','Moby-Dick'), ('A screaming comes across the sky.','Thomas Pynchon','Gravity\'s Rainbow'), ('I am an invisible man.','Ralph Ellison','Invisible Man'), ('Where now? Who now? When now?','Samuel Beckett','The Unnamable'), ('It was love at first sight.','Joseph Heller','Catch-22'), ('All this happened, more or less.','Kurt Vonnegut','Slaughterhouse-Five'), ('Mrs. Dalloway said she would buy the flowers herself.','Virginia Woolf','Mrs. Dalloway'), ('It was a pleasure to burn.','Ray Bradbury','Fahrenheit 451'); Query OK, 8 rows affected (0.00 sec) Records: 8 Duplicates: 0 Warnings: 0 -- Set the innodb_ft_server_stopword_table option to the new stopword table mysql> SET GLOBAL innodb_ft_server_stopword_table = 'test/my_stopwords'; Query OK, 0 rows affected (0.00 sec) -- Create the full-text index (which rebuilds the table if no FTS_DOC_ID column is defined) mysql> CREATE FULLTEXT INDEX idx ON opening_lines(opening_line); Query OK, 0 rows affected, 1 warning (1.17 sec) Records: 0 Duplicates: 0 Warnings: 1
Verify that the specified stopword ('Ishmael') does not appear by querying the words in INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE
.
By default, words less than 3 characters in length or greater than 84 characters in length do not appear in an InnoDB
full-text search index. Maximum and minimum word length values are configurable using the innodb_ft_max_token_size
and innodb_ft_min_token_size
variables. This default behavior does not apply to the ngram parser plugin. ngram token size is defined by the ngram_token_size
option.
mysql> SET GLOBAL innodb_ft_aux_table='test/opening_lines'; Query OK, 0 rows affected (0.00 sec) mysql> SELECT word FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE LIMIT 15; +-----------+ | word | +-----------+ | across | | all | | burn | | buy | | call | | comes | | dalloway | | first | | flowers | | happened | | herself | | invisible | | less | | love | | man | +-----------+ 15 rows in set (0.00 sec)
To create stopword lists on a table-by-table basis, create other stopword tables and use the innodb_ft_user_stopword_table
option to specify the stopword table that you want to use before you create the full-text index.
The stopword file is loaded and searched using latin1
if character_set_server
is ucs2
, utf16
, utf16le
, or utf32
.
To override the default stopword list for MyISAM tables, set the ft_stopword_file
system variable. (See Section 5.1.8, 「Server System Variables」.) The variable value should be the path name of the file containing the stopword list, or the empty string to disable stopword filtering. The server looks for the file in the data directory unless an absolute path name is given to specify a different directory. After changing the value of this variable or the contents of the stopword file, restart the server and rebuild your FULLTEXT
indexes.
The stopword list is free-form, separating stopwords with any nonalphanumeric character such as newline, space, or comma. Exceptions are the underscore character (_
) and a single apostrophe ('
) which are treated as part of a word. The character set of the stopword list is the server's default character set; see Section 10.3.2, 「Server Character Set and Collation」.
The following list shows the default stopwords for MyISAM
search indexes. In a MySQL source distribution, you can find this list in the storage/myisam/ft_static.c
file.
a's able about above according accordingly across actually after afterwards again against ain't all allow allows almost alone along already also although always am among amongst an and another any anybody anyhow anyone anything anyway anyways anywhere apart appear appreciate appropriate are aren't around as aside ask asking associated at available away awfully be became because become becomes becoming been before beforehand behind being believe below beside besides best better between beyond both brief but by c'mon c's came can can't cannot cant cause causes certain certainly changes clearly co com come comes concerning consequently consider considering contain containing contains corresponding could couldn't course currently definitely described despite did didn't different do does doesn't doing don't done down downwards during each edu eg eight either else elsewhere enough entirely especially et etc even ever every everybody everyone everything everywhere ex exactly example except far few fifth first five followed following follows for former formerly forth four from further furthermore get gets getting given gives go goes going gone got gotten greetings had hadn't happens hardly has hasn't have haven't having he he's hello help hence her here here's hereafter hereby herein hereupon hers herself hi him himself his hither hopefully how howbeit however i'd i'll i'm i've ie if ignored immediate in inasmuch inc indeed indicate indicated indicates inner insofar instead into inward is isn't it it'd it'll it's its itself just keep keeps kept know known knows last lately later latter latterly least less lest let let's like liked likely little look looking looks ltd mainly many may maybe me mean meanwhile merely might more moreover most mostly much must my myself name namely nd near nearly necessary need needs neither never nevertheless new next nine no nobody non none noone nor normally not nothing novel now nowhere obviously of off often oh ok okay old on once one ones only onto or other others otherwise ought our ours ourselves out outside over overall own particular particularly per perhaps placed please plus possible presumably probably provides que quite qv rather rd re really reasonably regarding regardless regards relatively respectively right said same saw say saying says second secondly see seeing seem seemed seeming seems seen self selves sensible sent serious seriously seven several shall she should shouldn't since six so some somebody somehow someone something sometime sometimes somewhat somewhere soon sorry specified specify specifying still sub such sup sure t's take taken tell tends th than thank thanks thanx that that's thats the their theirs them themselves then thence there there's thereafter thereby therefore therein theres thereupon these they they'd they'll they're they've think third this thorough thoroughly those though three through throughout thru thus to together too took toward towards tried tries truly try trying twice two un under unfortunately unless unlikely until unto up upon us use used useful uses using usually value various very via viz vs want wants was wasn't way we we'd we'll we're we've welcome well went were weren't what what's whatever when whence whenever where where's whereafter whereas whereby wherein whereupon wherever whether which while whither who who's whoever whole whom whose why will willing wish with within without won't wonder would wouldn't yes yet you you'd you'll you're you've your yours yourself yourselves zero
Full-text searches are supported for InnoDB
and MyISAM
tables only.
Full-text searches are not supported for partitioned tables. See Section 23.6, 「Restrictions and Limitations on Partitioning」.
Full-text searches can be used with most multibyte character sets. The exception is that for Unicode, the utf8
character set can be used, but not the ucs2
character set. Although FULLTEXT
indexes on ucs2
columns cannot be used, you can perform IN BOOLEAN MODE
searches on a ucs2
column that has no such index.
The remarks for utf8
also apply to utf8mb4
, and the remarks for ucs2
also apply to utf16
, utf16le
, and utf32
.
Ideographic languages such as Chinese and Japanese do not have word delimiters. Therefore, the built-in full-text parser cannot determine where words begin and end in these and other such languages.
A character-based ngram full-text parser that supports Chinese, Japanese, and Korean (CJK), and a word-based MeCab parser plugin that supports Japanese are provided for use with InnoDB
and MyISAM
tables.
Although the use of multiple character sets within a single table is supported, all columns in a FULLTEXT
index must use the same character set and collation.
The MATCH()
column list must match exactly the column list in some FULLTEXT
index definition for the table, unless this MATCH()
is IN BOOLEAN MODE
on a MyISAM
table. For MyISAM
tables, boolean-mode searches can be done on nonindexed columns, although they are likely to be slow.
The argument to AGAINST()
must be a string value that is constant during query evaluation. This rules out, for example, a table column because that can differ for each row.
Index hints are more limited for FULLTEXT
searches than for non-FULLTEXT
searches. See Section 8.9.4, 「Index Hints」.
For InnoDB
, all DML operations (INSERT
, UPDATE
, DELETE
) involving columns with full-text indexes are processed at transaction commit time. For example, for an INSERT
operation, an inserted string is tokenized and decomposed into individual words. The individual words are then added to full-text index tables when the transaction is committed. As a result, full-text searches only return committed data.
The '%' character is not a supported wildcard character for full-text searches.
MySQL's full-text search capability has few user-tunable parameters. You can exert more control over full-text searching behavior if you have a MySQL source distribution because some changes require source code modifications. See Section 2.9, 「Installing MySQL from Source」.
Full-text search is carefully tuned for effectiveness. Modifying the default behavior in most cases can actually decrease effectiveness. Do not alter the MySQL sources unless you know what you are doing.
Most full-text variables described in this section must be set at server startup time. A server restart is required to change them; they cannot be modified while the server is running.
Some variable changes require that you rebuild the FULLTEXT
indexes in your tables. Instructions for doing so are given later in this section.
The minimum and maximum lengths of words to be indexed are defined by the innodb_ft_min_token_size
and innodb_ft_max_token_size
for InnoDB
search indexes, and ft_min_word_len
and ft_max_word_len
for MyISAM
ones.
Minimum and maximum word length full-text parameters do not apply to FULLTEXT
indexes created using the ngram parser. ngram token size is defined by the ngram_token_size
option.
After changing any of these options, rebuild your FULLTEXT
indexes for the change to take effect. For example, to make two-character words searchable, you could put the following lines in an option file:
[mysqld] innodb_ft_min_token_size=2 ft_min_word_len=2
Then restart the server and rebuild your FULLTEXT
indexes. For MyISAM
tables, note the remarks regarding myisamchk in the instructions that follow for rebuilding MyISAM
full-text indexes.
For MyISAM
search indexes, the 50% threshold for natural language searches is determined by the particular weighting scheme chosen. To disable it, look for the following line in storage/myisam/ftdefs.h
:
#define GWS_IN_USE GWS_PROB
Change that line to this:
#define GWS_IN_USE GWS_FREQ
Then recompile MySQL. There is no need to rebuild the indexes in this case.
By making this change, you severely decrease MySQL's ability to provide adequate relevance values for the MATCH()
function. If you really need to search for such common words, it would be better to search using IN BOOLEAN MODE
instead, which does not observe the 50% threshold.
To change the operators used for boolean full-text searches on MyISAM
tables, set the ft_boolean_syntax
system variable. (InnoDB
does not have an equivalent setting.) This variable can be changed while the server is running, but you must have privileges sufficient to set global system variables (see Section 5.1.9.1, 「System Variable Privileges」). No rebuilding of indexes is necessary in this case.
For the built-in full-text parser, you can change the set of characters that are considered word characters in several ways, as described in the following list. After making the modification, rebuild the indexes for each table that contains any FULLTEXT
indexes. Suppose that you want to treat the hyphen character ('-') as a word character. Use one of these methods:
Modify the MySQL source: In storage/innobase/handler/ha_innodb.cc
(for InnoDB
), or in storage/myisam/ftdefs.h
(for MyISAM
), see the true_word_char()
and misc_word_char()
macros. Add '-'
to one of those macros and recompile MySQL.
Modify a character set file: This requires no recompilation. The true_word_char()
macro uses a 「character type」 table to distinguish letters and numbers from other characters. . You can edit the contents of the <ctype><map>
array in one of the character set XML files to specify that '-'
is a 「letter.」 Then use the given character set for your FULLTEXT
indexes. For information about the <ctype><map>
array format, see Section 10.12.1, 「Character Definition Arrays」.
Add a new collation for the character set used by the indexed columns, and alter the columns to use that collation. For general information about adding collations, see Section 10.13, 「Adding a Collation to a Character Set」. For an example specific to full-text indexing, see Section 12.9.7, 「Adding a Collation for Full-Text Indexing」.
For the changes to take effect, FULLTEXT
indexes must be rebuilt after modifying any of the following full-text index variables: 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
. Modifying innodb_ft_min_token_size
, innodb_ft_max_token_size
, or ngram_token_size
requires restarting the server.
To rebuild FULLTEXT
indexes for an InnoDB
table, use ALTER TABLE
with the DROP INDEX
and ADD INDEX
options to drop and re-create each index.
Running OPTIMIZE TABLE
on a table with a full-text index rebuilds the full-text index, removing deleted Document IDs and consolidating multiple entries for the same word, where possible.
To optimize a full-text index, enable innodb_optimize_fulltext_only
and run OPTIMIZE TABLE
.
mysql> set GLOBAL innodb_optimize_fulltext_only=ON; Query OK, 0 rows affected (0.01 sec) mysql> OPTIMIZE TABLE opening_lines; +--------------------+----------+----------+----------+ | Table | Op | Msg_type | Msg_text | +--------------------+----------+----------+----------+ | test.opening_lines | optimize | status | OK | +--------------------+----------+----------+----------+ 1 row in set (0.01 sec)
To avoid lengthy rebuild times for full-text indexes on large tables, you can use the innodb_ft_num_word_optimize
option to perform the optimization in stages. The innodb_ft_num_word_optimize
option defines the number of words that are optimized each time OPTIMIZE TABLE
is run. The default setting is 2000, which means that 2000 words are optimized each time OPTIMIZE TABLE
is run. Subsequent OPTIMIZE TABLE
operations continue from where the preceding OPTIMIZE TABLE
operation ended.
If you modify full-text variables that affect indexing (ft_min_word_len
, ft_max_word_len
, or ft_stopword_file
), or if you change the stopword file itself, you must rebuild your FULLTEXT
indexes after making the changes and restarting the server.
To rebuild the FULLTEXT
indexes for a MyISAM
table, it is sufficient to do a QUICK
repair operation:
mysql>
REPAIR TABLE tbl_name
QUICK;tbl_name
Alternatively, use ALTER TABLE
as just described. In some cases, this may be faster than a repair operation.
Each table that contains any FULLTEXT
index must be repaired as just shown. Otherwise, queries for the table may yield incorrect results, and modifications to the table will cause the server to see the table as corrupt and in need of repair.
If you use myisamchk to perform an operation that modifies MyISAM
table indexes (such as repair or analyze), the FULLTEXT
indexes are rebuilt using the default full-text parameter values for minimum word length, maximum word length, and stopword file unless you specify otherwise. This can result in queries failing.
The problem occurs because these parameters are known only by the server. They are not stored in MyISAM
index files. To avoid the problem if you have modified the minimum or maximum word length or stopword file values used by the server, specify the same ft_min_word_len
, ft_max_word_len
, and ft_stopword_file
values for myisamchk that you use for mysqld. For example, if you have set the minimum word length to 3, you can repair a table with myisamchk like this:
myisamchk --recover --ft_min_word_len=3 .MYI tbl_name
To ensure that myisamchk and the server use the same values for full-text parameters, place each one in both the [mysqld]
and [myisamchk]
sections of an option file:
[mysqld] ft_min_word_len=3 [myisamchk] ft_min_word_len=3
An alternative to using myisamchk for MyISAM
table index modification is to use the REPAIR TABLE
, ANALYZE TABLE
, OPTIMIZE TABLE
, or ALTER TABLE
statements. These statements are performed by the server, which knows the proper full-text parameter values to use.
This section describes how to add a new collation for full-text searches using the built-in full-text parser. The sample collation is like latin1_swedish_ci
but treats the '-'
character as a letter rather than as a punctuation character so that it can be indexed as a word character. General information about adding collations is given in Section 10.13, 「Adding a Collation to a Character Set」; it is assumed that you have read it and are familiar with the files involved.
To add a collation for full-text indexing, use the following procedure. The instructions here add a collation for a simple character set, which as discussed in Section 10.13, 「Adding a Collation to a Character Set」, can be created using a configuration file that describes the character set properties. For a complex character set such as Unicode, create collations using C source files that describe the character set properties.
Add a collation to the Index.xml
file. The collation ID must be unused, so choose a value different from 1000 if that ID is already taken on your system.
<charset name="latin1"> ... <collation name="latin1_fulltext_ci" id="1000"/> </charset>
Declare the sort order for the collation in the latin1.xml
file. In this case, the order can be copied from latin1_swedish_ci
:
<collation name="latin1_fulltext_ci"> <map> 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 </map> </collation>
Modify the ctype
array in latin1.xml
. Change the value corresponding to 0x2D (which is the code for the '-'
character) from 10 (punctuation) to 01 (uppercase letter). In the following array, this is the element in the fourth row down, third value from the end.
<ctype> <map> 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 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 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 </map> </ctype> 01
Restart the server.
To employ the new collation, include it in the definition of columns that are to use it:
mysql> Query OK, 0 rows affected (0.13 sec) mysql> Query OK, 0 rows affected (0.47 sec) DROP TABLE IF EXISTS t1;CREATE TABLE t1 (a TEXT CHARACTER SET latin1 COLLATE latin1_fulltext_ci,FULLTEXT INDEX(a)) ENGINE=InnoDB;
Test the collation to verify that hyphen is considered as a word character:
mysql> Query OK, 3 rows affected (0.22 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql> +------+ | a | +------+ | ---- | +------+ 1 row in set (0.00 sec) INSERT INTO t1 VALUEs ('----'),('....'),('abcd');SELECT * FROM t1 WHERE MATCH a AGAINST ('----' IN BOOLEAN MODE);
The built-in MySQL full-text parser uses the white space between words as a delimiter to determine where words begin and end, which is a limitation when working with ideographic languages that do not use word delimiters. To address this limitation, MySQL provides an ngram full-text parser that supports Chinese, Japanese, and Korean (CJK). The ngram full-text parser is supported for use with InnoDB
and MyISAM
.
MySQL also provides a MeCab full-text parser plugin for Japanese, which tokenizes documents into meaningful words. For more information, see Section 12.9.9, 「MeCab Full-Text Parser Plugin」.
An ngram is a contiguous sequence of n
characters from a given sequence of text. The ngram parser tokenizes a sequence of text into a contiguous sequence of n
characters. For example, you can tokenize 「abcd」 for different values of n
using the ngram full-text parser.
n=1: 'a', 'b', 'c', 'd' n=2: 'ab', 'bc', 'cd' n=3: 'abc', 'bcd' n=4: 'abcd'
The ngram full-text parser is a built-in server plugin. As with other built-in server plugins, it is automatically loaded when the server is started.
The full-text search syntax described in Section 12.9, 「Full-Text Search Functions」 applies to the ngram parser plugin. Differences in parsing behavior are described in this section. Full-text-related configuration options, except for minimum and maximum word length options (innodb_ft_min_token_size
, innodb_ft_max_token_size
, ft_min_word_len
, ft_max_word_len
) are also applicable.
The ngram parser has a default ngram token size of 2 (bigram). For example, with a token size of 2, the ngram parser parses the string 「abc def」 into four tokens: 「ab」, 「bc」, 「de」 and 「ef」.
ngram token size is configurable using the ngram_token_size
configuration option, which has a minimum value of 1 and maximum value of 10.
Typically, ngram_token_size
is set to the size of the largest token that you want to search for. If you only intend to search for single characters, set ngram_token_size
to 1. A smaller token size produces a smaller full-text search index, and faster searches. If you need to search for words comprised of more than one character, set ngram_token_size
accordingly. For example, 「Happy Birthday」 is 「生日快樂」 in simplified Chinese, where 「生日」 is 「birthday」, and 「快樂」 translates as 「happy」. To search on two-character words such as these, set ngram_token_size
to a value of 2 or higher.
As a read-only variable, ngram_token_size
may only be set as part of a startup string or in a configuration file:
Startup string:
mysqld --ngram_token_size=2
Configuration file:
[mysqld] ngram_token_size=2
The following minimum and maximum word length configuration options are ignored for FULLTEXT
indexes that use the ngram parser: innodb_ft_min_token_size
, innodb_ft_max_token_size
, ft_min_word_len
, and ft_max_word_len
.
To create a FULLTEXT
index that uses the ngram parser, specify WITH PARSER ngram
with CREATE TABLE
, ALTER TABLE
, or CREATE INDEX
.
The following example demonstrates creating a table with an ngram
FULLTEXT
index, inserting sample data (Simplified Chinese text), and viewing tokenized data in the INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE
table.
mysql> USE test; mysql> CREATE TABLE articles ( id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, title VARCHAR(200), body TEXT, FULLTEXT (title,body) WITH PARSER ngram ) ENGINE=InnoDB CHARACTER SET utf8mb4; mysql> SET NAMES utf8mb4; INSERT INTO articles (title,body) VALUES ('數據庫管理','在本教程中我將向你展現如何管理數據庫'), ('數據庫應用開發','學習開發數據庫應用程序'); mysql> SET GLOBAL innodb_ft_aux_table="test/articles"; mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE ORDER BY doc_id, position;
To add a FULLTEXT
index to an existing table, you can use ALTER TABLE
or CREATE INDEX
. For example:
CREATE TABLE articles ( id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, title VARCHAR(200), body TEXT ) ENGINE=InnoDB CHARACTER SET utf8; ALTER TABLE articles ADD FULLTEXT INDEX ft_index (title,body) WITH PARSER ngram; # Or: CREATE FULLTEXT INDEX ft_index ON articles (title,body) WITH PARSER ngram;
The ngram parser eliminates spaces when parsing. For example:
「ab cd」 is parsed to 「ab」, 「cd」
「a bc」 is parsed to 「bc」
The built-in MySQL full-text parser compares words to entries in the stopword list. If a word is equal to an entry in the stopword list, the word is excluded from the index. For the ngram parser, stopword handling is performed differently. Instead of excluding tokens that are equal to entries in the stopword list, the ngram parser excludes tokens that contain stopwords. For example, assuming ngram_token_size=2
, a document that contains 「a,b」 is parsed to 「a,」 and 「,b」. If a comma (「,」) is defined as a stopword, both 「a,」 and 「,b」 are excluded from the index because they contain a comma.
By default, the ngram parser uses the default stopword list, which contains a list of English stopwords. For a stopword list applicable to Chinese, Japanese, or Korean, you must create your own. For information about creating a stopword list, see Section 12.9.4, 「Full-Text Stopwords」.
Stopwords greater in length than ngram_token_size
are ignored.
For natural language mode search, the search term is converted to a union of ngram terms. For example, the string 「abc」 (assuming ngram_token_size=2
) is converted to 「ab bc」. Given two documents, one containing 「ab」 and the other containing 「abc」, the search term 「ab bc」 matches both documents.
For boolean mode search, the search term is converted to an ngram phrase search. For example, the string 'abc' (assuming ngram_token_size=2
) is converted to '「ab bc」'. Given two documents, one containing 'ab' and the other containing 'abc', the search phrase '「ab bc」' only matches the document containing 'abc'.
Because an ngram FULLTEXT
index contains only ngrams, and does not contain information about the beginning of terms, wildcard searches may return unexpected results. The following behaviors apply to wildcard searches using ngram FULLTEXT
search indexes:
If the prefix term of a wildcard search is shorter than ngram token size, the query returns all indexed rows that contain ngram tokens starting with the prefix term. For example, assuming ngram_token_size=2
, a search on 「a*」 returns all rows starting with 「a」.
If the prefix term of a wildcard search is longer than ngram token size, the prefix term is converted to an ngram phrase and the wildcard operator is ignored. For example, assuming ngram_token_size=2
, an 「abc*」 wildcard search is converted to 「ab bc」.
Phrase searches are converted to ngram phrase searches. For example, The search phrase 「abc」 is converted to 「ab bc」, which returns documents containing 「abc」 and 「ab bc」.
The search phrase 「abc def」 is converted to 「ab bc de ef」, which returns documents containing 「abc def」 and 「ab bc de ef」. A document that contains 「abcdef」 is not returned.
The built-in MySQL full-text parser uses the white space between words as a delimiter to determine where words begin and end, which is a limitation when working with ideographic languages that do not use word delimiters. To address this limitation for Japanese, MySQL provides a MeCab full-text parser plugin. The MeCab full-text parser plugin is supported for use with InnoDB
and MyISAM
.
MySQL also provides an ngram full-text parser plugin that supports Japanese. For more information, see Section 12.9.8, 「ngram Full-Text Parser」.
The MeCab full-text parser plugin is a full-text parser plugin for Japanese that tokenizes a sequence of text into meaningful words. For example, MeCab tokenizes 「データベース管理」 (「Database Management」) into 「データベース」 (「Database」) and 「管理」 (「Management」). By comparison, the ngram full-text parser tokenizes text into a contiguous sequence of n
characters, where n
represents a number between 1 and 10.
In addition to tokenizing text into meaningful words, MeCab indexes are typically smaller than ngram indexes, and MeCab full-text searches are generally faster. One drawback is that it may take longer for the MeCab full-text parser to tokenize documents, compared to the ngram full-text parser.
The full-text search syntax described in Section 12.9, 「Full-Text Search Functions」 applies to the MeCab parser plugin. Differences in parsing behavior are described in this section. Full-text related configuration options are also applicable.
For additional information about the MeCab parser, refer to the MeCab: Yet Another Part-of-Speech and Morphological Analyzer project on Github.
The MeCab parser plugin requires mecab
and mecab-ipadic
.
On supported Fedora, Debian and Ubuntu platforms (except Ubuntu 12.04 where the system mecab
version is too old), MySQL dynamically links to the system mecab
installation if it is installed to the default location. On other supported Unix-like platforms, libmecab.so
is statically linked in libpluginmecab.so
, which is located in the MySQL plugin directory. mecab-ipadic
is included in MySQL binaries and is located in
.MYSQL_HOME
\lib\mecab
You can install mecab
and mecab-ipadic
using a native package management utility (on Fedora, Debian, and Ubuntu), or you can build mecab
and mecab-ipadic
from source. For information about installing mecab
and mecab-ipadic
using a native package management utility, see Installing MeCab From a Binary Distribution (Optional). If you want to build mecab
and mecab-ipadic
from source, see Building MeCab From Source (Optional).
On Windows, libmecab.dll
is found in the MySQL bin
directory. mecab-ipadic
is located in
.MYSQL_HOME
/lib/mecab
To install and configure the MeCab parser plugin, perform the following steps:
In the MySQL configuration file, set the mecab_rc_file
configuration option to the location of the mecabrc
configuration file, which is the configuration file for MeCab. If you are using the MeCab package distributed with MySQL, the mecabrc
file is located in MYSQL_HOME/lib/mecab/etc/
.
[mysqld] loose-mecab-rc-file=MYSQL_HOME/lib/mecab/etc/mecabrc
The loose
prefix is an option modifier. The mecab_rc_file
option is not recognized by MySQL until the MeCaB parser plugin is installed but it must be set before attempting to install the MeCaB parser plugin. The loose
prefix allows you restart MySQL without encountering an error due to an unrecognized variable.
If you use your own MeCab installation, or build MeCab from source, the location of the mecabrc
configuration file may differ.
For information about the MySQL configuration file and its location, see Section 4.2.2.2, 「Using Option Files」.
Also in the MySQL configuration file, set the minimum token size to 1 or 2, which are the values recommended for use with the MeCab parser. For InnoDB
tables, minimum token size is defined by the innodb_ft_min_token_size
configuration option, which has a default value of 3. For MyISAM
tables, minimum token size is defined by ft_min_word_len
, which has a default value of 4.
[mysqld] innodb_ft_min_token_size=1
Modify the mecabrc
configuration file to specify the dictionary you want to use. The mecab-ipadic
package distributed with MySQL binaries includes three dictionaries (ipadic_euc-jp
, ipadic_sjis
, and ipadic_utf-8
). The mecabrc
configuration file packaged with MySQL contains and entry similar to the following:
dicdir = /path/to/mysql/lib/mecab/lib/mecab/dic/ipadic_euc-jp
To use the ipadic_utf-8
dictionary, for example, modify the entry as follows:
dicdir=/lib/mecab/dic/ipadic_utf-8MYSQL_HOME
If you are using your own MeCab installation or have built MeCab from source, the default dicdir
entry in the mecabrc
file will differ, as will the dictionaries and their location.
After the MeCab parser plugin is installed, you can use the mecab_charset
status variable to view the character set used with MeCab. The three MeCab dictionaries provided with the MySQL binary support the following character sets.
The ipadic_euc-jp
dictionary supports the ujis
and eucjpms
character sets.
The ipadic_sjis
dictionary supports the sjis
and cp932
character sets.
The ipadic_utf-8
dictionary supports the utf8
and utf8mb4
character sets.
mecab_charset
only reports the first supported character set. For example, the ipadic_utf-8
dictionary supports both utf8
and utf8mb4
. mecab_charset
always reports utf8
when this dictionary is in use.
Restart MySQL.
Install the MeCab parser plugin:
The MeCab parser plugin is installed using INSTALL PLUGIN
syntax. The plugin name is mecab
, and the shared library name is libpluginmecab.so
. For additional information about installing plugins, see Section 5.6.1, 「Installing and Uninstalling Plugins」.
INSTALL PLUGIN mecab SONAME 'libpluginmecab.so';
Once installed, the MeCab parser plugin loads at every normal MySQL restart.
Verify that the MeCab parser plugin is loaded using the SHOW PLUGINS
statement.
mysql> SHOW PLUGINS;
A mecab
plugin should appear in the list of plugins.
To create a FULLTEXT
index that uses the mecab parser, specify WITH PARSER ngram
with CREATE TABLE
, ALTER TABLE
, or CREATE INDEX
.
This example demonstrates creating a table with a mecab
FULLTEXT
index, inserting sample data, and viewing tokenized data in the INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE
table:
mysql> USE test; mysql> CREATE TABLE articles ( id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, title VARCHAR(200), body TEXT, FULLTEXT (title,body) WITH PARSER mecab ) ENGINE=InnoDB CHARACTER SET utf8; mysql> SET NAMES utf8; mysql> INSERT INTO articles (title,body) VALUES ('データベース管理','このチュートリアルでは、私はどのようにデータベースを管理する方法を紹介します'), ('データベースアプリケーション開発','データベースアプリケーションを開発することを學ぶ'); mysql> SET GLOBAL innodb_ft_aux_table="test/articles"; mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE ORDER BY doc_id, position;
To add a FULLTEXT
index to an existing table, you can use ALTER TABLE
or CREATE INDEX
. For example:
CREATE TABLE articles ( id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, title VARCHAR(200), body TEXT ) ENGINE=InnoDB CHARACTER SET utf8; ALTER TABLE articles ADD FULLTEXT INDEX ft_index (title,body) WITH PARSER mecab; # Or: CREATE FULLTEXT INDEX ft_index ON articles (title,body) WITH PARSER mecab;
The MeCab parser uses spaces as separators in query strings. For example, the MeCab parser tokenizes データベース管理 as データベース and 管理.
By default, the MeCab parser uses the default stopword list, which contains a short list of English stopwords. For a stopword list applicable to Japanese, you must create your own. For information about creating stopword lists, see Section 12.9.4, 「Full-Text Stopwords」.
For natural language mode search, the search term is converted to a union of tokens. For example, データベース管理 is converted to データベース 管理.
SELECT COUNT(*) FROM articles WHERE MATCH(title,body) AGAINST('データベース管理' IN NATURAL LANGUAGE MODE);
For boolean mode search, the search term is converted to a search phrase. For example, データベース管理 is converted to データベース 管理.
SELECT COUNT(*) FROM articles WHERE MATCH(title,body) AGAINST('データベース管理' IN BOOLEAN MODE);
Wildcard search terms are not tokenized. A search on データベース管理* is performed on the prefix, データベース管理.
SELECT COUNT(*) FROM articles WHERE MATCH(title,body) AGAINST('データベース*' IN BOOLEAN MODE);
Phrases are tokenized. For example, データベース管理 is tokenized as データベース 管理.
SELECT COUNT(*) FROM articles WHERE MATCH(title,body) AGAINST('"データベース管理"' IN BOOLEAN MODE);
This section describes how to install mecab
and mecab-ipadic
from a binary distribution using a native package management utility. For example, on Fedora, you can use Yum to perform the installation:
yum mecab-devel
On Debian or Ubuntu, you can perform an APT installation:
apt-get install mecab apt-get install mecab-ipadic
If you want to build mecab
and mecab-ipadic
from source, basic installation steps are provided below. For additional information, refer to the MeCab documentation.
Download the tar.gz packages for mecab
and mecab-ipadic
from http://taku910.github.io/mecab/#download. As of February, 2016, the latest available packages are mecab-0.996.tar.gz
and mecab-ipadic-2.7.0-20070801.tar.gz
.
Install mecab
:
tar zxfv mecab-0.996.tar cd mecab-0.996 ./configure make make check su make install
Install mecab-ipadic
:
tar zxfv mecab-ipadic-2.7.0-20070801.tar cd mecab-ipadic-2.7.0-20070801 ./configure make su make install
Compile MySQL using the WITH_MECAB
CMake option. Set the WITH_MECAB
option to system
if you have installed mecab
and mecab-ipadic
to the default location.
-DWITH_MECAB=system
If you defined a custom installation directory, set WITH_MECAB
to the custom directory. For example:
-DWITH_MECAB=/path/to/mecab
Cast functions and operators enable conversion of values from one data type to another.
CONVERT()
with a USING
clause provides a way to convert data between different character sets:
CONVERT( USING ) exprtranscoding_name
In MySQL, transcoding names are the same as the corresponding character set names.
Examples:
SELECT CONVERT(_latin1'Müller' USING utf8); INSERT INTO utf8_table (utf8_column) SELECT CONVERT(latin1_column USING utf8) FROM latin1_table;
You can also use CONVERT()
without USING
or CAST()
to convert strings between different character sets:
CONVERT(, CHAR[()] CHARACTER SET ) CAST( AS CHAR[()] CHARACTER SET ) stringNcharset_namestringNcharset_name
Examples:
SELECT CONVERT('test', CHAR CHARACTER SET utf8); SELECT CAST('test' AS CHAR CHARACTER SET utf8);
If you specify CHARACTER SET
as just shown, the resulting character set and collation are charset_name
charset_name
and the default collation of charset_name
. If you omit CHARACTER SET
, the resulting character set and collation are defined by the charset_name
character_set_connection
and collation_connection
system variables that determine the default connection character set and collation (see Section 10.4, 「Connection Character Sets and Collations」).
A COLLATE
clause is not permitted within a CONVERT()
or CAST()
call, but you can apply it to the function result. For example, this is legal:
SELECT CAST('test' AS CHAR CHARACTER SET utf8) COLLATE utf8_bin;
But this is illegal:
SELECT CAST('test' AS CHAR CHARACTER SET utf8 COLLATE utf8_bin);
Normally, you cannot compare a BLOB
value or other binary string in case-insensitive fashion because binary strings use the binary
character set, which has no collation with the concept of lettercase. To perform a case-insensitive comparison, use the CONVERT()
or CAST()
function to convert the value to a nonbinary string. Comparisons of the resulting string use its collation. For example, if the conversion result character set has a case-insensitive collation, a LIKE
operation is not case-sensitive:
SELECT 'A' LIKE CONVERT( USING latin1) FROM ; blob_coltbl_name
To use a different character set, substitute its name for latin1
in the preceding statement. To specify a particular collation for the converted string, use a COLLATE
clause following the CONVERT()
call:
SELECT 'A' LIKE CONVERT( USING latin1) COLLATE latin1_german1_ci FROM ; blob_coltbl_name
CONVERT()
and CAST()
can be used more generally for comparing strings that are represented in different character sets. For example, a comparison of these strings results in an error because they have different character sets:
mysql> mysql> ERROR 1267 (HY000): Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and (latin2_general_ci,IMPLICIT) for operation '=' SET @s1 = _latin1 'abc', @s2 = _latin2 'abc';SELECT @s1 = @s2;
Converting one of the strings to a character set compatible with the other enables the comparison to occur without error:
mysql> +---------------------------------+ | @s1 = CONVERT(@s2 USING latin1) | +---------------------------------+ | 1 | +---------------------------------+ SELECT @s1 = CONVERT(@s2 USING latin1);
For string literals, another way to specify the character set is to use a character set introducer (_latin1
and _latin2
in the preceding example are instances of introducers). Unlike conversion functions such as CAST()
, or CONVERT()
, which convert a string from one character set to another, an introducer designates a string literal as having a particular character set, with no conversion involved. For more information, see Section 10.3.8, 「Character Set Introducers」.
Character set conversion is also useful preceding lettercase conversion of binary strings. LOWER()
and UPPER()
are ineffective when applied directly to binary strings because the concept of lettercase does not apply. To perform lettercase conversion of a binary string, first convert it to a nonbinary string:
mysql> mysql> +-------------+------------------------------------+ | LOWER(@str) | LOWER(CONVERT(@str USING utf8mb4)) | +-------------+------------------------------------+ | New York | new york | +-------------+------------------------------------+ SET @str = BINARY 'New York';SELECT LOWER(@str), LOWER(CONVERT(@str USING utf8mb4));
If you convert an indexed column using BINARY
, CAST()
, or CONVERT()
, MySQL may not be able to use the index efficiently.
The cast functions are useful for creating a column with a specific type in a CREATE TABLE ... SELECT
statement:
mysql> mysql> *************************** 1. row *************************** Table: new_table Create Table: CREATE TABLE `new_table` ( `c1` date DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 CREATE TABLE new_table SELECT CAST('2000-01-01' AS DATE) AS c1;SHOW CREATE TABLE new_table\G
The cast functions are useful for sorting ENUM
columns in lexical order. Normally, sorting of ENUM
columns occurs using the internal numeric values. Casting the values to CHAR
results in a lexical sort:
SELECT FROM ORDER BY CAST( AS CHAR); enum_coltbl_nameenum_col
CAST()
also changes the result if you use it as part of a more complex expression such as CONCAT('Date: ',CAST(NOW() AS DATE))
.
For temporal values, there is little need to use CAST()
to extract data in different formats. Instead, use a function such as EXTRACT()
, DATE_FORMAT()
, or TIME_FORMAT()
. See Section 12.7, 「Date and Time Functions」.
To cast a string to a number, you normally need do nothing other than use the string value in numeric context:
mysql> -> 2 SELECT 1+'1';
That is also true for hexadecimal and bit literals, which are binary strings by default:
mysql> -> 'A', 65 mysql> -> 'a', 97 SELECT X'41', X'41'+0;SELECT b'1100001', b'1100001'+0;
A string used in an arithmetic operation is converted to a floating-point number during expression evaluation.
A number used in string context is converted to a string:
mysql> -> 'hello you 2' SELECT CONCAT('hello you ',2);
For information about implicit conversion of numbers to strings, see Section 12.2, 「Type Conversion in Expression Evaluation」.
MySQL supports arithmetic with both signed and unsigned 64-bit values. For numeric operators (such as +
or -
) where one of the operands is an unsigned integer, the result is unsigned by default (see Section 12.6.1, 「Arithmetic Operators」). To override this, use the SIGNED
or UNSIGNED
cast operator to cast a value to a signed or unsigned 64-bit integer, respectively.
mysql> -> -1 mysql> -> 18446744073709551615 mysql> -> -1 SELECT 1 - 2;SELECT CAST(1 - 2 AS UNSIGNED);SELECT CAST(CAST(1 - 2 AS UNSIGNED) AS SIGNED);
If either operand is a floating-point value, the result is a floating-point value and is not affected by the preceding rule. (In this context, DECIMAL
column values are regarded as floating-point values.)
mysql> -> -1.0 SELECT CAST(1 AS UNSIGNED) - 2.0;
The SQL mode affects the result of conversion operations (see Section 5.1.11, 「Server SQL Modes」). Examples:
For conversion of a 「zero」 date string to a date, CONVERT()
and CAST()
return NULL
and produce a warning when the NO_ZERO_DATE
SQL mode is enabled.
For integer subtraction, if the NO_UNSIGNED_SUBTRACTION
SQL mode is enabled, the subtraction result is signed even if any operand is unsigned.
The following list describes the available cast functions and operators:
BINARY
expr
The BINARY
operator converts the expression to a binary string. A common use for BINARY
is to force a character string comparison to be done byte by byte rather than character by character, in effect becoming case-sensitive. The BINARY
operator also causes trailing spaces in comparisons to be significant.
mysql> -> 1 mysql> -> 0 mysql> -> 1 mysql> -> 0 SELECT 'a' = 'A';SELECT BINARY 'a' = 'A';SELECT 'a' = 'a ';SELECT BINARY 'a' = 'a ';
In a comparison, BINARY
affects the entire operation; it can be given before either operand with the same result.
For purposes of converting a string expression to a binary string, these constructs are equivalent:
BINARY CAST( AS BINARY) CONVERT( USING BINARY) exprexprexpr
If a value is a string literal, it can be designated as a binary string without performing any conversion by using the _binary
character set introducer:
mysql> -> 1 mysql> -> 0 SELECT 'a' = 'A';SELECT _binary 'a' = 'A';
For information about introducers, see Section 10.3.8, 「Character Set Introducers」.
The BINARY
operator in expressions differs in effect from the BINARY
attribute in character column definitions. A character column defined with the BINARY
attribute is assigned table default character set and the binary (_bin
) collation of that character set. Every nonbinary character set has a _bin
collation. For example, the binary collation for the utf8
character set is utf8_bin
, so if the table default character set is utf8
, these two column definitions are equivalent:
CHAR(10) BINARY CHAR(10) CHARACTER SET utf8 COLLATE utf8_bin
The use of CHARACTER SET binary
in the definition of a CHAR
, VARCHAR
, or TEXT
column causes the column to be treated as the corresponding binary string data type. For example, the following pairs of definitions are equivalent:
CHAR(10) CHARACTER SET binary BINARY(10) VARCHAR(10) CHARACTER SET binary VARBINARY(10) TEXT CHARACTER SET binary BLOB
The CAST()
function takes an expression of any type and produces a result value of the specified type, similar to CONVERT()
. For more information, see the description of CONVERT()
.
CAST()
is standard SQL syntax.
CONVERT(
, expr
,type
)CONVERT(
expr
USING transcoding_name
)
The CONVERT()
function takes an expression of any type and produces a result value of the specified type.
Discussion of CONVERT(
syntax here also applies to expr
, type
)CAST(
, which is equivalent.expr
AS type
)
CONVERT(... USING ...)
is standard SQL syntax. The non-USING
form of CONVERT()
is ODBC syntax.
CONVERT()
with USING
converts data between different character sets. In MySQL, transcoding names are the same as the corresponding character set names. For example, this statement converts the string 'abc'
in the default character set to the corresponding string in the utf8
character set:
SELECT CONVERT('abc' USING utf8);
CONVERT()
without USING
and CAST()
take an expression and a type
value specifying the result type. These type
values are permitted:
BINARY[(
N
)]
Produces a string with the BINARY
data type. See Section 11.4.2, 「The BINARY and VARBINARY Types」 for a description of how this affects comparisons. If the optional length N
is given, BINARY(
causes the cast to use no more than N
)N
bytes of the argument. Values shorter than N
bytes are padded with 0x00
bytes to a length of N
.
CHAR[(
N
)] [charset_info
]
Produces a string with the CHAR
data type. If the optional length N
is given, CHAR(
causes the cast to use no more than N
)N
characters of the argument. No padding occurs for values shorter than N
characters.
With no charset_info
clause, CHAR
produces a string with the default character set. To specify the character set explicitly, these charset_info
values are permitted:
CHARACTER SET
: Produces a string with the given character set.charset_name
ASCII
: Shorthand for CHARACTER SET latin1
.
UNICODE
: Shorthand for CHARACTER SET ucs2
.
In all cases, the string has the default collation for the character set.
DATE
Produces a DATE
value.
DATETIME
Produces a DATETIME
value.
DECIMAL[(
M
[,D
])]
Produces a DECIMAL
value. If the optional M
and D
values are given, they specify the maximum number of digits (the precision) and the number of digits following the decimal point (the scale).
DOUBLE
Produces a DOUBLE
result. Added in MySQL 8.0.17.
FLOAT[(P
)]
If the precision P
is not specified, produces a result of type FLOAT
. If P
is provided and 0 <= < P
<= 24, the result is of type FLOAT
. If 25 <= P
<= 53, the result is of type REAL
. If P
< 0 or P
> 53, an error is returned. Added in MySQL 8.0.17.
JSON
Produces a JSON
value. For details on the rules for conversion of values between JSON
and other types, see Comparison and Ordering of JSON Values.
NCHAR[(
N
)]
Like CHAR
, but produces a string with the national character set. See Section 10.3.7, 「The National Character Set」.
Unlike CHAR
, NCHAR
does not permit trailing character set information to be specified.
REAL
Produces a result of type REAL
. This is actually FLOAT
if REAL_AS_FLOAT
SQL mode is enabled; otherwise the result is of type DOUBLE
.
SIGNED [INTEGER]
Produces a signed integer value.
TIME
Produces a TIME
value.
UNSIGNED [INTEGER]
Produces an unsigned integer value.
Table 12.15 XML Functions
Name | Description |
---|---|
ExtractValue() |
Extract a value from an XML string using XPath notation |
UpdateXML() |
Return replaced XML fragment |
This section discusses XML and related functionality in MySQL.
It is possible to obtain XML-formatted output from MySQL in the mysql and mysqldump clients by invoking them with the --xml
option. See Section 4.5.1, 「mysql — The MySQL Command-Line Client」, and Section 4.5.4, 「mysqldump — A Database Backup Program」.
Two functions providing basic XPath 1.0 (XML Path Language, version 1.0) capabilities are available. Some basic information about XPath syntax and usage is provided later in this section; however, an in-depth discussion of these topics is beyond the scope of this manual, and you should refer to the XML Path Language (XPath) 1.0 standard for definitive information. A useful resource for those new to XPath or who desire a refresher in the basics is the Zvon.org XPath Tutorial, which is available in several languages.
These functions remain under development. We continue to improve these and other aspects of XML and XPath functionality in MySQL 8.0 and onwards. You may discuss these, ask questions about them, and obtain help from other users with them in the MySQL XML User Forum.
XPath expressions used with these functions support user variables and local stored program variables. User variables are weakly checked; variables local to stored programs are strongly checked (see also Bug #26518):
User variables (weak checking). Variables using the syntax $@
(that is, user variables) are not checked. No warnings or errors are issued by the server if a variable has the wrong type or has previously not been assigned a value. This also means the user is fully responsible for any typographical errors, since no warnings will be given if (for example) variable_name
$@myvariable
is used where $@myvariable
was intended.
Example:
mysql> Query OK, 0 rows affected (0.00 sec) mysql> Query OK, 0 rows affected (0.00 sec) mysql> +------+--------------------------------+ | @i | ExtractValue(@xml, '//b[$@i]') | +------+--------------------------------+ | 1 | X | +------+--------------------------------+ 1 row in set (0.00 sec) mysql> +------+--------------------------------+ | @j | ExtractValue(@xml, '//b[$@j]') | +------+--------------------------------+ | 2 | Y | +------+--------------------------------+ 1 row in set (0.00 sec) mysql> +------+--------------------------------+ | @k | ExtractValue(@xml, '//b[$@k]') | +------+--------------------------------+ | NULL | | +------+--------------------------------+ 1 row in set (0.00 sec) SET @xml = '<a><b>X</b><b>Y</b></a>';SET @i =1, @j = 2;SELECT @i, ExtractValue(@xml, '//b[$@i]');SELECT @j, ExtractValue(@xml, '//b[$@j]');SELECT @k, ExtractValue(@xml, '//b[$@k]');
Variables in stored programs (strong checking). Variables using the syntax $
can be declared and used with these functions when they are called inside stored programs. Such variables are local to the stored program in which they are defined, and are strongly checked for type and value.variable_name
Example:
mysql> mysql> -> -> -> -> -> -> -> -> -> Query OK, 0 rows affected (0.01 sec) mysql> mysql> +--------------------------+---+------------------------------+ | xml | i | ExtractValue(xml, '//a[$i]') | +--------------------------+---+------------------------------+ | <a>X</a><a>Y</a><a>Z</a> | 1 | X | +--------------------------+---+------------------------------+ 1 row in set (0.00 sec) +--------------------------+---+------------------------------+ | xml | i | ExtractValue(xml, '//a[$i]') | +--------------------------+---+------------------------------+ | <a>X</a><a>Y</a><a>Z</a> | 2 | Y | +--------------------------+---+------------------------------+ 1 row in set (0.01 sec) +--------------------------+---+------------------------------+ | xml | i | ExtractValue(xml, '//a[$i]') | +--------------------------+---+------------------------------+ | <a>X</a><a>Y</a><a>Z</a> | 3 | Z | +--------------------------+---+------------------------------+ 1 row in set (0.01 sec) DELIMITER |CREATE PROCEDURE myproc ()BEGINDECLARE i INT DEFAULT 1;DECLARE xml VARCHAR(25) DEFAULT '<a>X</a><a>Y</a><a>Z</a>';WHILE i < 4 DOSELECT xml, i, ExtractValue(xml, '//a[$i]');SET i = i+1;END WHILE;END |DELIMITER ;CALL myproc();
Parameters. Variables used in XPath expressions inside stored routines that are passed in as parameters are also subject to strong checking.
Expressions containing user variables or variables local to stored programs must otherwise (except for notation) conform to the rules for XPath expressions containing variables as given in the XPath 1.0 specification.
A user variable used to store an XPath expression is treated as an empty string. Because of this, it is not possible to store an XPath expression as a user variable. (Bug #32911)
ExtractValue(
xml_frag
, xpath_expr
)
ExtractValue()
takes two string arguments, a fragment of XML markup xml_frag
and an XPath expression xpath_expr
(also known as a locator); it returns the text (CDATA
) of the first text node which is a child of the element or elements matched by the XPath expression.
Using this function is the equivalent of performing a match using the xpath_expr
after appending /text()
. In other words, ExtractValue('<a><b>Sakila</b></a>', '/a/b')
and ExtractValue('<a><b>Sakila</b></a>', '/a/b/text()')
produce the same result.
If multiple matches are found, the content of the first child text node of each matching element is returned (in the order matched) as a single, space-delimited string.
If no matching text node is found for the expression (including the implicit /text()
)—for whatever reason, as long as xpath_expr
is valid, and xml_frag
consists of elements which are properly nested and closed—an empty string is returned. No distinction is made between a match on an empty element and no match at all. This is by design.
If you need to determine whether no matching element was found in xml_frag
or such an element was found but contained no child text nodes, you should test the result of an expression that uses the XPath count()
function. For example, both of these statements return an empty string, as shown here:
mysql> +-------------------------------------+ | ExtractValue('<a><b/></a>', '/a/b') | +-------------------------------------+ | | +-------------------------------------+ 1 row in set (0.00 sec) mysql> +-------------------------------------+ | ExtractValue('<a><c/></a>', '/a/b') | +-------------------------------------+ | | +-------------------------------------+ 1 row in set (0.00 sec) SELECT ExtractValue('<a><b/></a>', '/a/b');SELECT ExtractValue('<a><c/></a>', '/a/b');
However, you can determine whether there was actually a matching element using the following:
mysql> +-------------------------------------+ | ExtractValue('<a><b/></a>', 'count(/a/b)') | +-------------------------------------+ | 1 | +-------------------------------------+ 1 row in set (0.00 sec) mysql> +-------------------------------------+ | ExtractValue('<a><c/></a>', 'count(/a/b)') | +-------------------------------------+ | 0 | +-------------------------------------+ 1 row in set (0.01 sec) SELECT ExtractValue('<a><b/></a>', 'count(/a/b)');SELECT ExtractValue('<a><c/></a>', 'count(/a/b)');
ExtractValue()
returns only CDATA
, and does not return any tags that might be contained within a matching tag, nor any of their content (see the result returned as val1
in the following example).
mysql> -> -> -> -> -> +------+------+------+------+---------+ | val1 | val2 | val3 | val4 | val5 | +------+------+------+------+---------+ | ccc | ddd | ddd | | ddd eee | +------+------+------+------+---------+ SELECTExtractValue('<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;
This function uses the current SQL collation for making comparisons with contains()
, performing the same collation aggregation as other string functions (such as CONCAT()
), in taking into account the collation coercibility of their arguments; see Section 10.8.4, 「Collation Coercibility in Expressions」, for an explanation of the rules governing this behavior.
(Previously, binary—that is, case-sensitive—comparison was always used.)
NULL
is returned if xml_frag
contains elements which are not properly nested or closed, and a warning is generated, as shown in this example:
mysql> +-----------------------------------+ | ExtractValue('<a>c</a><b', '//a') | +-----------------------------------+ | NULL | +-----------------------------------+ 1 row in set, 1 warning (0.00 sec) mysql> *************************** 1. row *************************** Level: Warning Code: 1525 Message: Incorrect XML value: 'parse error at line 1 pos 11: END-OF-INPUT unexpected ('>' wanted)' 1 row in set (0.00 sec) mysql> +-------------------------------------+ | ExtractValue('<a>c</a><b/>', '//a') | +-------------------------------------+ | c | +-------------------------------------+ 1 row in set (0.00 sec) SELECT ExtractValue('<a>c</a><b', '//a');SHOW WARNINGS\GSELECT ExtractValue('<a>c</a><b/>', '//a');
UpdateXML(
xml_target
, xpath_expr
, new_xml
)
This function replaces a single portion of a given fragment of XML markup xml_target
with a new XML fragment new_xml
, and then returns the changed XML. The portion of xml_target
that is replaced matches an XPath expression xpath_expr
supplied by the user.
If no expression matching xpath_expr
is found, or if multiple matches are found, the function returns the original xml_target
XML fragment. All three arguments should be strings.
mysql> -> -> -> -> -> -> *************************** 1. row *************************** 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> SELECTUpdateXML('<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
A discussion in depth of XPath syntax and usage are beyond the scope of this manual. Please see the XML Path Language (XPath) 1.0 specification for definitive information. A useful resource for those new to XPath or who are wishing a refresher in the basics is the Zvon.org XPath Tutorial, which is available in several languages.
Descriptions and examples of some basic XPath expressions follow:
/
tag
Matches <
if and only if tag
/><
is the root element.tag
/>
Example: /a
has a match in <a><b/></a>
because it matches the outermost (root) tag. It does not match the inner a
element in <b><a/></b>
because in this instance it is the child of another element.
/
tag1
/tag2
Matches <
if and only if it is a child of tag2
/><
, and tag1
/><
is the root element.tag1
/>
Example: /a/b
matches the b
element in the XML fragment <a><b/></a>
because it is a child of the root element a
. It does not have a match in <b><a/></b>
because in this case, b
is the root element (and hence the child of no other element). Nor does the XPath expression have a match in <a><c><b/></c></a>
; here, b
is a descendant of a
, but not actually a child of a
.
This construct is extendable to three or more elements. For example, the XPath expression /a/b/c
matches the c
element in the fragment <a><b><c/></b></a>
.
//
tag
Matches any instance of <
.tag
>
Example: //a
matches the a
element in any of the following: <a><b><c/></b></a>
; <c><a><b/></a></b>
; <c><b><a/></b></c>
.
//
can be combined with /
. For example, //a/b
matches the b
element in either of the fragments <a><b/></a>
or <c><a><b/></a></c>
.
//
is the equivalent of tag
/descendant-or-self::*/
. A common error is to confuse this with tag
/descendant-or-self::
, although the latter expression can actually lead to very different results, as can be seen here:tag
mysql> Query OK, 0 rows affected (0.00 sec) mysql> +-----------------------------------------+ | @xml | +-----------------------------------------+ | <a><b><c>w</c><b>x</b><d>y</d>z</b></a> | +-----------------------------------------+ 1 row in set (0.00 sec) mysql> +------------------------------+ | ExtractValue(@xml, '//b[1]') | +------------------------------+ | x z | +------------------------------+ 1 row in set (0.00 sec) mysql> +------------------------------+ | ExtractValue(@xml, '//b[2]') | +------------------------------+ | | +------------------------------+ 1 row in set (0.01 sec) mysql> +---------------------------------------------------+ | ExtractValue(@xml, '/descendant-or-self::*/b[1]') | +---------------------------------------------------+ | x z | +---------------------------------------------------+ 1 row in set (0.06 sec) mysql> +---------------------------------------------------+ | ExtractValue(@xml, '/descendant-or-self::*/b[2]') | +---------------------------------------------------+ | | +---------------------------------------------------+ 1 row in set (0.00 sec) mysql> +-------------------------------------------------+ | ExtractValue(@xml, '/descendant-or-self::b[1]') | +-------------------------------------------------+ | z | +-------------------------------------------------+ 1 row in set (0.00 sec) mysql> +-------------------------------------------------+ | ExtractValue(@xml, '/descendant-or-self::b[2]') | +-------------------------------------------------+ | x | +-------------------------------------------------+ 1 row in set (0.00 sec) SET @xml = '<a><b><c>w</c><b>x</b><d>y</d>z</b></a>';SELECT @xml;SELECT ExtractValue(@xml, '//b[1]');SELECT ExtractValue(@xml, '//b[2]');SELECT ExtractValue(@xml, '/descendant-or-self::*/b[1]');SELECT ExtractValue(@xml, '/descendant-or-self::*/b[2]');SELECT ExtractValue(@xml, '/descendant-or-self::b[1]');SELECT ExtractValue(@xml, '/descendant-or-self::b[2]');
The *
operator acts as a 「wildcard」 that matches any element. For example, the expression /*/b
matches the b
element in either of the XML fragments <a><b/></a>
or <c><b/></c>
. However, the expression does not produce a match in the fragment <b><a/></b>
because b
must be a child of some other element. The wildcard may be used in any position: The expression /*/b/*
will match any child of a b
element that is itself not the root element.
You can match any of several locators using the |
(UNION
) operator. For example, the expression //b|//c
matches all b
and c
elements in the XML target.
It is also possible to match an element based on the value of one or more of its attributes. This done using the syntax
. For example, the expression tag
[@attribute
="value
"]//b[@id="idB"]
matches the second b
element in the fragment <a><b id="idA"/><c/><b id="idB"/></a>
. To match against any element having
, use the XPath expression attribute
="value
"//*[
.attribute
="value
"]
To filter multiple attribute values, simply use multiple attribute-comparison clauses in succession. For example, the expression //b[@c="x"][@d="y"]
matches the element <b c="x" d="y"/>
occurring anywhere in a given XML fragment.
To find elements for which the same attribute matches any of several values, you can use multiple locators joined by the |
operator. For example, to match all b
elements whose c
attributes have either of the values 23 or 17, use the expression //b[@c="23"]|//b[@c="17"]
. You can also use the logical or
operator for this purpose: //b[@c="23" or @c="17"]
.
The difference between or
and |
is that or
joins conditions, while |
joins result sets.
XPath Limitations. The XPath syntax supported by these functions is currently subject to the following limitations:
Nodeset-to-nodeset comparison (such as '/a/b[@c=@d]'
) is not supported.
All of the standard XPath comparison operators are supported. (Bug #22823)
Relative locator expressions are resolved in the context of the root node. For example, consider the following query and result:
mysql> -> -> -> +--------+ | result | +--------+ | X Y | +--------+ 1 row in set (0.03 sec) SELECT ExtractValue('<a><b c="1">X</b><b c="2">Y</b></a>','a/b') AS result;
In this case, the locator a/b
resolves to /a/b
.
Relative locators are also supported within predicates. In the following example, d[../@c="1"]
is resolved as /a/b[@c="1"]/d
:
mysql> -> -> -> -> -> -> +--------+ | result | +--------+ | X | +--------+ 1 row in set (0.00 sec) 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;
Locators prefixed with expressions that evaluate as scalar values—including variable references, literals, numbers, and scalar function calls—are not permitted, and their use results in an error.
The ::
operator is not supported in combination with node types such as the following:
axis
::comment()
axis
::text()
axis
::processing-instructions()
axis
::node()
However, name tests (such as
and axis
::name
) are supported, as shown in these examples:axis
::*
mysql> +-------------------------------------------------------+ | ExtractValue('<a><b>x</b><c>y</c></a>','/a/child::b') | +-------------------------------------------------------+ | x | +-------------------------------------------------------+ 1 row in set (0.02 sec) mysql> +-------------------------------------------------------+ | ExtractValue('<a><b>x</b><c>y</c></a>','/a/child::*') | +-------------------------------------------------------+ | x y | +-------------------------------------------------------+ 1 row in set (0.01 sec) SELECT ExtractValue('<a><b>x</b><c>y</c></a>','/a/child::b');SELECT ExtractValue('<a><b>x</b><c>y</c></a>','/a/child::*');
「Up-and-down」 navigation is not supported in cases where the path would lead 「above」 the root element. That is, you cannot use expressions which match on descendants of ancestors of a given element, where one or more of the ancestors of the current element is also an ancestor of the root element (see Bug #16321).
The following XPath functions are not supported, or have known issues as indicated:
id()
lang()
local-name()
name()
namespace-uri()
normalize-space()
starts-with()
string()
substring-after()
substring-before()
translate()
The following axes are not supported:
following-sibling
following
preceding-sibling
preceding
XPath expressions passed as arguments to ExtractValue()
and UpdateXML()
may contain the colon character (:
) in element selectors, which enables their use with markup employing XML namespaces notation. For example:
mysql> Query OK, 0 rows affected (0.00 sec) mysql> +-----------------------------+ | ExtractValue(@xml, '//e:f') | +-----------------------------+ | 444 | +-----------------------------+ 1 row in set (0.00 sec) mysql> +--------------------------------------------+ | UpdateXML(@xml, '//b:c', '<g:h>555</g:h>') | +--------------------------------------------+ | <a>111<g:h>555</g:h></a> | +--------------------------------------------+ 1 row in set (0.00 sec) SET @xml = '<a>111<b:c>222<d>333</d><e:f>444</e:f></b:c></a>';SELECT ExtractValue(@xml, '//e:f');SELECT UpdateXML(@xml, '//b:c', '<g:h>555</g:h>');
This is similar in some respects to what is permitted by Apache Xalan and some other parsers, and is much simpler than requiring namespace declarations or the use of the namespace-uri()
and local-name()
functions.
Error handling. For both ExtractValue()
and UpdateXML()
, the XPath locator used must be valid and the XML to be searched must consist of elements which are properly nested and closed. If the locator is invalid, an error is generated:
mysql>
ERROR 1105 (HY000): XPATH syntax error: '&a'
SELECT ExtractValue('<a>c</a><b/>', '/&a');
If xml_frag
does not consist of elements which are properly nested and closed, NULL
is returned and a warning is generated, as shown in this example:
mysql> +-----------------------------------+ | ExtractValue('<a>c</a><b', '//a') | +-----------------------------------+ | NULL | +-----------------------------------+ 1 row in set, 1 warning (0.00 sec) mysql> *************************** 1. row *************************** Level: Warning Code: 1525 Message: Incorrect XML value: 'parse error at line 1 pos 11: END-OF-INPUT unexpected ('>' wanted)' 1 row in set (0.00 sec) mysql> +-------------------------------------+ | ExtractValue('<a>c</a><b/>', '//a') | +-------------------------------------+ | c | +-------------------------------------+ 1 row in set (0.00 sec) SELECT ExtractValue('<a>c</a><b', '//a');SHOW WARNINGS\GSELECT ExtractValue('<a>c</a><b/>', '//a');
The replacement XML used as the third argument to UpdateXML()
is not checked to determine whether it consists solely of elements which are properly nested and closed.
XPath Injection. code injection occurs when malicious code is introduced into the system to gain unauthorized access to privileges and data. It is based on exploiting assumptions made by developers about the type and content of data input from users. XPath is no exception in this regard.
A common scenario in which this can happen is the case of application which handles authorization by matching the combination of a login name and password with those found in an XML file, using an XPath expression like this one:
//user[login/text()='neapolitan' and password/text()='1c3cr34m']/attribute::id
This is the XPath equivalent of an SQL statement like this one:
SELECT id FROM users WHERE login='neapolitan' AND password='1c3cr34m';
A PHP application employing XPath might handle the login process like this:
<?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 "You are now logged in as user $result[0]."; else echo "Invalid login name or password."; } else exit("Failed to open $file."); ?>
No checks are performed on the input. This means that a malevolent user can 「short-circuit」 the test by entering ' or 1=1
for both the login name and password, resulting in $xpath
being evaluated as shown here:
//user[login/text()='' or 1=1 and password/text()='' or 1=1]/attribute::id
Since the expression inside the square brackets always evaluates as true
, it is effectively the same as this one, which matches the id
attribute of every user
element in the XML document:
//user/attribute::id
One way in which this particular attack can be circumvented is simply by quoting the variable names to be interpolated in the definition of $xpath
, forcing the values passed from a Web form to be converted to strings:
$xpath = "//user[login/text()='$login' and password/text()='$password']/attribute::id";
This is the same strategy that is often recommended for preventing SQL injection attacks. In general, the practices you should follow for preventing XPath injection attacks are the same as for preventing SQL injection:
Never accepted untested data from users in your application.
Check all user-submitted data for type; reject or convert data that is of the wrong type
Test numeric data for out of range values; truncate, round, or reject values that are out of range. Test strings for illegal characters and either strip them out or reject input containing them.
Do not output explicit error messages that might provide an unauthorized user with clues that could be used to compromise the system; log these to a file or database table instead.
Just as SQL injection attacks can be used to obtain information about database schemas, so can XPath injection be used to traverse XML files to uncover their structure, as discussed in Amit Klein's paper Blind XPath Injection (PDF file, 46KB).
It is also important to check the output being sent back to the client. Consider what can happen when we use the MySQL ExtractValue()
function:
mysql> -> -> -> +-------------------------------+ | id | +-------------------------------+ | 00327 13579 02403 42354 28570 | +-------------------------------+ 1 row in set (0.01 sec) SELECT ExtractValue(LOAD_FILE('users.xml'),'//user[login/text()="" or 1=1 and password/text()="" or 1=1]/attribute::id') AS id;
Because ExtractValue()
returns multiple matches as a single space-delimited string, this injection attack provides every valid ID contained within users.xml
to the user as a single row of output. As an extra safeguard, you should also test output before returning it to the user. Here is a simple example:
mysql> -> -> -> Query OK, 0 rows affected (0.00 sec) mysql> -> -> -> -> +----------------------------+ | singleID | +----------------------------+ | Unable to retrieve user ID | +----------------------------+ 1 row in set (0.00 sec) SELECT @id = ExtractValue(LOAD_FILE('users.xml'),'//user[login/text()="" or 1=1 and password/text()="" or 1=1]/attribute::id');SELECT IF(INSTR(@id, ' ') = 0,@id,'Unable to retrieve user ID')AS singleID;
In general, the guidelines for returning data to users securely are the same as for accepting user input. These can be summed up as:
Always test outgoing data for type and permissible values.
Never permit unauthorized users to view error messages that might provide information about the application that could be used to exploit it.
Bit functions and operators comprise BIT_COUNT()
, BIT_AND()
, BIT_OR()
, BIT_XOR()
, &
, |
, ^
, ~
, <<
, and >>
. (The BIT_AND()
, BIT_OR()
, and BIT_XOR()
aggregate functions are described in Section 12.20.1, 「Aggregate (GROUP BY) Function Descriptions」.) Prior to MySQL 8.0, bit functions and operators required BIGINT
(64-bit integer) arguments and returned BIGINT
values, so they had a maximum range of 64 bits. Non-BIGINT
arguments were converted to BIGINT
prior to performing the operation and truncation could occur.
In MySQL 8.0, bit functions and operators permit binary string type arguments (BINARY
, VARBINARY
, and the BLOB
types) and return a value of like type, which enables them to take arguments and produce return values larger than 64 bits. Nonbinary string arguments are converted to BIGINT
and processed as such, as before.
An implication of this change in behavior is that bit operations on binary string arguments might produce a different result in MySQL 8.0 than in 5.7. For information about how to prepare in MySQL 5.7 for potential incompatibilities between MySQL 5.7 and 8.0, see Bit Functions and Operators, in MySQL 5.7 Reference Manual.
Bit operations prior to MySQL 8.0 handle only unsigned 64-bit integer argument and result values (that is, unsigned BIGINT
values). Conversion of arguments of other types to BIGINT
occurs as necessary. Examples:
This statement operates on numeric literals, treated as unsigned 64-bit integers:
mysql> +-----------+----------+---------------+ | 127 | 128 | 128 << 2 | BIT_COUNT(15) | +-----------+----------+---------------+ | 255 | 512 | 4 | +-----------+----------+---------------+ SELECT 127 | 128, 128 << 2, BIT_COUNT(15);
This statement performs to-number conversions on the string arguments ('127'
to 127
, and so forth) before performing the same operations as the first statement and producing the same results:
mysql> +---------------+------------+-----------------+ | '127' | '128' | '128' << 2 | BIT_COUNT('15') | +---------------+------------+-----------------+ | 255 | 512 | 4 | +---------------+------------+-----------------+ SELECT '127' | '128', '128' << 2, BIT_COUNT('15');
This statement uses hexadecimal literals for the bit-operation arguments. MySQL by default treats hexadecimal literals as binary strings, but in numeric context evaluates them as numbers (see Section 9.1.4, 「Hexadecimal Literals」). Prior to MySQL 8.0, numeric context includes bit operations. Examples:
mysql> +---------------+------------+------------------+ | X'7F' | X'80' | X'80' << 2 | BIT_COUNT(X'0F') | +---------------+------------+------------------+ | 255 | 512 | 4 | +---------------+------------+------------------+ SELECT X'7F' | X'80', X'80' << 2, BIT_COUNT(X'0F');
Handling of bit-value literals in bit operations is similar to hexadecimal literals (that is, as numbers).
MySQL 8.0 extends bit operations to handle binary string arguments directly (without conversion) and produce binary string results. (Arguments that are not integers or binary strings are still converted to integers, as before.) This extension enhances bit operations in the following ways:
Bit operations become possible on values longer than 64 bits.
It is easier to perform bit operations on values that are more naturally represented as binary strings than as integers.
For example, consider UUID values and IPv6 addresses, which have human-readable text formats like this:
UUID: 6ccd780c-baba-1026-9564-5b8c656024db IPv6: fe80::219:d1ff:fe91:1a72
It is cumbersome to operate on text strings in those formats. An alternative is convert them to fixed-length binary strings without delimiters. UUID_TO_BIN()
and INET6_ATON()
each produce a value of data type BINARY(16)
, a binary string 16 bytes (128 bits) long. The following statements illustrate this (HEX()
is used to produce displayable values):
mysql> +----------------------------------------------------------+ | HEX(UUID_TO_BIN('6ccd780c-baba-1026-9564-5b8c656024db')) | +----------------------------------------------------------+ | 6CCD780CBABA102695645B8C656024DB | +----------------------------------------------------------+ mysql> +---------------------------------------------+ | HEX(INET6_ATON('fe80::219:d1ff:fe91:1a72')) | +---------------------------------------------+ | FE800000000000000219D1FFFE911A72 | +---------------------------------------------+ SELECT HEX(UUID_TO_BIN('6ccd780c-baba-1026-9564-5b8c656024db'));SELECT HEX(INET6_ATON('fe80::219:d1ff:fe91:1a72'));
Those binary values are easily manipulable with bit operations to perform actions such as extracting the timestamp from UUID values, or extracting the network and host parts of IPv6 addresses. (For examples, see later in this discussion.)
Arguments that count as binary strings include column values, routine parameters, local variables, and user-defined variables that have a binary string type: BINARY
, VARBINARY
, or one of the BLOB
types.
What about hexadecimal literals and bit literals? Recall that those are binary strings by default in MySQL, but numbers in numeric context. How are they handled for bit operations in MySQL 8.0? Does MySQL continue to evaluate them in numeric context, as is done prior to MySQL 8.0? Or do bit operations evaluate them as binary strings, now that binary strings can be handled 「natively」 without conversion?
Answer: It has been common to specify arguments to bit operations using hexadecimal literals or bit literals with the intent that they represent numbers, so MySQL continues to evaluate bit operations in numeric context when all bit arguments are hexadecimal or bit literals, for backward compatility. If you require evaluation as binary strings instead, that is easily accomplished: Use the _binary
introducer for at least one literal.
These bit operations evaluate the hexadecimal literals and bit literals as integers:
mysql> +---------------+---------------------------+ | X'40' | X'01' | b'11110001' & b'01001111' | +---------------+---------------------------+ | 65 | 65 | +---------------+---------------------------+ SELECT X'40' | X'01', b'11110001' & b'01001111';
These bit operations evaluate the hexadecimal literals and bit literals as binary strings, due to the _binary
introducer:
mysql> +-----------------------+-----------------------------------+ | _binary X'40' | X'01' | b'11110001' & _binary b'01001111' | +-----------------------+-----------------------------------+ | A | A | +-----------------------+-----------------------------------+ SELECT _binary X'40' | X'01', b'11110001' & _binary b'01001111';
Although the bit operations in both statements produce a result with a numeric value of 65, the second statement operates in binary-string context, for which 65 is ASCII A
.
In numeric evaluation context, permitted values of hexadecimal literal and bit literal arguments have a maximum of 64 bits, as do results. By contrast, in binary-string evaluation context, permitted arguments (and results) can exceed 64 bits:
mysql> +---------------------------------------------------+ | _binary X'4040404040404040' | X'0102030405060708' | +---------------------------------------------------+ | ABCDEFGH | +---------------------------------------------------+ SELECT _binary X'4040404040404040' | X'0102030405060708';
There are several ways to refer to a hexadecimal literal or bit literal in a bit operation to cause binary-string evaluation:
_binary BINARY CAST( AS BINARY) literalliteralliteral
Another way to produce binary-string evaluation of hexadecimal literals or bit literals is to assign them to user-defined variables, which results in variables that have a binary string type:
mysql> mysql> +-----------+-----------+ | @v1 | @v2 | @v3 & @v4 | +-----------+-----------+ | A | A | +-----------+-----------+ SET @v1 = X'40', @v2 = X'01', @v3 = b'11110001', @v4 = b'01001111';SELECT @v1 | @v2, @v3 & @v4;
In binary-string context, bitwise operation arguments must have the same length or an ER_INVALID_BITWISE_OPERANDS_SIZE
error occurs:
mysql> ERROR 3513 (HY000): Binary operands of bitwise operators must be of equal length SELECT _binary X'40' | X'0001';
To satisfy the equal-length requirement, pad the shorter value with leading zero digits or, if the longer value begins with leading zero digits and a shorter result value is acceptable, strip them:
mysql> +---------------------------+ | _binary X'0040' | X'0001' | +---------------------------+ | A | +---------------------------+ mysql> +-----------------------+ | _binary X'40' | X'01' | +-----------------------+ | A | +-----------------------+ SELECT _binary X'0040' | X'0001';SELECT _binary X'40' | X'01';
Padding or stripping can also be accomplished using functions such as LPAD()
, RPAD()
, SUBSTR()
, or CAST()
. In such cases, the expression arguments are no longer all literals and _binary
becomes unnecessary. Examples:
mysql> +---------------------------------+ | LPAD(X'40', 2, X'00') | X'0001' | +---------------------------------+ | A | +---------------------------------+ mysql> +-------------------------------+ | X'40' | SUBSTR(X'0001', 2, 1) | +-------------------------------+ | A | +-------------------------------+ SELECT LPAD(X'40', 2, X'00') | X'0001';SELECT X'40' | SUBSTR(X'0001', 2, 1);
The following example illustrates use of bit operations to extract parts of a UUID value, in this case, the timestamp and IEEE 802 node number. This technique requires bitmasks for each extracted part.
Convert the text UUID to the corresponding 16-byte binary value so that it can be manipulated using bit operations in binary-string context:
mysql> mysql> +----------------------------------+ | HEX(@uuid) | +----------------------------------+ | 6CCD780CBABA102695645B8C656024DB | +----------------------------------+ SET @uuid = UUID_TO_BIN('6ccd780c-baba-1026-9564-5b8c656024db');SELECT HEX(@uuid);
Construct bitmasks for the timestamp and node number parts of the value. The timestamp comprises the first three parts (64 bits, bits 0 to 63) and the node number is the last part (48 bits, bits 80 to 127):
mysql> mysql> mysql> +----------------------------------+ | HEX(@ts_mask) | +----------------------------------+ | FFFFFFFFFFFFFFFF0000000000000000 | +----------------------------------+ mysql> +----------------------------------+ | HEX(@node_mask) | +----------------------------------+ | 00000000000000000000FFFFFFFFFFFF | +----------------------------------+ SET @ts_mask = CAST(X'FFFFFFFFFFFFFFFF' AS BINARY(16));SET @node_mask = CAST(X'FFFFFFFFFFFF' AS BINARY(16)) >> 80;SELECT HEX(@ts_mask);SELECT HEX(@node_mask);
The CAST(... AS BINARY(16))
function is used here because the masks must be the same length as the UUID value against which they are applied. The same result can be produced using other functions to pad the masks to the required length:
SET @ts_mask= RPAD(X'FFFFFFFFFFFFFFFF' , 16, X'00'); SET @node_mask = LPAD(X'FFFFFFFFFFFF', 16, X'00') ;
Use the masks to extract the timestamp and node number parts:
mysql> +----------------------------------+ | timestamp part | +----------------------------------+ | 6CCD780CBABA10260000000000000000 | +----------------------------------+ mysql> +----------------------------------+ | node part | +----------------------------------+ | 000000000000000000005B8C656024DB | +----------------------------------+ SELECT HEX(@uuid & @ts_mask) AS 'timestamp part';SELECT HEX(@uuid & @node_mask) AS 'node part';
The preceding example uses these bit operations: right shift (>>
) and bitwise AND (&
).
UUID_TO_BIN()
takes a flag that causes some bit rearrangement in the resulting binary UUID value. If you use that flag, modify the extraction masks accordingly.
The next example uses bit operations to extract the network and host parts of an IPv6 address. Suppose that the network part has a length of 80 bits. Then the host part has a length of 128 − 80 = 48 bits. To extract the network and host parts of the address, convert it to a binary string, then use bit operations in binary-string context.
Convert the text IPv6 address to the corresponding binary string:
mysql> SET @ip = INET6_ATON('fe80::219:d1ff:fe91:1a72');
Define the network length in bits:
mysql> SET @net_len = 80;
Construct network and host masks by shifting the all-ones address left or right. To do this, begin with the address ::
, which is shorthand for all zeros, as you can see by converting it to a binary string like this:
mysql> +----------------------------------+ | all zeros | +----------------------------------+ | 00000000000000000000000000000000 | +----------------------------------+ SELECT HEX(INET6_ATON('::')) AS 'all zeros';
To produce the complementary value (all ones), use the ~
operator to invert the bits:
mysql> +----------------------------------+ | all ones | +----------------------------------+ | FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF | +----------------------------------+ SELECT HEX(~INET6_ATON('::')) AS 'all ones';
Shift the all-ones value left or right to produce the network and host masks:
mysql> mysql> SET @net_mask = ~INET6_ATON('::') << (128 - @net_len);SET @host_mask = ~INET6_ATON('::') >> @net_len;
Display the masks to verify that they cover the correct parts of the address:
mysql> +----------------------------+ | network mask | +----------------------------+ | ffff:ffff:ffff:ffff:ffff:: | +----------------------------+ mysql> +------------------------+ | host mask | +------------------------+ | ::ffff:255.255.255.255 | +------------------------+ SELECT INET6_NTOA(@net_mask) AS 'network mask';SELECT INET6_NTOA(@host_mask) AS 'host mask';
Extract and display the network and host parts of the address:
mysql> mysql> mysql> +-----------------+ | network part | +-----------------+ | fe80::219:0:0:0 | +-----------------+ mysql> +------------------+ | host part | +------------------+ | ::d1ff:fe91:1a72 | +------------------+ SET @net_part = @ip & @net_mask;SET @host_part = @ip & @host_mask;SELECT INET6_NTOA(@net_part) AS 'network part';SELECT INET6_NTOA(@host_part) AS 'host part';
The preceding example uses these bit operations: Complement (~
), left shift (<<
), and bitwise AND (&
).
The remaining discussion provides details on argument handling for each group of bit operations, more information about literal-value handling in bit operations, and potential incompatibilities between MySQL 8.0 and older MySQL versions.
For &
, |
, and ^
bit operations, the result type depends on whether the arguments are evaluated as binary strings or numbers:
Binary-string evaluation occurs when the arguments have a binary string type, and at least one of them is not a hexadecimal literal, bit literal, or NULL
literal. Numeric evaluation occurs otherwise, with argument conversion to unsigned 64-bit integers as necessary.
Binary-string evaluation produces a binary string of the same length as the arguments. If the arguments have unequal lengths, an ER_INVALID_BITWISE_OPERANDS_SIZE
error occurs. Numeric evaluation produces an unsigned 64-bit integer.
Examples of numeric evaluation:
mysql> +--------+---------------+ | 64 | 1 | X'40' | X'01' | +--------+---------------+ | 65 | 65 | +--------+---------------+ SELECT 64 | 1, X'40' | X'01';
Examples of binary-string evaluation:
mysql> +-----------------------+ | _binary X'40' | X'01' | +-----------------------+ | A | +-----------------------+ mysql> mysql> +---------------+ | @var1 | @var2 | +---------------+ | A | +---------------+ SELECT _binary X'40' | X'01';SET @var1 = X'40', @var2 = X'01';SELECT @var1 | @var2;
For ~
, <<
, and >>
bit operations, the result type depends on whether the bit argument is evaluated as a binary string or number:
Binary-string evaluation occurs when the bit argument has a binary string type, and is not a hexadecimal literal, bit literal, or NULL
literal. Numeric evaluation occurs otherwise, with argument conversion to an unsigned 64-bit integer as necessary.
Binary-string evaluation produces a binary string of the same length as the bit argument. Numeric evaluation produces an unsigned 64-bit integer.
For shift operations, bits shifted off the end of the value are lost without warning, regardless of the argument type. In particular, if the shift count is greater or equal to the number of bits in the bit argument, all bits in the result are 0.
Examples of numeric evaluation:
mysql> +----------------------+---------+------------+ | ~0 | 64 << 2 | X'40' << 2 | +----------------------+---------+------------+ | 18446744073709551615 | 256 | 256 | +----------------------+---------+------------+ SELECT ~0, 64 << 2, X'40' << 2;
Examples of binary-string evaluation:
mysql> +----------------------------------------+ | HEX(_binary X'1111000022220000' >> 16) | +----------------------------------------+ | 0000111100002222 | +----------------------------------------+ mysql> +----------------------------------------+ | HEX(_binary X'1111000022220000' << 16) | +----------------------------------------+ | 0000222200000000 | +----------------------------------------+ mysql> mysql> +-------------+ | HEX(~@var1) | +-------------+ | 0F0F0F0F | +-------------+ SELECT HEX(_binary X'1111000022220000' >> 16);SELECT HEX(_binary X'1111000022220000' << 16);SET @var1 = X'F0F0F0F0';SELECT HEX(~@var1);
The BIT_COUNT()
function always returns an unsigned 64-bit integer, or NULL
if the argument is NULL
.
mysql> +----------------+ | BIT_COUNT(127) | +----------------+ | 7 | +----------------+ mysql> +----------------------+------------------------------+ | BIT_COUNT(b'010101') | BIT_COUNT(_binary b'010101') | +----------------------+------------------------------+ | 3 | 3 | +----------------------+------------------------------+ SELECT BIT_COUNT(127);SELECT BIT_COUNT(b'010101'), BIT_COUNT(_binary b'010101');
For the BIT_AND()
, BIT_OR()
, and BIT_XOR()
bit functions, the result type depends on whether the function argument values are evaluated as binary strings or numbers:
Binary-string evaluation occurs when the argument values have a binary string type, and the argument is not a hexadecimal literal, bit literal, or NULL
literal. Numeric evaluation occurs otherwise, with argument value conversion to unsigned 64-bit integers as necessary.
Binary-string evaluation produces a binary string of the same length as the argument values. If argument values have unequal lengths, an ER_INVALID_BITWISE_OPERANDS_SIZE
error occurs. If the argument size exceeds 511 bytes, an ER_INVALID_BITWISE_AGGREGATE_OPERANDS_SIZE
error occurs. Numeric evaluation produces an unsigned 64-bit integer.
NULL
values do not affect the result unless all values are NULL
. In that case, the result is a neutral value having the same length as the length of the argument values (all bits 1 for BIT_AND()
, all bits 0 for BIT_OR()
, and BIT_XOR()
).
Example:
mysql> mysql> mysql> mysql> mysql> mysql> mysql> +-----------------+----------------+-----------------+ | HEX(BIT_AND(a)) | HEX(BIT_OR(a)) | HEX(BIT_XOR(a)) | +-----------------+----------------+-----------------+ | FFFFFFFFFFFF | 000000000000 | 000000000000 | | 1234 | FF34 | ED00 | +-----------------+----------------+-----------------+ CREATE TABLE t (group_id INT, a VARBINARY(6));INSERT INTO t VALUES (1, NULL);INSERT INTO t VALUES (1, NULL);INSERT INTO t VALUES (2, NULL);INSERT INTO t VALUES (2, X'1234');INSERT INTO t VALUES (2, X'FF34');SELECT HEX(BIT_AND(a)), HEX(BIT_OR(a)), HEX(BIT_XOR(a))FROM t GROUP BY group_id;
For backward compatibility, MySQL 8.0 evaluates bit operations in numeric context when all bit arguments are hexadecimal literals, bit literals, or NULL
literals. That is, bit operations on binary-string bit arguments do not use binary-string evaluation if all bit arguments are unadorned hexadecimal literals, bit literals, or NULL
literals. (This does not apply to such literals if they are written with a _binary
introducer, BINARY
operator, or other way of specifying them explicitly as binary strings.)
The literal handling just described is the same as prior to MySQL 8.0. Examples:
These bit operations evaluate the literals in numeric context and produce a BIGINT
result:
b'0001' | b'0010' X'0008' << 8
These bit operations evaluate NULL
in numeric context and produce a BIGINT
result that has a NULL
value:
NULL & NULL NULL >> 4
In MySQL 8.0, you can cause those operations to evaluate the arguments in binary-string context by indicating explicitly that at least one argument is a binary string:
_binary b'0001' | b'0010' _binary X'0008' << 8 BINARY NULL & NULL BINARY NULL >> 4
The result of the last two expressions is NULL
, just as without the BINARY
operator, but the data type of the result is a binary string type rather than an integer type.
Because bit operations can handle binary string arguments natively in MySQL 8.0, some expressions produce a different result in MySQL 8.0 than in 5.7. The five problematic expression types to watch out for are:
{ & | ^ } { & | ^ } { << >> } ~ () nonliteral_binarybinarybinarynonliteral_binarynonliteral_binaryanythingnonliteral_binaryAGGR_BIT_FUNCnonliteral_binary
Those expressions return BIGINT
in MySQL 5.7, binary string in 8.0.
Explanation of notation:
{
: List of operators that apply to the given expression type.op1
op2
... }
binary
: Any kind of binary string argument, including a hexadecimal literal, bit literal, or NULL
literal.
nonliteral_binary
: An argument that is a binary string value other than a hexadecimal literal, bit literal, or NULL
literal.
AGGR_BIT_FUNC
: An aggregate function that takes bit-value arguments: BIT_AND()
, BIT_OR()
, BIT_XOR()
.
For information about how to prepare in MySQL 5.7 for potential incompatibilities between MySQL 5.7 and 8.0, see Bit Functions and Operators, in MySQL 5.7 Reference Manual.
The following list describes available bit functions and operators:
Bitwise OR.
The result type depends on whether the arguments are evaluated as binary strings or numbers:
Binary-string evaluation occurs when the arguments have a binary string type, and at least one of them is not a hexadecimal literal, bit literal, or NULL
literal. Numeric evaluation occurs otherwise, with argument conversion to unsigned 64-bit integers as necessary.
Binary-string evaluation produces a binary string of the same length as the arguments. If the arguments have unequal lengths, an ER_INVALID_BITWISE_OPERANDS_SIZE
error occurs. Numeric evaluation produces an unsigned 64-bit integer.
For more information, see the introductory discussion in this section.
mysql> -> 31 mysql> -> 'ABCD' SELECT 29 | 15;SELECT _binary X'40404040' | X'01020304';
Bitwise AND.
The result type depends on whether the arguments are evaluated as binary strings or numbers:
Binary-string evaluation occurs when the arguments have a binary string type, and at least one of them is not a hexadecimal literal, bit literal, or NULL
literal. Numeric evaluation occurs otherwise, with argument conversion to unsigned 64-bit integers as necessary.
Binary-string evaluation produces a binary string of the same length as the arguments. If the arguments have unequal lengths, an ER_INVALID_BITWISE_OPERANDS_SIZE
error occurs. Numeric evaluation produces an unsigned 64-bit integer.
For more information, see the introductory discussion in this section.
mysql> -> 13 mysql> -> 'F0' SELECT 29 & 15;SELECT HEX(_binary X'FF' & b'11110000');
Bitwise XOR.
The result type depends on whether the arguments are evaluated as binary strings or numbers:
Binary-string evaluation occurs when the arguments have a binary string type, and at least one of them is not a hexadecimal literal, bit literal, or NULL
literal. Numeric evaluation occurs otherwise, with argument conversion to unsigned 64-bit integers as necessary.
Binary-string evaluation produces a binary string of the same length as the arguments. If the arguments have unequal lengths, an ER_INVALID_BITWISE_OPERANDS_SIZE
error occurs. Numeric evaluation produces an unsigned 64-bit integer.
For more information, see the introductory discussion in this section.
mysql> -> 0 mysql> -> 1 mysql> -> 8 mysql> -> 'EFCD' SELECT 1 ^ 1;SELECT 1 ^ 0;SELECT 11 ^ 3;SELECT HEX(_binary X'FEDC' ^ X'1111');
Shifts a longlong (BIGINT
) number or binary string to the left.
The result type depends on whether the bit argument is evaluated as a binary string or number:
Binary-string evaluation occurs when the bit argument has a binary string type, and is not a hexadecimal literal, bit literal, or NULL
literal. Numeric evaluation occurs otherwise, with argument conversion to an unsigned 64-bit integer as necessary.
Binary-string evaluation produces a binary string of the same length as the bit argument. Numeric evaluation produces an unsigned 64-bit integer.
Bits shifted off the end of the value are lost without warning, regardless of the argument type. In particular, if the shift count is greater or equal to the number of bits in the bit argument, all bits in the result are 0.
For more information, see the introductory discussion in this section.
mysql> -> 4 mysql> -> 'FF00FF00FF00' SELECT 1 << 2;SELECT HEX(_binary X'00FF00FF00FF' << 8);
Shifts a longlong (BIGINT
) number or binary string to the right.
The result type depends on whether the bit argument is evaluated as a binary string or number:
Binary-string evaluation occurs when the bit argument has a binary string type, and is not a hexadecimal literal, bit literal, or NULL
literal. Numeric evaluation occurs otherwise, with argument conversion to an unsigned 64-bit integer as necessary.
Binary-string evaluation produces a binary string of the same length as the bit argument. Numeric evaluation produces an unsigned 64-bit integer.
Bits shifted off the end of the value are lost without warning, regardless of the argument type. In particular, if the shift count is greater or equal to the number of bits in the bit argument, all bits in the result are 0.
For more information, see the introductory discussion in this section.
mysql> -> 1 mysql> -> '0000FF00FF00' SELECT 4 >> 2;SELECT HEX(_binary X'00FF00FF00FF' >> 8);
Invert all bits.
The result type depends on whether the bit argument is evaluated as a binary string or number:
Binary-string evaluation occurs when the bit argument has a binary string type, and is not a hexadecimal literal, bit literal, or NULL
literal. Numeric evaluation occurs otherwise, with argument conversion to an unsigned 64-bit integer as necessary.
Binary-string evaluation produces a binary string of the same length as the bit argument. Numeric evaluation produces an unsigned 64-bit integer.
For more information, see the introductory discussion in this section.
mysql> -> 4 mysql> -> 'FFFF0000EEEE1111' SELECT 5 & ~1;SELECT HEX(~X'0000FFFF1111EEEE');
Returns the number of bits that are set in the argument N
as an unsigned 64-bit integer, or NULL
if the argument is NULL
.
mysql> -> 1, 7 mysql> -> 1, 7 mysql> -> 1, 1 SELECT BIT_COUNT(64), BIT_COUNT(BINARY 64);SELECT BIT_COUNT('64'), BIT_COUNT(_binary '64');SELECT BIT_COUNT(X'40'), BIT_COUNT(_binary X'40');
Table 12.17 Encryption Functions
Name | Description |
---|---|
AES_DECRYPT() |
Decrypt using AES |
AES_ENCRYPT() |
Encrypt using AES |
ASYMMETRIC_DECRYPT() |
Decrypt ciphertext using private or public key |
ASYMMETRIC_DERIVE() |
Derive symmetric key from asymmetric keys |
ASYMMETRIC_ENCRYPT() |
Encrypt cleartext using private or public key |
ASYMMETRIC_SIGN() |
Generate signature from digest |
ASYMMETRIC_VERIFY() |
Verify that signature matches digest |
COMPRESS() |
Return result as a binary string |
CREATE_ASYMMETRIC_PRIV_KEY() |
Create private key |
CREATE_ASYMMETRIC_PUB_KEY() |
Create public key |
CREATE_DH_PARAMETERS() |
Generate shared DH secret |
CREATE_DIGEST() |
Generate digest from string |
DECODE() |
Decode a string encrypted using ENCODE() |
DES_DECRYPT() |
Decrypt a string |
DES_ENCRYPT() |
Encrypt a string |
ENCODE() |
Encode a string |
ENCRYPT() |
Encrypt a string |
MD5() |
Calculate MD5 checksum |
PASSWORD() |
Calculate and return a password string |
RANDOM_BYTES() |
Return a random byte vector |
SHA1() , SHA() |
Calculate an SHA-1 160-bit checksum |
SHA2() |
Calculate an SHA-2 checksum |
STATEMENT_DIGEST() |
Compute statement digest hash value |
STATEMENT_DIGEST_TEXT() |
Compute normalized statement digest |
UNCOMPRESS() |
Uncompress a string compressed |
UNCOMPRESSED_LENGTH() |
Return the length of a string before compression |
VALIDATE_PASSWORD_STRENGTH() |
Determine strength of password |
Many encryption and compression functions return strings for which the result might contain arbitrary byte values. If you want to store these results, use a column with a VARBINARY
or BLOB
binary string data type. This will avoid potential problems with trailing space removal or character set conversion that would change data values, such as may occur if you use a nonbinary string data type (CHAR
, VARCHAR
, TEXT
).
Some encryption functions return strings of ASCII characters: MD5()
, SHA()
, SHA1()
, SHA2()
, STATEMENT_DIGEST()
, STATEMENT_DIGEST_TEXT()
. Their return value is a string that has a character set and collation determined by the character_set_connection
and collation_connection
system variables. This is a nonbinary string unless the character set is binary
.
If an application stores values from a function such as MD5()
or SHA1()
that returns a string of hex digits, more efficient storage and comparisons can be obtained by converting the hex representation to binary using UNHEX()
and storing the result in a BINARY(
column. Each pair of hexadecimal digits requires one byte in binary form, so the value of N
)N
depends on the length of the hex string. N
is 16 for an MD5()
value and 20 for a SHA1()
value. For SHA2()
, N
ranges from 28 to 32 depending on the argument specifying the desired bit length of the result.
The size penalty for storing the hex string in a CHAR
column is at least two times, up to eight times if the value is stored in a column that uses the utf8
character set (where each character uses 4 bytes). Storing the string also results in slower comparisons because of the larger values and the need to take character set collation rules into account.
Suppose that an application stores MD5()
string values in a CHAR(32)
column:
CREATE TABLE md5_tbl (md5_val CHAR(32), ...); INSERT INTO md5_tbl (md5_val, ...) VALUES(MD5('abcdef'), ...);
To convert hex strings to more compact form, modify the application to use UNHEX()
and BINARY(16)
instead as follows:
CREATE TABLE md5_tbl (md5_val BINARY(16), ...); INSERT INTO md5_tbl (md5_val, ...) VALUES(UNHEX(MD5('abcdef')), ...);
Applications should be prepared to handle the very rare case that a hashing function produces the same value for two different input values. One way to make collisions detectable is to make the hash column a primary key.
Exploits for the MD5 and SHA-1 algorithms have become known. You may wish to consider using another one-way encryption function described in this section instead, such as SHA2()
.
Passwords or other sensitive values supplied as arguments to encryption functions are sent as cleartext to the MySQL server unless an SSL connection is used. Also, such values will appear in any MySQL logs to which they are written. To avoid these types of exposure, applications can encrypt sensitive values on the client side before sending them to the server. The same considerations apply to encryption keys. To avoid exposing these, applications can use stored procedures to encrypt and decrypt values on the server side.
AES_DECRYPT(
crypt_str
,key_str
[,init_vector
])
This function decrypts data using the official AES (Advanced Encryption Standard) algorithm. For more information, see the description of AES_ENCRYPT()
.
The optional initialization vector argument, init_vector
. Statements that use AES_DECRYPT()
are unsafe for statement-based replication.
AES_ENCRYPT(
str
,key_str
[,init_vector
])
AES_ENCRYPT()
and AES_DECRYPT()
implement encryption and decryption of data using the official AES (Advanced Encryption Standard) algorithm, previously known as 「Rijndael.」 The AES standard permits various key lengths. By default these functions implement AES with a 128-bit key length. Key lengths of 196 or 256 bits can be used, as described later. The key length is a trade off between performance and security.
AES_ENCRYPT()
encrypts the string str
using the key string key_str
and returns a binary string containing the encrypted output. AES_DECRYPT()
decrypts the encrypted string crypt_str
using the key string key_str
and returns the original plaintext string. If either function argument is NULL
, the function returns NULL
.
The str
and crypt_str
arguments can be any length, and padding is automatically added to str
so it is a multiple of a block as required by block-based algorithms such as AES. This padding is automatically removed by the AES_DECRYPT()
function. The length of crypt_str
can be calculated using this formula:
16 * (trunc( / 16) + 1) string_length
For a key length of 128 bits, the most secure way to pass a key to the key_str
argument is to create a truly random 128-bit value and pass it as a binary value. For example:
INSERT INTO t VALUES (1,AES_ENCRYPT('text',UNHEX('F3229A0B371ED2D9441B830D21A390C3')));
A passphrase can be used to generate an AES key by hashing the passphrase. For example:
INSERT INTO t VALUES (1,AES_ENCRYPT('text', UNHEX(SHA2('My secret passphrase',512))));
Do not pass a password or passphrase directly to crypt_str
, hash it first. Previous versions of this documentation suggested the former approach, but it is no longer recommended as the examples shown here are more secure.
If AES_DECRYPT()
detects invalid data or incorrect padding, it returns NULL
. However, it is possible for AES_DECRYPT()
to return a non-NULL
value (possibly garbage) if the input data or the key is invalid.
AES_ENCRYPT()
and AES_DECRYPT()
permit control of the block encryption mode and take an optional init_vector
initialization vector argument:
The block_encryption_mode
system variable controls the mode for block-based encryption algorithms. Its default value is aes-128-ecb
, which signifies encryption using a key length of 128 bits and ECB mode. For a description of the permitted values of this variable, see Section 5.1.8, 「Server System Variables」.
The optional init_vector
argument provides an initialization vector for block encryption modes that require it.
For modes that require the optional init_vector
argument, it must be 16 bytes or longer (bytes in excess of 16 are ignored). An error occurs if init_vector
is missing.
For modes that do not require init_vector
, it is ignored and a warning is generated if it is specified.
A random string of bytes to use for the initialization vector can be produced by calling RANDOM_BYTES(16)
. For encryption modes that require an initialization vector, the same vector must be used for encryption and decryption.
mysql> mysql> mysql> mysql> mysql> +-----------------------------------------------+ | AES_DECRYPT(@crypt_str,@key_str,@init_vector) | +-----------------------------------------------+ | text | +-----------------------------------------------+ SET block_encryption_mode = 'aes-256-cbc';SET @key_str = SHA2('My secret passphrase',512);SET @init_vector = RANDOM_BYTES(16);SET @crypt_str = AES_ENCRYPT('text',@key_str,@init_vector);SELECT AES_DECRYPT(@crypt_str,@key_str,@init_vector);
The following table lists each permitted block encryption mode, the SSL libraries that support it, and whether the initialization vector argument is required.
Block Encryption Mode | SSL Libraries that Support Mode | Initialization Vector Required |
---|---|---|
ECB | OpenSSL, wolfSSL | No |
CBC | OpenSSL, wolfSSL | Yes |
CFB1 | OpenSSL | Yes |
CFB8 | OpenSSL | Yes |
CFB128 | OpenSSL | Yes |
OFB | OpenSSL | Yes |
Statements that use AES_ENCRYPT()
or AES_DECRYPT()
are unsafe for statement-based replication.
Compresses a string and returns the result as a binary string. This function requires MySQL to have been compiled with a compression library such as zlib
. Otherwise, the return value is always NULL
. The compressed string can be uncompressed with UNCOMPRESS()
.
mysql> -> 21 mysql> -> 0 mysql> -> 13 mysql> -> 15 SELECT LENGTH(COMPRESS(REPEAT('a',1000)));SELECT LENGTH(COMPRESS(''));SELECT LENGTH(COMPRESS('a'));SELECT LENGTH(COMPRESS(REPEAT('a',16)));
The compressed string contents are stored the following way:
Empty strings are stored as empty strings.
Nonempty strings are stored as a 4-byte length of the uncompressed string (low byte first), followed by the compressed string. If the string ends with space, an extra .
character is added to avoid problems with endspace trimming should the result be stored in a CHAR
or VARCHAR
column. (However, use of nonbinary string data types such as CHAR
or VARCHAR
to store compressed strings is not recommended anyway because character set conversion may occur. Use a VARBINARY
or BLOB
binary string column instead.)
This function was removed in MySQL 8.0.3.
Consider using AES_ENCRYPT()
and AES_DECRYPT()
instead.
DES_DECRYPT(
crypt_str
[,key_str
])
This function was removed in MySQL 8.0.3.
Consider using AES_ENCRYPT()
and AES_DECRYPT()
instead.
DES_ENCRYPT(
str
[,{key_num
|key_str
}])
This function was removed in MySQL 8.0.3.
Consider using AES_ENCRYPT()
and AES_DECRYPT()
instead.
This function was removed in MySQL 8.0.3.
Consider using AES_ENCRYPT()
and AES_DECRYPT()
instead.
This function was removed in MySQL 8.0.3. For one-way hashing, consider using SHA2()
instead.
Calculates an MD5 128-bit checksum for the string. The value is returned as a string of 32 hexadecimal digits, or NULL
if the argument was NULL
. The return value can, for example, be used as a hash key. See the notes at the beginning of this section about storing hash values efficiently.
The return value is a string in the connection character set.
If FIPS mode is enabled, MD5()
returns NULL
. See Section 6.5, 「FIPS Support」.
mysql> -> 'ae2b1fca515949e5d54fb22b8ed95575' SELECT MD5('testing');
This is the 「RSA Data Security, Inc. MD5 Message-Digest Algorithm.」
See the note regarding the MD5 algorithm at the beginning this section.
This function was removed in MySQL 8.0.11.
This function returns a binary string of len
random bytes generated using the random number generator of the SSL library. Permitted values of len
range from 1 to 1024. For values outside that range, RANDOM_BYTES()
generates a warning and returns NULL
.
RANDOM_BYTES()
can be used to provide the initialization vector for the AES_DECRYPT()
and AES_ENCRYPT()
functions. For use in that context, len
must be at least 16. Larger values are permitted, but bytes in excess of 16 are ignored.
RANDOM_BYTES()
generates a random value, which makes its result nondeterministic. Consequently, statements that use this function are unsafe for statement-based replication.
Calculates an SHA-1 160-bit checksum for the string, as described in RFC 3174 (Secure Hash Algorithm). The value is returned as a string of 40 hexadecimal digits, or NULL
if the argument was NULL
. One of the possible uses for this function is as a hash key. See the notes at the beginning of this section about storing hash values efficiently. SHA()
is synonymous with SHA1()
.
The return value is a string in the connection character set.
mysql> -> 'a9993e364706816aba3e25717850c26c9cd0d89d' SELECT SHA1('abc');
SHA1()
can be considered a cryptographically more secure equivalent of MD5()
. However, see the note regarding the MD5 and SHA-1 algorithms at the beginning this section.
Calculates the SHA-2 family of hash functions (SHA-224, SHA-256, SHA-384, and SHA-512). The first argument is the plaintext string to be hashed. The second argument indicates the desired bit length of the result, which must have a value of 224, 256, 384, 512, or 0 (which is equivalent to 256). If either argument is NULL
or the hash length is not one of the permitted values, the return value is NULL
. Otherwise, the function result is a hash value containing the desired number of bits. See the notes at the beginning of this section about storing hash values efficiently.
The return value is a string in the connection character set.
mysql> -> '23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7' SELECT SHA2('abc', 224);
This function works only if MySQL has been configured with SSL support. See Section 6.3, 「Using Encrypted Connections」.
SHA2()
can be considered cryptographically more secure than MD5()
or SHA1()
.
Given an SQL statement as a string, returns the statement digest hash value as a string in the connection character set, or NULL
if the argument is NULL
. The related STATEMENT_DIGEST_TEXT()
function returns the normalized statement digest. For information about statement digesting, see Section 26.10, 「Performance Schema Statement Digests and Sampling」.
Both functions use the MySQL parser to parse the statement. If parsing fails, an error occurs. The error message includes the parse error only if the statement is provided as a literal string.
The max_digest_length
system variable determines the maximum number of bytes available to these functions for computing normalized statement digests.
mysql> mysql> +------------------------------------------------------------------+ | STATEMENT_DIGEST(@stmt) | +------------------------------------------------------------------+ | 3bb95eeade896657c4526e74ff2a2862039d0a0fe8a9e7155b5fe492cbd78387 | +------------------------------------------------------------------+ mysql> +----------------------------------------------------------+ | STATEMENT_DIGEST_TEXT(@stmt) | +----------------------------------------------------------+ | SELECT * FROM `mytable` WHERE `cola` = ? AND `colb` = ? | +----------------------------------------------------------+ SET @stmt = 'SELECT * FROM mytable WHERE cola = 10 AND colb = 20';SELECT STATEMENT_DIGEST(@stmt);SELECT STATEMENT_DIGEST_TEXT(@stmt);
STATEMENT_DIGEST_TEXT(
statement
)
Given an SQL statement as a string, returns the normalized statement digest as a string in the connection character set, or NULL
if the argument is NULL
. For additional discussion and examples, see the description of the related STATEMENT_DIGEST()
function.
UNCOMPRESS(
string_to_uncompress
)
Uncompresses a string compressed by the COMPRESS()
function. If the argument is not a compressed value, the result is NULL
. This function requires MySQL to have been compiled with a compression library such as zlib
. Otherwise, the return value is always NULL
.
mysql> -> 'any string' mysql> -> NULL SELECT UNCOMPRESS(COMPRESS('any string'));SELECT UNCOMPRESS('any string');
UNCOMPRESSED_LENGTH(
compressed_string
)
Returns the length that the compressed string had before being compressed.
mysql> -> 30 SELECT UNCOMPRESSED_LENGTH(COMPRESS(REPEAT('a',30)));
VALIDATE_PASSWORD_STRENGTH(
str
)
Given an argument representing a plaintext password, this function returns an integer to indicate how strong the password is. The return value ranges from 0 (weak) to 100 (strong).
Password assessment by VALIDATE_PASSWORD_STRENGTH()
is done by the validate_password
component. If that component is not installed, the function always returns 0. For information about installing validate_password
, see Section 6.4.3, 「The Password Validation Component」. To examine or configure the parameters that affect password testing, check or set the system variables implemented by validate_password
. See Section 6.4.3.2, 「Password Validation Options and Variables」.
The password is subjected to increasingly strict tests and the return value reflects which tests were satisfied, as shown in the following table. In addition, if the validate_password.check_user_name
system variable is enabled and the password matches the user name, VALIDATE_PASSWORD_STRENGTH()
returns 0 regardless of how other validate_password
system variables are set.
Password Test | Return Value |
---|---|
Length < 4 | 0 |
Length ≥ 4 and < validate_password.length |
25 |
Satisfies policy 1 (LOW ) |
50 |
Satisfies policy 2 (MEDIUM ) |
75 |
Satisfies policy 3 (STRONG ) |
100 |
This section describes functions used to manipulate user-level locks.
Table 12.18 Locking Functions
Name | Description |
---|---|
GET_LOCK() |
Get a named lock |
IS_FREE_LOCK() |
Whether the named lock is free |
IS_USED_LOCK() |
Whether the named lock is in use; return connection identifier if true |
RELEASE_ALL_LOCKS() |
Release all current named locks |
RELEASE_LOCK() |
Release the named lock |
Tries to obtain a lock with a name given by the string str
, using a timeout of timeout
seconds. A negative timeout
value means infinite timeout. The lock is exclusive. While held by one session, other sessions cannot obtain a lock of the same name.
Returns 1
if the lock was obtained successfully, 0
if the attempt timed out (for example, because another client has previously locked the name), or NULL
if an error occurred (such as running out of memory or the thread was killed with mysqladmin kill).
A lock obtained with GET_LOCK()
is released explicitly by executing RELEASE_LOCK()
or implicitly when your session terminates (either normally or abnormally). Locks obtained with GET_LOCK()
are not released when transactions commit or roll back.
GET_LOCK()
is implemented using the metadata locking (MDL) subsystem. Multiple simultaneous locks can be acquired and GET_LOCK()
does not release any existing locks. For example, suppose that you execute these statements:
SELECT GET_LOCK('lock1',10); SELECT GET_LOCK('lock2',10); SELECT RELEASE_LOCK('lock2'); SELECT RELEASE_LOCK('lock1');
The second GET_LOCK()
acquires a second lock and both RELEASE_LOCK()
calls return 1 (success).
It is even possible for a given session to acquire multiple locks for the same name. Other sessions cannot acquire a lock with that name until the acquiring session releases all its locks for the name.
Uniquely named locks acquired with GET_LOCK()
appear in the Performance Schema metadata_locks
table. The OBJECT_TYPE
column says USER LEVEL LOCK
and the OBJECT_NAME
column indicates the lock name. In the case that multiple locks are acquired for the same name, only the first lock for the name registers a row in the metadata_locks
table. Subsequent locks for the name increment a counter in the lock but do not acquire additional metadata locks. The metadata_locks
row for the lock is deleted when the last lock instance on the name is released.
The capability of acquiring multiple locks means there is the possibility of deadlock among clients. When this happens, the server chooses a caller and terminates its lock-acquisition request with an ER_USER_LOCK_DEADLOCK
error. This error does not cause transactions to roll back.
MySQL enforces a maximum length on lock names of 64 characters.
GET_LOCK()
can be used to implement application locks or to simulate record locks. Names are locked on a server-wide basis. If a name has been locked within one session, GET_LOCK()
blocks any request by another session for a lock with the same name. This enables clients that agree on a given lock name to use the name to perform cooperative advisory locking. But be aware that it also enables a client that is not among the set of cooperating clients to lock a name, either inadvertently or deliberately, and thus prevent any of the cooperating clients from locking that name. One way to reduce the likelihood of this is to use lock names that are database-specific or application-specific. For example, use lock names of the form db_name.str
or app_name.str
.
If multiple clients are waiting for a lock, the order in which they will acquire it is undefined. Applications should not assume that clients will acquire the lock in the same order that they issued the lock requests.
GET_LOCK()
is unsafe for statement-based replication. A warning is logged if you use this function when binlog_format
is set to STATEMENT
.
With the capability of acquiring multiple named locks, it is possible for a single statement to acquire a large number of locks. For example:
INSERT INTO ... SELECT GET_LOCK(t1.col_name) FROM t1;
These types of statements may have certain adverse effects. For example, if the statement fails part way through and rolls back, locks acquired up to the point of failure will still exist. If the intent is for there to be a correspondence between rows inserted and locks acquired, that intent will not be satisfied. Also, if it is important that locks are granted in a certain order, be aware that result set order may differ depending on which execution plan the optimizer chooses. For these reasons, it may be best to limit applications to a single lock-acquisition call per statement.
A different locking interface is available as either a plugin service or a set of user-defined functions. This interface provides lock namespaces and distinct read and write locks, unlike the interface provided by GET_LOCK()
and related functions. For details, see Section 29.3.1, 「The Locking Service」.
Checks whether the lock named str
is free to use (that is, not locked). Returns 1
if the lock is free (no one is using the lock), 0
if the lock is in use, and NULL
if an error occurs (such as an incorrect argument).
This function is unsafe for statement-based replication. A warning is logged if you use this function when binlog_format
is set to STATEMENT
.
Checks whether the lock named str
is in use (that is, locked). If so, it returns the connection identifier of the client session that holds the lock. Otherwise, it returns NULL
.
This function is unsafe for statement-based replication. A warning is logged if you use this function when binlog_format
is set to STATEMENT
.
Releases all named locks held by the current session and returns the number of locks released (0 if there were none)
This function is unsafe for statement-based replication. A warning is logged if you use this function when binlog_format
is set to STATEMENT
.
Releases the lock named by the string str
that was obtained with GET_LOCK()
. Returns 1
if the lock was released, 0
if the lock was not established by this thread (in which case the lock is not released), and NULL
if the named lock did not exist. The lock does not exist if it was never obtained by a call to GET_LOCK()
or if it has previously been released.
The DO
statement is convenient to use with RELEASE_LOCK()
. See Section 13.2.3, 「DO Syntax」.
This function is unsafe for statement-based replication. A warning is logged if you use this function when binlog_format
is set to STATEMENT
.
Table 12.19 Information Functions
Name | Description |
---|---|
BENCHMARK() |
Repeatedly execute an expression |
CHARSET() |
Return the character set of the argument |
COERCIBILITY() |
Return the collation coercibility value of the string argument |
COLLATION() |
Return the collation of the string argument |
CONNECTION_ID() |
Return the connection ID (thread ID) for the connection |
CURRENT_ROLE() |
Return the current active roles |
CURRENT_USER() , CURRENT_USER |
The authenticated user name and host name |
DATABASE() |
Return the default (current) database name |
FOUND_ROWS() |
For a SELECT with a LIMIT clause, the number of rows that would be returned were there no LIMIT clause |
ICU_VERSION() |
ICU library version |
LAST_INSERT_ID() |
Value of the AUTOINCREMENT column for the last INSERT |
ROLES_GRAPHML() |
Return a GraphML document representing memory role subgraphs |
ROW_COUNT() |
The number of rows updated |
SCHEMA() |
Synonym for DATABASE() |
SESSION_USER() |
Synonym for USER() |
SYSTEM_USER() |
Synonym for USER() |
USER() |
The user name and host name provided by the client |
VERSION() |
Return a string that indicates the MySQL server version |
The BENCHMARK()
function executes the expression expr
repeatedly count
times. It may be used to time how quickly MySQL processes the expression. The result value is always 0
. The intended use is from within the mysql client, which reports query execution times:
mysql> +---------------------------------------------------+ | BENCHMARK(1000000,AES_ENCRYPT('hello','goodbye')) | +---------------------------------------------------+ | 0 | +---------------------------------------------------+ 1 row in set (4.74 sec) SELECT BENCHMARK(1000000,AES_ENCRYPT('hello','goodbye'));
The time reported is elapsed time on the client end, not CPU time on the server end. It is advisable to execute BENCHMARK()
several times, and to interpret the result with regard to how heavily loaded the server machine is.
BENCHMARK()
is intended for measuring the runtime performance of scalar expressions, which has some significant implications for the way that you use it and interpret the results:
Only scalar expressions can be used. Although the expression can be a subquery, it must return a single column and at most a single row. For example, BENCHMARK(10, (SELECT * FROM t))
will fail if the table t
has more than one column or more than one row.
Executing a SELECT
statement expr
N
times differs from executing SELECT BENCHMARK(
in terms of the amount of overhead involved. The two have very different execution profiles and you should not expect them to take the same amount of time. The former involves the parser, optimizer, table locking, and runtime evaluation N
, expr
)N
times each. The latter involves only runtime evaluation N
times, and all the other components just once. Memory structures already allocated are reused, and runtime optimizations such as local caching of results already evaluated for aggregate functions can alter the results. Use of BENCHMARK()
thus measures performance of the runtime component by giving more weight to that component and removing the 「noise」 introduced by the network, parser, optimizer, and so forth.
Returns the character set of the string argument.
mysql> -> 'utf8' mysql> -> 'latin1' mysql> -> 'utf8' SELECT CHARSET('abc');SELECT CHARSET(CONVERT('abc' USING latin1));SELECT CHARSET(USER());
Returns the collation coercibility value of the string argument.
mysql> -> 0 mysql> -> 3 mysql> -> 4 mysql> -> 5 SELECT COERCIBILITY('abc' COLLATE utf8_swedish_ci);SELECT COERCIBILITY(USER());SELECT COERCIBILITY('abc');SELECT COERCIBILITY(1000);
The return values have the meanings shown in the following table. Lower values have higher precedence.
Coercibility | Meaning | Example |
---|---|---|
0 |
Explicit collation | Value with COLLATE clause |
1 |
No collation | Concatenation of strings with different collations |
2 |
Implicit collation | Column value, stored routine parameter or local variable |
3 |
System constant | USER() return value |
4 |
Coercible | Literal string |
5 |
Numeric | Numeric or temporal value |
5 |
Ignorable | NULL or an expression derived from NULL |
For more information, see Section 10.8.4, 「Collation Coercibility in Expressions」.
Returns the collation of the string argument.
mysql> -> 'utf8_general_ci' mysql> -> 'utf8mb4_0900_ai_ci' mysql> -> 'latin1_swedish_ci' SELECT COLLATION('abc');SELECT COLLATION(_utf8mb4'abc');SELECT COLLATION(_latin1'abc');
Returns the connection ID (thread ID) for the connection. Every connection has an ID that is unique among the set of currently connected clients.
The value returned by CONNECTION_ID()
is the same type of value as displayed in the ID
column of the