# SQL
Based on MySQL
# Docs
docs
help
help HELP 'search_string'- corresponding table in
mysql—help_category,help_keyword,help_relation,help_topic - the top-level help categories
HELP 'contents' - topics in help categories — use the category name
HELP 'data types' - keywords
HELP 'ascii' HELP 'create table'
- corresponding table in
after
brew install- secure with a root password —
mysql_secure_installation - connect
mysql -uroot - start with
launchdbrew services start mysql - start without a background service
mysql.server start
- secure with a root password —
# CLI
mycli — A Terminal Client for MySQL with AutoCompletion and Syntax Highlighting
- mycli at GitHub (opens new window)
- mycli docs (opens new window)
- pager —
nopager,pager less,pager more
mysqlmysql [options] [db_name]- authentication
--user=user_name,-u user_name--password[=password],-p[password]
- privileges
--skip-show-database— sets theskip_show_databasesystem variable that controls who is permitted to use
- case sensitivity — see Language Basics
--lower-case-table-names[=#]
- autocomplete —
--auto-rehash,mysql> \#,mysql> rehash - output format
--xml--html
- authentication
at
mysql>— statements should end with;if accidentally enters multiline modequit,exit- help
HELP COMMAND HELP STATEMENT - open file
\. <filename> | source <filename>
mysqlshowmysqlshow—SHOW DATABASES,SHOW SCHEMASmysqlshow db_name—SHOW TABLES
mysqladminmysqlsh— mysql shell, with JavaScript and Python support- MySQL :: MySQL Shell 8.0 :: 1 MySQL Shell Features (opens new window)
- APIs
- The X DevAPI — work with both relational and document data
- The AdminAPI — work with InnoDB cluster
# Data Types
See Literals for syntax.
numeric
- attributes
- arithmetic operations — all arithmetic is done using signed
BIGINTorDOUBLEvalues, bear overflow awareness in mind - string-to-number conversion — automatically, to
DOUBLEorBIGINT SIGNEDby default, no effect when usingUNSIGNED— deprecated for columns of typeFLOAT,DOUBLE, andDECIMAL(and any synonyms), useCHECKinstead- subtraction between integer values — the result is unsigned if one of the two is
UNSIGNED, unlesssql_modeNO_UNSIGNED_SUBTRACTION
- subtraction between integer values — the result is unsigned if one of the two is
ZEROFILL— deprecated, automaticallyUNSIGNEDif used, useLPAD()orCHARinstead
- arithmetic operations — all arithmetic is done using signed
TINYINT,SMALLINT,MEDIUMINT,INTorINTEGER,BIGINT— 1 B, 2 B, 3 B, 4 B, 8 BTINYINT[(M)] [UNSIGNED] [ZEROFILL]Mlike inTINYINT(1)— the maximum display width, unrelated to the range of values a type can storeSERIAL— equivalent toBIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE
BOOL,BOOLEAN—TINYINT(1), zero forFALSE, nonzero for true,TRUEis 1DECIMAL,NUMERIC,DEC,FIXED—Mfor precision (total digits) up to 65 and defaults to 10,Dfor scale (fraction digits, no decimal point if 0), up to 30 and defaults to 0DECIMAL[(M[,D])] [ZEROFILL]- arithmetic operations — done with
Mof 65 - when more digits than permitted — generally truncation
- arithmetic operations — done with
FLOAT,DOUBLE,DOUBLE PRECISION- deprecated —
FLOAT(p),FLOAT(M,D),DOUBLE(M,D),DOUBLE PRECISION[(M,D)]
- deprecated —
BIT[(M)]—Mindicates the number of bits from 1 (default) to 64- literal syntax — see Literals
- attributes
date and time
- attribute
- invalid value — zero value, out of range or otherwise invalid values are converted to zero value, except
TIME, controlled bysql_modeNO_ZERO_DATE - zero date — useful for applications that need to store birthdays for which you may not know the exact date, like
2009-00-00, controlled bysql_modeNO_ZERO_IN_DATE- dummy date
0000-00-00(zero value) — sometimes more convenient than usingNULLvalues, and uses less data and index space
- dummy date
fspfractional seconds part — defaults to 0, up to 6 (microsecond, ANSI SQL default), rounded for excessive values, controlled bysql_modeTIME_TRUNCATE_FRACTIONAL- automatic initialization and updating — for
TIMESTAMPorDATETIME - string and number — accept both string and number when assigning, but need to convert to numbers (
TIME_TO_SEC(),TO_DAYS()) beforeSUM()andAVG() - conversion — missing date as
CURRENT_DATE(), missing time part as00:00:00, rounding
- invalid value — zero value, out of range or otherwise invalid values are converted to zero value, except
DATE— from'1000-01-01'to'9999-12-31'DATETIME[(fsp)]— from1000-01-01 00:00:00.000000'to'9999-12-31 23:59:59.999999'- automatic initialization and updating —
DEFAULT CURRENT_TIMESTAMPandON UPDATE CURRENT_TIMESTAMP, also synonyms ofCURRENT_TIMESTAMP, the parameter asfsp
- automatic initialization and updating —
TIMESTAMP[(fsp)]— in UTC, from'1970-01-01 00:00:01.000000'to'2038-01-19 03:14:07.999999'- automatic initialization and updating —
DEFAULT CURRENT_TIMESTAMPandON UPDATE CURRENT_TIMESTAMP, also synonyms ofCURRENT_TIMESTAMP, the parameter asfsp explicit_defaults_for_timestampsystem variable — controls nonstandard behaviors for default values andNULL-value handling inTIMESTAMPcolumns
- automatic initialization and updating —
TIME[(fsp)]— from'-838:59:59.000000'to'838:59:59.000000', can also used for elapsed time or a time interval- out of range value — clipped to the closest endpoint
- invalid values — converted to the zero value which itself is valid
- number values — as left padded with zero, like
1111to00:11:11
YEAR— from1901to2155, 1 byte
- attribute
string
- attribute
CHARACTER SET,CHARSET— seeSHOW CHARACTER SET, defaults toutf8mb4from version 8,latin1previouslyCREATE TABLE t ( c1 VARCHAR(20) CHARACTER SET utf8, c2 TEXT CHARACTER SET latin1 COLLATE latin1_general_cs );CREATE DATABASE european_sales CHARACTER SET latin1;ASCIIattribute — shorthand forCHARACTER SET latin1
COLLATECHAR BINARYandVARCHAR BINARY— use the binary (_bin) collation, likeutf8mb4_binPAD_ATTRIBUTE— many collation withPAD SPACE, with which strings are compared without regard to any trailing spaces (LIKEexcluded), possible cause of duplicate-key errorsmysql> SELECT myname = 'Jones', myname = 'Jones ' FROM names; +--------------------+--------------------+ | myname = 'Jones' | myname = 'Jones ' | +--------------------+--------------------+ | 1 | 1 | +--------------------+--------------------+
CHAR— space right padded, widthMfrom 0 to 255 default 1CHAR[(M)] [CHARACTER SET charset_name] [COLLATE collation_name]CHAR(0)— onlyNULLand''- trailing spaces removed upon retrieval
- no trailing space removal —
sql_modePAD_CHAR_TO_FULL_LENGTH
- no trailing space removal —
- when assigning size exceeded values — truncated with warning if not in strict mode, error in strict mode for truncation of non-space characters
- excessive trailing spaces — truncated silently regardless of strict mode
- variable-length off-page storage when ≥ 768 B — InnoDB encodes fixed-length fields greater than or equal to 768 bytes in length as variable-length fields, which can be stored off-page, for example,
CHAR(255)withutf8mb4
VARCHAR— variable length withMfrom 0 to 65535, but actual effective maximum length subject to charset and maximum row size (65535 B)VARCHAR(M) [CHARACTER SET charset_name] [COLLATE collation_name]- length information — stored with length prefix, 1 or 2 byte
- when assigning size exceeded values — truncated with warning if not in strict mode, error in strict mode for truncation of non-space characters
- excessive trailing spaces — truncated with warning regardless of strict mode
MEDIUMTEXT, andLONGTEXT— variable length up to: 16 MB, 4 GBTINYTEXT [CHARACTER SET charset_name] [COLLATE collation_name]TINYTEXT,TEXT— up to: 255 B, 65535 B; useCHARandVARCHARinsteadTEXT(M)— creates the column as the smallest type large enough to hold valuesMbytes long- length information — stored with length prefix
- when assigning size exceeded values — truncated with warning if not in strict mode, error in strict mode for truncation of non-space characters
- excessive trailing spaces — truncated with warning regardless of strict mode
- padded for index comparisons — index entry comparisons are space-padded at the end
- engine
MEMORYdoes not supportTEXTandBLOB— forced to use on-disk temporary tables when temporary tables with columns of these types being used - separately allocated object — represented internally by a separately allocated object, whereas for all other data types storage is allocated once per column when the table is opened
- binary strings
CHARACTER SET binarymake character strings binary —CHARbecomesBINARY,VARCHARbecomesVARBINARY, andTEXTbecomesBLOBBINARY[(M)]—CHAR CHARACTER SET binary,0x00(\0) right padded, and as integral part of the value (being compared and no removal upon retrieval)VARBINARY(M)—VARCHARbinary versionMEDIUMBLOB,LONGBLOB— no padded index comparisonsTINYBLOB,BLOB[(M)]
ENUM— a string object that can have only one value, can beNULLor the special''error value, up to 65535 distinct elementsENUM('value1','value2',...) [CHARACTER SET charset_name] [COLLATE collation_name]- ordinal — represented internally as integers starting from 1,
NULLasNULLand''as 0 - maximum element length —
M <= 255and another constraint, whereMis the element literal length
- ordinal — represented internally as integers starting from 1,
SET—ENUMbut a string object that can have zero or more values,NULLor''not permitted, and up to 64 distinct members- bit vectors internally
- literal — comma separated string, like
'a,b'
- attribute
spatial
JSON
# Statements
statements
- DDL — Data Definition Language
- DML — Data Manipulation Language
- TCL — Transaction Control Language
- DCL — Data Control Language,
GRANT,REVOKE
USE db_name— use the named database as the default (current) database for subsequent statements- currently using —
DATABASE()
- currently using —
# Inspection
# SHOW
SHOW— provide information about databases, tables, columns, or status information about the server- correspond to tables in
INFORMATION_SCHEMA—SELECTcorresponding tables yields the same result WHEREclause — evaluated against the column names in the result
- correspond to tables in
show server information
SHOW ENGINESHOW VARIABLES— see System VariablesSHOW CHARACTER SET- corresponding table in
INFORMATION_SCHEMA—INFORMATION_SCHEMA.CHARACTER_SETS - hidden character set —
filename, internal use only
- corresponding table in
show database information
SHOW DATABASES,SHOW SCHEMAS— lists the databases on the MySQL server hostSHOW {DATABASES | SCHEMAS} [LIKE 'pattern' | WHERE expr]- CLI
mysqlshowmysqloption--skip-show-database— sets theskip_show_databasesystem variable that controls who is permitted to use
- corrsponding table in
INFORMATION_SCHEMA—INFORMATION_SCHEMA.SCHEMATA
- CLI
SHOW CREATE DATABASESHOW CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] db_name
show table information
SHOW TABLES— lists the non-TEMPORARYtables in a given databaseSHOW [EXTENDED] [FULL] TABLES [{FROM | IN} db_name] [LIKE 'pattern' | WHERE expr]EXTENDED— list hidden tables prefixed with#sq1created by failedALTER TABLEstatementsFULL— an additionalTable_typecolumn, with valuesBASE TABLE,VIEWandSYSTEM VIEW(only forINFORMATION_SCHEMA)- corresponding table in
INFORMATION_SCHEMA—INFORMATION_SCHEMA.TABLES - CLI —
mysqlshow db_name
SHOW TABLE STATUS— works likesSHOW TABLES, but provides a lot of informationSHOW TABLE STATUS [{FROM | IN} db_name] [LIKE 'pattern' | WHERE expr]- CLI —
mysqlshow --status db_name command - corresponding table in
INFORMATION_SCHEMA—INFORMATION_SCHEMA.TABLES
- CLI —
SHOW INDEXSHOW [EXTENDED] {INDEX | INDEXES | KEYS} {FROM | IN} tbl_name [{FROM | IN} db_name] [WHERE expr]
SHOW COLUMNSSHOW [EXTENDED] [FULL] {COLUMNS | FIELDS} {FROM | IN} tbl_name [{FROM | IN} db_name] [LIKE 'pattern' | WHERE expr]EXTENDED— include information about hidden columns that MySQL uses internally and are not accessible by usersFULL— include the column collation and comments, as well as the privileges- corresponding table in
INFORMATION_SCHEMA—INFORMATION_SCHEMA.COLUMNS - CLI —
mysqlshow db_name tbl_name SHOW CREATE TABLESHOW CREATE TABLE tbl_nameEXPLAIN,DESCRIBE,DESC{EXPLAIN | DESCRIBE | DESC} tbl_name [col_name | wild]
# EXPLAIN
EXPLAIN,DESCRIBE,DESC- also can be used as
SHOW COLUMNS - execution plan, usually
EXPLAIN— displays information from the optimizer, i.e. how it would process the statement, including information about how tables are joined and in which order{EXPLAIN | DESCRIBE | DESC} [FORMAT = {TRADITIONAL | JSON | TREE}] {explainable_stmt | FOR CONNECTION connection_id}explainable_stmt—SELECT,DELETE,INSERT,REPLACE, andUPDATE; alsoTABLEfrom MySQL 8.0.19FOR CONNECTION connection_id— the last statement in the named connectionconnection_id—CONNECTION_ID()for current session
FORMATTRADITIONAL— tabularTREE— the only format which shows hash join usage
- ouput — see 8.8.2 EXPLAIN Output Format (opens new window)
type(JSON name:access_type) in output, see docs for detailssystem,consteq_ref,unique_subqueryref,ref_or_null,index_subqueryrangeindex_mergeindex,ALL
EXPLAIN ANALYZE— execution plan along with timing and additional, iterator-based, information about how the optimizer's expectations matched the actual execution{EXPLAIN | DESCRIBE | DESC} ANALYZE select_statementselect_statement— besidesSELECT, also multi-tableUPDATEandDELETEstatements; alsoTABLEfrom MySQL 8.0.19
- also can be used as
performance benchmark profiling
- system variable
profilingSET profiling=1; SELECT SQL_NO_CACHE * FROM my_table; -- ... SHOW PROFILE; SET profiling=0; STATUSstarting withSelectFLUSH STATUS; SELECT SQL_NO_CACHE * FROM my_table; SHOW SESSION STATUS LIKE 'Select%';STATUSlast_query_costSHOW STATUS LIKE 'last_query_cost';
- system variable
select optimization
- more tbd
- big query refactor
- 切分大查询 — 一个大查询如果一次性执行的话,可能一次锁住很多数据、占满整个事务日志、耗尽系统资源、阻塞很多小的但重要的查询。
- 分解大连接查询 — 将一个大连接查询分解成对每一个表进行一次单表查询,然后在应用程序中进行关联,这样做的好处有:
- 让缓存更高效。对于连接查询,如果其中一个表发生变化,那么整个查询缓存就无法使用。而分解后的多个查询,即使其中一个表发生变化,对其它表的查询缓存依然可以使用。
- 分解成多个单表查询,这些单表查询的缓存结果更可能被其它查询使用到,从而减少冗余记录的查询。
- 减少锁竞争;
- 在应用层进行连接,可以更容易对数据库进行拆分,从而更容易做到高性能和可伸缩。
# DDL
- DDL statements, atomic or otherwise, implicitly end any transaction that is active in the current session
# CREATE TABLE
CREATE TABLECREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name (create_definition,...) [table_options] [partition_options]TEMPORARY— tbd, temporary tables kept until the end of transaction or sessiontable_optionstable_option [[,] table_option] ...table_optionAUTO_INCREMENT [=] valueCOMMENT [=] 'string'- more
- more
create_definitioninCREATE TABLE,ALTER TABLEcol_name column_definition | {INDEX|KEY} [index_name] [index_type] (key_part,...) [index_option] ... | {FULLTEXT|SPATIAL} [INDEX|KEY] [index_name] (key_part,...) [index_option] ... | [CONSTRAINT [symbol]] PRIMARY KEY [index_type] (key_part,...) [index_option] ... | [CONSTRAINT [symbol]] UNIQUE [INDEX|KEY] [index_name] [index_type] (key_part,...) [index_option] ... | [CONSTRAINT [symbol]] FOREIGN KEY [index_name] (col_name,...) reference_definition | check_constraint_definition- syntax — column definition with constraint attributes or a sole constraint or index definition
key_part—{col_name [(length)] | (expr)} [ASC | DESC], order matterslength— up to 767 bytes long for InnoDB tables that use theREDUNDANTorCOMPACTrow format, 3072 bytes forDYNAMICorCOMPRESSEDrow format
check_constraint_definition— also used incolumn_definition[CONSTRAINT [symbol]] CHECK (expr) [[NOT] ENFORCED]
column_definitioninCREATE TABLE,ALTER TABLE- vanilla column
data_type [NOT NULL | NULL] [DEFAULT {literal | (expr)} ] [AUTO_INCREMENT] [UNIQUE [KEY]] [[PRIMARY] KEY] [COMMENT 'string'] [COLLATE collation_name] [COLUMN_FORMAT {FIXED|DYNAMIC|DEFAULT}] [STORAGE {DISK|MEMORY}] [reference_definition] [check_constraint_definition] - generated column — support secondary indexes and partition but not subqueries, stored procedures and more
data_type [COLLATE collation_name] [GENERATED ALWAYS] AS (expr) [VIRTUAL | STORED] [NOT NULL | NULL] [UNIQUE [KEY]] [[PRIMARY] KEY] [COMMENT 'string'] [reference_definition] [check_constraint_definition]- example —
col1 LIKE '%xxx'dose not use index search, create a reversed generated column to utilize index:loc1 VARCHAR(200) GENERATED ALWAYS AS (REVERSE(col1)), create index on this generated column to hit index withloc1 LIKE REVERSE('%xxx')
- example —
- vanilla column
key/index creation options
index_type: USING {BTREE | HASH} index_option: KEY_BLOCK_SIZE [=] value | index_type | WITH PARSER parser_name | COMMENT 'string' | {VISIBLE | INVISIBLE}KEY | INDEX— as indexPRIMARY KEY— implicitlyNOT NULL, name isPRIMARYUNIQUE [INDEX|KEY]— error when duplicateFOREIGN KEY— only InnoDB and NDB tables support checking of foreign key constraintsreference_definition: REFERENCES tbl_name (col_name,...) [ON DELETE reference_option] [ON UPDATE reference_option] reference_option: RESTRICT | CASCADE | SET NULL | NO ACTION- switch — system variable
foreign_key_checks CASCADE— delete or update from the parent table is cascaded to the matching rows in the child table; cascaded actions do not activate triggersSET NULL— literallyRESTRICTorNO ACTION(default) — rejects the delete or update operation for the parent table if there is a related foreign key value in the referenced table- corresponding tables in
INFORMATION_SCHEMA—INFORMATION_SCHEMA.KEY_COLUMN_USAGE,INFORMATION_SCHEMA.INNODB_FOREIGN,INFORMATION_SCHEMA.INNODB_FOREIGN_COLS
- switch — system variable
FULLTEXT,SPATIALkeys — tbd- inspect —
SHOW INDEX
# ALTER TABLE, DROP TABLE
ALTER TABLEALTER TABLE tbl_name [alter_specification [, alter_specification] ...] [partition_options]alter_specification— one of below, see docstable_options- add
- add column
ADD [COLUMN] col_name column_definition [FIRST | AFTER col_name] | ADD [COLUMN] (col_name column_definition,...) - add index key
ADD {INDEX|KEY} [index_name] [index_type] (key_part,...) [index_option] ... | ADD [CONSTRAINT [symbol]] PRIMARY KEY [index_type] (key_part,...) [index_option] ... | ADD [CONSTRAINT [symbol]] UNIQUE [INDEX|KEY] [index_name] [index_type] (key_part,...) [index_option] ... | ADD [CONSTRAINT [symbol]] FOREIGN KEY [index_name] (col_name,...) reference_definition
- add column
- delete
DROP {CHECK|CONSTRAINT} symbol | DROP [COLUMN] col_name | DROP {INDEX|KEY} index_name | DROP PRIMARY KEY | DROP FOREIGN KEY fk_symbol
DROP TABLETRUNCATE [TABLE] tbl_name— empties a table completely, no trigger
# CREATE VIEW, PROCEDURE, FUNCTION, TRIGGER
CREATE VIEWCREATE [OR REPLACE] [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}] [DEFINER = user] [SQL SECURITY { DEFINER | INVOKER }] VIEW view_name [(column_list)] AS select_statement [WITH [CASCADED | LOCAL] CHECK OPTION]OR REPLACE— literally- frozen after creation — for a
SELECT *view on a table, new columns added to the table are unknown to the view, and errors when selecting from the view if relevent columns dropped from the table - updatable and insertable views — see docs
- more
CREATE PROCEDURECREATE [DEFINER = user] PROCEDURE sp_name ([proc_parameter[,...]]) [characteristic ...] routine_bodyCURSOR— MySQL supports cursors inside stored programs
CREATE FUNCTIONCREATE [DEFINER = user] FUNCTION sp_name ([func_parameter[,...]]) RETURNS type [characteristic ...] routine_bodyCREATE TRIGGER
# DML
# SELECT
SELECTSELECT [ALL | DISTINCT | DISTINCTROW ] [other_modifiers] select_expr [, select_expr] ... [FROM table_references [PARTITION partition_list]] [WHERE where_condition] [GROUP BY {col_name | expr | position}, ... [WITH ROLLUP]] [HAVING where_condition] [WINDOW window_name AS (window_spec) [, window_name AS (window_spec)] ...] [ORDER BY {col_name | expr | position} [ASC | DESC], ... [WITH ROLLUP]] [LIMIT {[offset,] row_count | row_count OFFSET offset}] [FOR {UPDATE | SHARE} [OF tbl_name [, tbl_name] ...] [NOWAIT | SKIP LOCKED] | LOCK IN SHARE MODE] [into_option]- in CTE —
SELECTcan start with aWITHclause to define common table expressions accessible within theSELECT - modifiers — affect the operation of the statement
ALL(default),DISTINCT—DISTINCTimplicitly sorts the data,DISTINCTROWis an aliasother_modifierstbd, modifiers beginning withSQL_are MySQL extensions —HIGH_PRIORITY,STRAIGHT_JOIN,SQL_SMALL_RESULT,SQL_BIG_RESULT,SQL_BUFFER_RESULT,SQL_NO_CACHE,SQL_CALC_FOUND_ROWS
position— column index, non-standard, deprecatedFOR UPDATE,FOR SHARE— locking reads
- in CTE —
select_exprinSELECT— the select list that indicates which columns to retrievecol_name [[AS] alias_name]col_name—col_name,tbl_name.col_name, ordb_name.tbl_name.col_name,*,tbl_name.*- single
*— all columns from all tables, probable error when used with other items tbl_name.*— all columns from the named table
- single
- alias and position scope — can be used in
GROUP BY,ORDER BY, orHAVINGclauses, but cannot be used inWHEREclause, because the column value might not yet be determined when theWHEREclause is executedSELECT college, region AS r, seed AS s FROM tournament ORDER BY r, s; SELECT college, region, seed FROM tournament ORDER BY 2, 3; OVER— seeWINDOW
into_optioninSELECT,INTO{ INTO OUTFILE 'file_name' [CHARACTER SET charset_name] export_options | INTO DUMPFILE 'file_name' | INTO var_name [, var_name] ... }var_list— the number of variables must match the number of columns; the query should return a single rowOUTFILEDUMPFILE— writes a single row to a file without any formatting- more
execution order — below is gross, the actual subject to optimizer
SET @mysql_order := ''; SELECT @mysql_order := CONCAT(@mysql_order," SELECT ") FROM (SELECT @mysql_order := CONCAT(@mysql_order," FROM ")) AS t1 JOIN (SELECT @mysql_order := CONCAT(@mysql_order," JOIN1 ")) AS t ON ((SELECT @mysql_order := CONCAT(@mysql_order," ON1 ")) | (RAND() < 1)) JOIN (SELECT @mysql_order := CONCAT(@mysql_order," JOIN2 ")) AS t2 ON ((SELECT @mysql_order := CONCAT(@mysql_order," ON2 ")) | (RAND() < 1)) WHERE ((SELECT @mysql_order := CONCAT(@mysql_order," WHERE ")) | (RAND() < 1)) GROUP BY (SELECT @mysql_order := CONCAT(@mysql_order," GROUP_BY ")) HAVING (SELECT @mysql_order := CONCAT(@mysql_order," HAVING ")) ORDER BY (SELECT @mysql_order := CONCAT(@mysql_order," ORDER_BY ")); SELECT @mysql_order;FROM JOIN1 JOIN2 WHERE ON2 ON1 SELECT ORDER_BY GROUP_BY HAVING- execution order defined in ANSI SQL —
FROM,WHERE,GROUP BY,HAVING,SELECT,ORDER BY
- execution order defined in ANSI SQL —
# FROM, JOIN
FROM— the table or tables from which to retrieve rows[FROM table_references [PARTITION partition_list]]PARTITION— partition selectiontable_referencestable_reference [, table_reference] ...
table_referenceinFROM, simplifiedtbl_name [[AS] alias] [index_hint_list]tbl_name—tbl_name, ordb_name.tbl_name- derived tables
FROM (SELECT first_name, last_name, email FROM customer WHERE first_name = 'JESSIE' ) AS cust;
- derived tables
JOIN— join if more than one table specifiedDUAL— dummy table name, for rows computed without reference to any tableindex_hint_list— give the optimizer information about how to choose indexes during query processing
table_referenceinFROMtable_factor | joined_tabletable_factortbl_name [PARTITION (partition_names)] [[AS] alias] [index_hint_list] | table_subquery [AS] alias [(col_list)] | ( table_references )( table_references )— MySQL extension to allow a list instead of a singletable_reference, each comma is considered as equivalent to an inner joinindex_hint_listindex_hint_list: index_hint [, index_hint] ... index_hint: USE {INDEX|KEY} [FOR {JOIN|ORDER BY|GROUP BY}] ([index_list]) | {IGNORE|FORCE} {INDEX|KEY} [FOR {JOIN|ORDER BY|GROUP BY}] (index_list) index_list: index_name [, index_name] ...col_list— a list of names for the derived table columns
joined_tableintable_referencejoined_table: table_reference {[INNER | CROSS] JOIN | STRAIGHT_JOIN} table_factor [join_specification] | table_reference LEFT [OUTER] JOIN table_reference join_specification | table_reference NATURAL [INNER | LEFT [OUTER]] JOIN table_factor- special joins
- tables joined multiple times — use alias for name resolving
- self joins — when self-referencing foreign keys exist, like a prequel column in a film table
- cross join or inner join, order of
table_referenceortable_factordoes not matterCROSS JOIN— Cartesian product, all permutations, nojoin_specificationINNER JOIN— only matches matchingjoin_specification, multiple records if multiple matches- MySQL extension —
JOIN,INNER JOIN,CROSS JOINare equivalent syntactically, although not semantically STRAIGHT_JOIN— likeJOIN, but the left table is always read before the right table
LEFT [OUTER] JOIN—NULLif no matchingNATURAL [...] JOIN— equivalent to anINNER JOINor aLEFT JOINwith aUSINGclause that names all columns that exist in both tablesjoin_specificationON search_condition | USING (join_column_list)search_condition— filtering likeWHEREjoin_column_list— list of columns that must exist in both tablescolumn_name [, column_name] ...USINGvsON—USINGwith redundant column elimination,ONwithout- redundant column elimination — by
COALESCE()columns with the same name, as in outer joinsNULLif no matchingCOALESCE(a.c1, b.c1), COALESCE(a.c2, b.c2), COALESCE(a.c3, b.c3) a.c1, a.c2, a.c3, b.c1, b.c2, b.c3
- redundant column elimination — by
- special joins
# UNION
UNIONSELECT ... UNION [ALL | DISTINCT] SELECT ... [UNION [ALL | DISTINCT] SELECT ...]- order — unordered, intermediate
ORDER BYare optimized out when withoutLIMIT - column name and type — names taken from the first
SELECT; corresponding columns should be the same type, otherwise determined by all values of the column ALLorDISTINCT—DISTINCTby default, duplicate rows removed; when mixed, aDISTINCTunion overrides anyALLunion to its left- additional column — help determine which
SELECTeach row comes from, and by which optionally order(SELECT 1 AS sort_col, col1a, col1b, ... FROM t1) UNION (SELECT 2, col2a, col2b, ... FROM t2) ORDER BY sort_col;
- order — unordered, intermediate
INTERSECT— ANSI SQL but not in MySQLEXCEPT— ANSI SQL but not in MySQL
# Filtering, Ordering, Grouping, Limiting
WHEREwhere_condition— an expression that evaluates to true for each row to be selected- no aggregate functions — can use any of the functions and operators, except for aggregate (summary) functions
- see Operators and Functions
GROUP BY,ORDER BY[GROUP BY {col_name | expr | position}, ... [WITH ROLLUP]] [ORDER BY {col_name | expr | position} [ASC | DESC], ... [WITH ROLLUP]]ORDER BY— defaults toACS, outermost one take precedence if used in nested multiple subqueries- resolve unqualified column or alias — by searching in the
select_exprvalues, then in the columns of the tables in theFROMclause
- resolve unqualified column or alias — by searching in the
GROUP BY- resolve unqualified column or alias — reverse order of
ORDER BY - implicit groups — all rows as a implicit group when no
GROUP BYclause present sql_modeONLY_FULL_GROUP_BY— reject queries for which the select list,HAVINGcondition, orORDER BYlist refer to non-aggregated columns that are neither named in theGROUP BYclause nor are functionally dependent on (uniquely determined by)GROUP BYcolumnsANY_VALUE(arg)— suppress the test for nondeterminism, equivalent to disablesql_modeONLY_FULL_GROUP_BY; use when a selected non-aggregated column is effectively functionally dependent on aGROUP BYcolumn by MySQL cannot determine itWITH ROLLUP— produce another (super-aggregate) row for eachGROUP BYcolumnmysql> SELECT year, SUM(profit) AS profit FROM sales GROUP BY year WITH ROLLUP; +------+--------+ | year | profit | +------+--------+ | 2000 | 4525 | | 2001 | 3010 | | NULL | 7535 | +------+--------+- name super-aggregate row —
GROUPING(expr [, expr] ...)return a bit vector, big endian, 1 when super-aggregateSELECT IF(GROUPING(year), 'All years', year) AS year, IF(GROUPING(country), 'All countries', country) AS country, IF(GROUPING(product), 'All products', product) AS product, SUM(profit) AS profit FROM sales GROUP BY year, country, product WITH ROLLUP;
- name super-aggregate row —
- no aggregation in
SELECTclause — return first row of a groupSELECT Email FROM Person GROUP BY Email HAVING COUNT(Email) > 1;
- resolve unqualified column or alias — reverse order of
max_sort_lengthsystem variable — onlymax_sort_lengthbytes compared, defaults to 1024 bytes
HAVING[HAVING where_condition]- for filter after
GROUP BY— must reference only columns in theGROUP BYclause or columns used in aggregate functions- extended in MySQL — permits
HAVINGto refer to columns in theSELECTlist and columns in outer subqueries as well - applied nearly last (before
LIMIT), with no optimization
- extended in MySQL — permits
- for filter after
LIMIT— outermost one take precedence if used in nested multiple subqueries[LIMIT {[offset,] row_count | row_count OFFSET offset}]offset— use 0 to include first row- up to end — use a large number
row_count
# WINDOW
WINDOW— windows for window functionsWINDOWclause inSELECT[WINDOW window_name AS (window_spec) [, window_name AS (window_spec)] ...]over_clausein aggregation and window functionsover_clause: {OVER (window_spec) | OVER window_name}window_specwindow_spec: [window_name] [partition_clause] [order_clause] [frame_clause]- empty — all rows
partition_clause— likeGROUP BY, differs from table partitioningPARTITION BY expr [, expr] ...order_clause— applies within individual partitionsORDER BY expr [ASC|DESC] [, expr [ASC|DESC]] ...frame_clause— a subset of the current partition, see below
frame_clause— a subset of the current partition, enabling move within a partition depending on the location of the current rowframe_clause: frame_units frame_extent- limitation — some window functions operate on the entire partition, frames are ignored for them
frame_units{ROWS | RANGE}ROWS— the frame is defined by beginning and ending row positionsRANGE— the frame is defined by rows within a value range
frame_extentframe_extent: {frame_start | BETWEEN frame_start AND frame_end} frame_start, frame_end: { CURRENT ROW | UNBOUNDED PRECEDING | UNBOUNDED FOLLOWING | expr PRECEDING | expr FOLLOWING }- single
frame_start—CURRENT ROWis implicitly the end BETWEEN—frame_startmust not occur later thanframe_end
- single
- default frame depends on
ORDER BY- with
ORDER BYRANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW - without
ORDER BYRANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
- with
- example
ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING
example
SELECT val, ROW_NUMBER() OVER w AS 'row_number', CUME_DIST() OVER w AS 'cume_dist', PERCENT_RANK() OVER w AS 'percent_rank', SUM(val) OVER () AS total_profit FROM numbers WINDOW w AS (ORDER BY val);
# Subqueries
subqueries
- return type — scalar, column, row, and table
- parentheses — even in functions, like
UPPER((SELECT s1 FROM t1)) - correlated subquery — a subquery that contains a reference to a table that also appears in the outer query
- limitations — see docs
row constructors —
(1, 2)orROW(1, 2), scalar if only one columncomparaison subqueries
- subquery type when no modifiers — correspondent. For a comparison of the subquery to a scalar, the subquery must return a scalar. For a comparison of the subquery to a row constructor, the subquery must be a row subquery that returns a row with the same number of values as the row constructor
non_subquery_operand comparison_operator (subquery)NULLwhen empty
ANY,IN,SOMEoperand comparison_operator { ANY | SOME } (subquery) operand IN (subquery)ALL—TRUEwhen empty subquery,UNKNOWNwhen containingNULLoperand comparison_operator ALL (subquery)NULLwhen empty and aggregatedSELECT * FROM t1 WHERE 1 > ALL (SELECT MAX(s1) FROM t2);
- subquery type when no modifiers — correspondent. For a comparison of the subquery to a scalar, the subquery must return a scalar. For a comparison of the subquery to a row constructor, the subquery must be a row subquery that returns a row with the same number of values as the row constructor
EXISTSorNOT EXISTS— whether a subquery is empty- example: What kind of store is present in all cities?
SELECT DISTINCT store_type FROM stores s1 WHERE NOT EXISTS ( SELECT * FROM cities WHERE NOT EXISTS ( SELECT * FROM cities_stores WHERE cities_stores.city = cities.city AND cities_stores.store_type = stores.store_type));
- example: What kind of store is present in all cities?
derived table
SELECT ... FROM (subquery) [AS] tbl_name [(col_list)] ...- alias — mandatory, because every table in a
FROMclause must have a name col_list— names for the derived table, must cover all columns- limitation — prior to MySQL 8.0.14, a derived table cannot contain outer references
- example
select Num as 'ConsecutiveNums' from `Logs`, (select @cnt := 0, @prev := 0) as _init where (@cnt := IF(@prev = (@prev := Num), @cnt + 1, 1)) = 3; LATERAL— can refer to columns from other tables, “this derived table depends on previous tables on its left side”- example — solve the problem that max value would be calculated twice if using subqueries in
SELECTclause, because a subquery inSELECTclause can only produce one columnSELECT salesperson.name, max_sale.amount, max_sale_customer.customer_name FROM salesperson, -- calculate maximum size, cache it in transient derived table max_sale LATERAL (SELECT MAX(amount) AS amount FROM all_sales WHERE all_sales.salesperson_id = salesperson.id) AS max_sale, -- find customer, reusing cached maximum size LATERAL (SELECT customer_name FROM all_sales WHERE all_sales.salesperson_id = salesperson.id AND all_sales.amount = -- the cached maximum size max_sale.amount) AS max_sale_customer;
- example — solve the problem that max value would be calculated twice if using subqueries in
- alias — mandatory, because every table in a
# WITH
Common Table Expressions, CTE — a named temporary result set that exists within the scope of a single statement, from MySQL 8.0
CTE positions
- at the beginning of
SELECT,UPDATE, andDELETEstatementsWITH ... SELECT ... WITH ... UPDATE ... WITH ... DELETE ...- CTE not updatable — need to refer to the original table to update / delete rows, use CTE in other clauses or joining CTE with original table one-to-one as workaround
- at the beginning of subqueries
SELECT ... WHERE id IN (WITH ... SELECT ...) ... SELECT * FROM (WITH ... SELECT ...) AS dt ... - immediately preceding
SELECTfor statements that include aSELECTstatementINSERT ... WITH ... SELECT ... REPLACE ... WITH ... SELECT ... CREATE TABLE ... WITH ... SELECT ... CREATE VIEW ... WITH ... SELECT ... DECLARE CURSOR ... WITH ... SELECT ... EXPLAIN ... WITH ... SELECT ...
- at the beginning of
WITHwith_clause: WITH [RECURSIVE] cte_name [(col_name [, col_name] ...)] AS (subquery) [, cte_name [(col_name [, col_name] ...)] AS (subquery)] ...- more tbd
- example
WITH cte1 AS (SELECT a, b FROM table1), cte2 AS (SELECT c, d FROM table2) SELECT b, d FROM cte1 JOIN cte2 WHERE cte1.a = cte2.c;
# DELETE
DELETEsyntax- single table delete
DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROM tbl_name [[AS] tbl_alias] [PARTITION (partition_name [, partition_name] ...)] [WHERE where_condition] [ORDER BY ...] [LIMIT row_count]ORDER BY— delete by the order specified
- multiple table delete
DELETE [LOW_PRIORITY] [QUICK] [IGNORE] tbl_name[.*] [, tbl_name[.*]] ... FROM table_references [WHERE where_condition]DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROM tbl_name[.*] [, tbl_name[.*]] ... USING table_references [WHERE where_condition]- target — matching rows
- alias coerced when declared, can only be declared in
table_referencesDELETE t1 FROM test AS t1, test2 WHERE ...
- single table delete
DELETEattributes- subqueries — cannot delete from a table and select from the same table in a subquery
- workaround — intermediate cache
DELETE FROM Person WHERE Person.Id NOT IN (SELECT * FROM (SELECT MIN(Id) FROM Person GROUP BY Email) AS _temp);- still error if optimizer optimize out the subquery — see release notes (opens new window) for details and workarounds
- workaround — use CTE
WITH rem AS (SELECT MIN(Id) AS id FROM Person GROUP BY Email) DELETE FROM Person WHERE Person.Id NOT IN (SELECT * FROM rem);
- workaround — intermediate cache
- modifiers —
LOW_PRIORITY,QUICK,IGNORE, see docs - keep desired in lieu of delete unwanted
INSERT INTO t_copy SELECT * FROM t WHERE ... ; RENAME TABLE t TO t_old, t_copy TO t; DROP TABLE t_old;
- subqueries — cannot delete from a table and select from the same table in a subquery
# UPDATE
UPDATE- single table
UPDATEUPDATE [LOW_PRIORITY] [IGNORE] table_reference SET assignment_list [WHERE where_condition] [ORDER BY ...] [LIMIT row_count] - multi-table update — each matching row is updated once
UPDATE [LOW_PRIORITY] [IGNORE] table_references SET assignment_list [WHERE where_condition] assignment_listassignment_list: assignment [, assignment] ... assignment: col_name = {expr | DEFAULT}
- single table
# INSERT
INSERTsyntaxINSERT ... VALUESINSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE] [INTO] tbl_name [PARTITION (partition_name [, partition_name] ...)] [(col_name [, col_name] ...)] { VALUES (value_list) [, (value_list)] ... | VALUES ROW(value_list)[, ROW(value_list)][, ...] } [AS row_alias[(col_alias [, col_alias] ...)]] [ON DUPLICATE KEY UPDATE assignment_list]INSERT ... SETINSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE] [INTO] tbl_name [PARTITION (partition_name [, partition_name] ...)] [AS row_alias[(col_alias [, col_alias] ...)]] SET assignment_list [ON DUPLICATE KEY UPDATE assignment_list]INSERT ... SELECT— insert many rows into a table from the result of aSELECTstatementINSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE] [INTO] tbl_name [PARTITION (partition_name [, partition_name] ...)] [(col_name [, col_name] ...)] [AS row_alias[(col_alias [, col_alias] ...)]] {SELECT ... | TABLE table_name} [ON DUPLICATE KEY UPDATE assignment_list]value_listandassignment_listvalue_list: value [, value] ... value: {expr | DEFAULT} assignment_list: assignment [, assignment] ... assignment: col_name = [row_alias.]value
clauses in
INSERT- resort to update when not permitted duplicates — update using
assignment_listwhen a duplicate value in aUNIQUEindex orPRIMARY KEY[ON DUPLICATE KEY UPDATE assignment_list] - refer to previous columns
INSERT INTO tbl_name (col1,col2) VALUES (15,col1*2);
- resort to update when not permitted duplicates — update using
REPLACE— MySQL extension,INSERTbut if an old row in the table has the same value as a new row for aPRIMARY KEYor aUNIQUEindex, the old row is deleted before the new row is inserted
# TCL
# Transactions
START TRANSACTIONorBEGIN— start a new transactionSTART TRANSACTION [transaction_characteristic [, transaction_characteristic] ...] transaction_characteristic: { WITH CONSISTENT SNAPSHOT | READ WRITE | READ ONLY }WITH CONSISTENT SNAPSHOT— starts a consistent read; the effect is the same as issuing aSTART TRANSACTIONfollowed by aSELECTfrom any InnoDB tableREAD WRITE,READ ONLY— set the transaction access mode; inREAD ONLYmode, MySQL enables extra optimizations for queries on InnoDB tables, the transaction can still modify or lockTEMPORARYtables- implicit commits — beginning a transaction and some statements including DDLs causes any pending transaction to be committed
- implicit unlock — beginning a transaction also causes table locks acquired with
LOCK TABLESto be released, as though you had executedUNLOCK TABLES BEGIN [WORK]— aliases ofSTART TRANSACTION
COMMIT, andROLLBACKstatementsCOMMIT [WORK] [AND [NO] CHAIN] [[NO] RELEASE] ROLLBACK [WORK] [AND [NO] CHAIN] [[NO] RELEASE] SET autocommit = {0 | 1}COMMIT— commits the current transaction, making its changes permanent, stored in the binary log in one chunk??ROLLBACK— rolls back the current transaction, canceling its changes- DDL cannot be rolled back
SET autocommit— disables or enables the default autocommit mode for the current session- defaults to
1— each statement is atomic, as if it were surrounded bySTART TRANSACTIONandCOMMIT
- defaults to
WORK— optional- after completion
AND CHAIN— a new transaction to begin with the same isolation level and access mode as soon as the current one endsRELEASE— causes the server to disconnect the current client session after terminating the current transactionNO— negate- system variable
completion_type
SAVEPOINTSAVEPOINT identifier ROLLBACK [WORK] TO [SAVEPOINT] identifier RELEASE SAVEPOINT identifieridentifier— overwrite when collisonROLLBACK TO— without terminating the transaction, changes are undone, but InnoDB does not release the row locks that were stored in memory after the savepoint, except new insert rows; later save points discardedRELEASE SAVEPOINT— delete a save point- deconstruction — all deleted after single
COMMITorROLLBACK
# SET TRANSACTION
SET TRANSACTIONSET [GLOBAL | SESSION] TRANSACTION transaction_characteristic [, transaction_characteristic] ... transaction_characteristic: { ISOLATION LEVEL level | access_mode }GLOBALorSESSION— global scope, or session scope, defaults to only next transaction within the same sessionaccess_modeREAD WRITE(default)READ ONLY
level— isolation levels for InnoDB, relax to minimize the amount of overhead for lockingSERIALIZABLE— likeREPEATABLE READ, but all reads are implicitly locking readsREPEATABLE READ(default)- consistent read — read the snapshot established by the first read
- for locking reads (
SELECTwithFOR UPDATEorFOR SHARE),UPDATE, andDELETEstatements — next-key locks, record locks, gap locks, see docs
READ COMMITTED- consistent read — read the snapshot that is reset to the time of each consistent read operation
- for locking reads (
SELECTwithFOR UPDATEorFOR SHARE),UPDATE, andDELETEstatements — record locks; gap locking is only used for foreign-key constraint checking and duplicate-key checking, see docs
READ UNCOMMITTED— no consistent read; otherwise likeREAD COMMITTED
check current
level—SHOW VARIABLES LIKE '%iso%'
# Locks
instance lock — prevents files from being created, renamed, or removed
LOCK INSTANCE FOR BACKUPUNLOCK INSTANCEtable lock — explicitly acquires table locks for the current client session
LOCK TABLES tbl_name [[AS] alias] lock_type [, tbl_name [[AS] alias] lock_type] ... lock_type: { READ [LOCAL] | [LOW_PRIORITY] WRITE }UNLOCK TABLES- more
other locks — see Locks
show lock
SHOW ENGINE INNODB STATUSSHOW OPEN TABLES
# Dynamic SQL
prepared statements
- merits
- less overhead for parsing the statement each time it is executed
- protection against SQL injection attacks
- scope — session specific if created in a session, global if created in a stored routine
- control — system variable
max_prepared_stmt_count - allowed statements — see docs
- merits
PREPAREPREPARE stmt_name FROM preparable_stmtpreparable_stmt— string literal or a user variable of a single SQL statement,?as parameter markers, keywords and identifiers cannot be parameters- implicit
DEALLOCATE— prepared statements with the samestmt_nameare deallocated implicitly
EXECUTEEXECUTE stmt_name [USING @var_name [, @var_name] ...]DEALLOCATE PREPARE{DEALLOCATE | DROP} PREPARE stmt_name
# Language Structure
# Basics
case sensitivity
- SQL statements — case insensitive
- database, trigger, table names — depends on file system and CLI option
--lower-case-table-names[=#]or system variablelower_case_table_names,1suggested with lowercase storing and insensitive comparisons - table aliases — platform dependent
index — start from 1
# Identifiers, User Variables and Comments
comment
- inline comment —
--,#(less commonly supported) - comment block:
/**//*! */— MySQL-specific code/*![version] MySQL-specific code *//*+ */— optimizer hints
- inline comment —
identifiers
- identifier quote — the
`character- also
"ifsql_modeANSI_QUOTES— Treat"as an identifier quote character and not as a string quote character - escape backtick —
``
- also
- identifier characters
- permitted characters when unquoted —
[$_0-9a-zA-Z\x80-\uFFFF], cannot be all numbers - permitted characters when quoted —
[\x01-\uFFFF] - space — database, table, and column names cannot end with space characters
- permitted characters when unquoted —
- qualifier —
schema_name.func_name(),`my-table`.`my-column` - mapping to filenames — refer to docs
- identifier quote — the
user defined variables — session specific
SET @var_name = expr [, @var_name = expr] ... SET @var_name := expr [, @var_name = expr] ...@var_name,@'my-var',@"my-var", or@`my-var`- corresponding table in
PERFORMANCE_SCHEMA—PERFORMANCE_SCHEMA.user_variables_by_thread - supported data types — integer, decimal (no precision), floating-point, binary or nonbinary string, or
NULL- auto conversion — other types are converted
- defaults to
NULL, as string when selected in a result set
- use in expressions —
@var_name, intended to provide data values, cannot be used directly as identifiers - evaluated on the client — a variable that is assigned a value in the select expression list, does not work in
HAVING,GROUP BY, andORDER BY - example
select Num as 'ConsecutiveNums' from `Logs`, (select @cnt := 0, @prev := 0) as _init where (@cnt := IF(@prev = (@prev := Num), @cnt + 1, 1)) = 3;
# Literals
NULLstrings literals —
', or"if not insql_modeANSI_QUOTES[_charset_name]'string' [COLLATE collation_name]SELECT _utf8mb4'abc' COLLATE utf8mb4_danish_ci; SELECT _utf8mb4 0x4D7953514C COLLATE utf8mb4_danish_ci;- escape sequences -
\0,\',\",\b(backspace),\n,\r,\t,\Z(ASCII 26 (Control+Z)),\\,\%,\_\',\"— also"'",'"',''enclosed in single quotes,""enclosed in double quotes\%,\_— only in in pattern-matching contexts, otherwise just the strings\%and\_, not to%and_- backslash ignored for all other escape sequences —
\xis justx - raw string —
QUOTE(str) - controlled by
sql_modeNO_BACKSLASH_ESCAPES
SETtype — comma separated string, like'a,b'
- escape sequences -
numbers literals
- (fixed-point) number
SELECT 1, .2, 3.4, -5, -6.78, +9.10 - approximate-value (floating-point) number
SELECT 1.2E3, 1.2E-3, -1.2E3, -1.2E-3, 1e3 TRUE,FALSE— 1, 0
- (fixed-point) number
BIT, number or binary string literals- hexidecimal
[_charset_name] X'val' [COLLATE collation_name]X'val',x'val',valmust contain an even number of digits0xval, case sensitive, not0Xcharset_name— defaults tobinary- numeric contexts — treated like
BIGINT, to ensure numeric treatment,+0orCAST(X'41' AS UNSIGNED) - bit operators — defaults to numeric context, for binary string context, use a
_binaryintroducer for at least one of the arguments - get hex —
HEX(str),HEX(N)
- binary — like hexidecimal, but no constraint on number of digits
[_charset_name] b'val' [COLLATE collation_name]
- hexidecimal
date and time literals
- quoted strings and numbers — like
'2015-07-21','20150721', and20150721'YYYY-MM-DD'or'YY-MM-DD','YYYY-MM-DD hh:mm:ss'or'YY-MM-DD hh:mm:ss', any punctuation character may be used as the delimiter'YYYYMMDD'or'YYMMDD','YYYYMMDDhhmmss'or'YYMMDDhhmmss','hhmmss'YYYYMMDDorYYMMDD,YYYYMMDDhhmmss,YYMMDDhhmmss,ss,mmss, orhhmmssformatted numbers- timezone offset — suffices like
+08:00, from-14:00to+14:00INSERT INTO ts (col) VALUES ('2020-01-01 10:10:10'), ('2020-01-01 10:10:10+05:30'), ('2020-01-01 10:10:10-08:00'); - trailing fractional seconds
- preceding zeros in delimited strings — optional
TIMEwith or without days —'D hh:mm:ss','hh:mm:ss','hh:mm','D hh:mm','D hh', or'ss',Dfrom 0 to 34 days
- ANSI SQL — space delimiter is optional
DATE 'str' TIME 'str' TIMESTAMP 'str'
- quoted strings and numbers — like
# Operators and Functions
implicit type conversion — use
CAST()for explict conversion- between strings and numbers —
1+'1',CONCAT(1)- character set and collation when implicitly converted to string — by
character_set_connectionandcollation_connection
- character set and collation when implicitly converted to string — by
- when comparing
NULL— result inNULLif one or both arguments areNULL, except<=>- hexidecimal values — as binary strings if not compared to a number
- when
TIMESTAMPorDATETIMEcompared to constants — constants converted - when comparing strings to numbers — convert to floating point numbers
- when arithmetic — see below
- between strings and numbers —
operator priority
- unary operators —
-,~(bit inversion) ^, arithmetic operators- bitwise operators
- comparison operators
- logical operators
- assignment operators —
:=,=(inSETstatements andSETclauses ofUPDATE); support multiple assignments
- unary operators —
numeric operators and functions
+,-,*— result is floating-point if any operand is floating-point, otherwiseUNSIGNEDif any operand isUNSIGNED/- scale of the result — when using two exact-value operands, the scale of the result is the scale of the first operand plus the value of the
div_precision_increment(defaults to 4) system variable - division by zero —
NULLor error, controlled bysql_modeERROR_FOR_DIVISION_BY_ZERO
- scale of the result — when using two exact-value operands, the scale of the result is the scale of the first operand plus the value of the
DIV— integer division returningBIGINT, non-integer types are converted toDECIMALand useDECIMALarithmetic, error when overflow%,MOD,MOD(N,M)
bitwise operators and functions
&,>>,<<,^,|,~BIT_COUNT(N)
comparison operators and functions — result in a value of
1(TRUE),0(FALSE), orNULL- L, E and G, also row operands — for example,
(a, b) <= (x, y)= > < >= <= <> != <=><=>—NULL-safe equal, equivalent to the ANSI SQLIS NOT DISTINCT FROM<>or!=— not equal
expr [NOT] IN (value,...)— also as row operands, useCAST()for best results,NULLif left value isNULLorNULLamong right values when not foundISIS [NOT] boolean_value—boolean_value:TRUE,FALSE, orUNKNOWN(forNULL)IS [NOT] NULL,ISNULL(expr)AUTO_INCREMENTcolumns — controlled by system variablesql_auto_is_null- zero values for
DATEnadDATETIMEcolumns — zero valuesIS NULLwhen the column defined asNOT NULL
- string related —
NULLif any parameter isNULLexpr1 SOUNDS LIKE expr2—SOUNDEX(expr1) = SOUNDEX(expr2)expr [NOT] LIKE pat [ESCAPE 'escape_char']- matching on a per-character basis — some collate rules may not work, trailing space significant
- wildcard —
%for any number of characters,_for one character - escape — defaults to use
\as escape character
expr [NOT] REGEXP pat,expr [NOT] RLIKE pat—REGEXP_LIKE()REGEXP_LIKE(expr, pat[, match_type])- compatibility — not multibyte safe prior to 8.0.4, and more
match_typeoptions —ccase sensitive,icase insensitive, more- regex syntax — limited support, see docs
STRCMP(expr1,expr2)
expr [NOT] BETWEEN min AND max— inclusive, equivalent to the expression(min <= expr AND expr <= max)if of same type, useCAST()for best resultsCASE— control flow,NULLif no else, different when use inside stored programs- switch case
CASE value WHEN [compare_value] THEN result [WHEN [compare_value] THEN result ...] [ELSE result] END - if else
CASE WHEN [condition] THEN result [WHEN [condition] THEN result ...] [ELSE result] END result— the aggregated type of all result values, see docs for details- in tandem —
ELT(),FIELD()
- switch case
- pick value or index
COALESCE(value,...)— the first non-NULLargumentGREATEST(value1,value2,...),LEAST(value1,value2,...)— with implicit type conversion,NULLif anyNULLargumentINTERVAL(N,N1,N2,N3,...)— binary searchN,N_irequired to be incremental, arguments treated as integers,-1ifNisNULL,0ifN < N1,1ifN1 <= N < N2and so onIF(expr1,expr2,expr3)— ternaryexpr1 ? expr2 : expr3in other languages, return type is aggregatedIFNULL(expr1,expr2)—expr1 ?? expr2in other languages,NULLcoalescing, return type is the generalized typeNULLIF(expr1,expr2)—IF(expr1 = expr2, NULL, expr1), return type asexpr1,expr1may be evaluated twice
- L, E and G, also row operands — for example,
logical operators
- short circuit — undefined and should not rely on, use
CASEfor guaranteed order or bitwise operator to ensure execution NOT—NOT NULLisNULLAND—1 AND NULLandNULL AND 1isNULLOR—1 OR NULLandNULL or 1isNULL||— deprecated asOR, when insql_modePIPES_AS_CONCAT,||is SQL-standard string concatenation
XOR—NULLif anyNULL
- short circuit — undefined and should not rely on, use
# Cast, Math, Date, Time and String Functions
cast
- use extract functions for date times
- string to number — use arithmetic, like
'1' | 0 - convert between character sets
CONVERT(expr USING transcoding_name) [COLLATE collation_name] CONVERT(string, CHAR[(N)] CHARACTER SET charset_name) [COLLATE collation_name] CAST(string AS CHAR[(N)] CHARACTER SET charset_name) [COLLATE collation_name] BINARY expr— to a binary string, force byte comparaison and trailing spaces significantCAST(expr AS type [ARRAY]),CONVERT(expr,type)type— see docs, some data types andSIGNED,UNSIGNED
mathmatical functions —
NULLwhen error- sign
ABS(X)SIGN(X)
- rounding
CEIL(X),CEILING(X),FLOOR(X)— return floating type when string or floating-point argumentsROUND(X),ROUND(X,D)— precisionDcan be negativeTRUNCATE(X,D)
RAND([N])—Math.random()in Java,Nfor seed- retrieve in random order —
ORDER BY RAND()
- retrieve in random order —
POW(X,Y),POWER(X,Y),SQRT(X)EXP(X),LN(X),LOG(X),LOG(B,X),LOG2(X),LOG10(X),LOG2(X),LOG10(X)- trigonometric — in radian
PI()DEGREES(X),RADIANS(X)— conversion between radians and degreesACOS(X),ASIN(X)ATAN(X),ATAN(Y,X),ATAN2(Y,X)— the latter two asY/XCOT(X)— cotangentCOS(X),SIN(X),TAN(X)
CRC32(expr)
- sign
date and time functions
- excess information ignored — ignore the time part if expect date values and vice versa
- current date or time evaluated at start — functions like
NOW()evaluated only once per query at the start of query execution, exceptSYSDATE()NOW([fsp]),CURRENT_TIMESTAMP,CURRENT_TIMESTAMP([fsp]),LOCALTIME,LOCALTIME([fsp]),LOCALTIMESTAMP,LOCALTIMESTAMP([fsp])SYSDATE([fsp])— nondeterministic, evaluated to the time at which executedCURDATE(),CURRENT_DATE,CURRENT_DATE()CURTIME([fsp]),CURRENT_TIME,CURRENT_TIME([fsp])UNIX_TIMESTAMP([date])— when without parametersUTC_DATE,UTC_DATE();UTC_TIME,UTC_TIME([fsp]);UTC_TIMESTAMP,UTC_TIMESTAMP([fsp])
- arithmetic
ADDDATE(date,INTERVAL expr unit),DATE_ADD(date,INTERVAL expr unit)SUBDATE(date,INTERVAL expr unit),DATE_SUB(date,INTERVAL expr unit)ADDDATE(expr,days);SUBDATE(expr,days)FROM_DAYS(N)ADDTIME(expr1,expr2);SUBTIME(expr1,expr2)TIMEDIFF(expr1,expr2)DATEDIFF(expr1,expr2)PERIOD_ADD(P,N)PERIOD_DIFF(P1,P2)TIMESTAMP(expr1,expr2)TIMESTAMPADD(unit,interval,datetime_expr),TIMESTAMPDIFF(unit,datetime_expr1,datetime_expr2)
- of
LAST_DAY(date)— last day of the monthMAKEDATE(year,dayofyear)MAKETIME(hour,minute,second)SEC_TO_TIME(seconds)STR_TO_DATE(str,format)FROM_UNIXTIME(unix_timestamp[,format])TIMESTAMP(expr)
- timezone
CONVERT_TZ(dt,from_tz,to_tz)
- format
- with format
DATE_FORMAT(date,format)— see docs for formats,STR_TO_DATE(str,format)for inversionTIME_FORMAT(time,format)FROM_UNIXTIME(unix_timestamp[,format])GET_FORMAT({DATE|TIME|DATETIME}, {'EUR'|'USA'|'JIS'|'ISO'|'INTERNAL'})
- name
DAYNAME(date)— Saturday, etc.MONTHNAME(date)
- extract
EXTRACT(unit FROM date)MICROSECOND(expr)SECOND(time)MINUTE(time)HOUR(time)TIME(expr)DAY(date),DAYOFMONTH(date)MONTH(date)YEAR(date)DATE(expr)
- index
DAYOFMONTH(date),DAY(date)DAYOFYEAR(date)DAYOFWEEK(date)— start from 1 = Sunday -WEEKDAY(date)— start from 0 = MondayQUARTER(date)WEEK(date[,mode])WEEKOFYEAR(date)—WEEK(date,3)YEARWEEK(date),YEARWEEK(date,mode)— return year and week
- conversion
TIME_TO_SEC(time)TO_DAYS(date)— since year 0TO_SECONDS(expr)UNIX_TIMESTAMP([date])
- with format
string functions
- char at
ASCII(str)ORD(str)— byte representation
- length
BIT_LENGTH(str)OCTET_LENGTH(str),LENGTH(str)— byte lengthCHAR_LENGTH(str), CHARACTER_LENGTH(str)
- to string, of
BIN(N)OCT(N)HEX(N)CONV(N,from_base,to_base)—Ntreated as unsigned unlessfrom_baseis negativeEXPORT_SET(bits,on,off[,separator[,number_of_bits]])—BIN()butonas 1 andoffas 0MAKE_SET(bits,str1,str2,...)— choose from bit vectorbits, little endianCHAR(N,... [USING charset_name])— from byte arrayFORMAT(X,D[,locale])— localizationLOAD_FILE(file_name)
- find — 0 if not found
INSTR(str,substr)REGEXP_INSTR(expr, pat[, pos[, occurrence[, return_option[, match_type]]]])REGEXP_SUBSTR(expr, pat[, pos[, occurrence[, match_type]]])—REGEXP_INSTR()but return matched result
LOCATE(substr,str),LOCATE(substr,str,pos),POSITION(substr IN str)
- transform
CONCAT(str1,str2,...)CONCAT_WS(separator,str1,str2,...)INSERT(str,pos,len,newstr)REPLACE(str,from_str,to_str)REPEAT(str,count)SPACE(N)—REPEAT(' ', N)REVERSE(str)- case
LOWER(str),LCASE(str)— for a binary string, first convert it to a non-binary stringUPPER(str),UCASE(str)
- substring — multibyte safe
LEFT(str,len)— from startRIGHT(str,len)— from endSUBSTRING(str,pos,len),MID(str,pos,len)SUBSTR(str,pos),SUBSTR(str FROM pos),SUBSTR(str,pos,len),SUBSTR(str FROM pos FOR len)SUBSTRING(str,pos),SUBSTRING(str FROM pos),SUBSTRING(str,pos,len),SUBSTRING(str FROM pos FOR len)SUBSTRING_INDEX(str,delim,count)— start from end ifcountis negative
- padding
LPAD(str,len,padstr)RPAD(str,len,padstr)
- trim
LTRIM(str)RTRIM(str)TRIM([{BOTH | LEADING | TRAILING} [remstr] FROM] str),TRIM([remstr FROM] str)
- mapping
ELT(N,str1,str2,str3,...)— selectstrNfrom string array starting fromstr1FIELD(str,str1,str2,str3,...)— ordinal in the string array starting fromstr1
- encoding
HEX(str)— hex representationUNHEX(str)TO_BASE64(str)FROM_BASE64(str)QUOTE(str)SOUNDEX(str)CHARSET(str)COLLATION(str)
- char at
# Aggregate and Window Functions
group functions
- ignore
NULLvalues - return type —
DOUBLEorDECIMALif exact-value arguments,BIGINT(or binary strings) for bitwise over_clause— use as window functions
- ignore
statistic group functions
SUM([DISTINCT] expr) [over_clause]AVG([DISTINCT] expr) [over_clause]MAX([DISTINCT] expr) [over_clause]MIN([DISTINCT] expr) [over_clause]STDDEV_POP(expr) [over_clause],STDDEV(expr) [over_clause],STD(expr) [over_clause]STDDEV_SAMP(expr) [over_clause]VAR_POP(expr) [over_clause],VARIANCE(expr) [over_clause]VAR_SAMP(expr) [over_clause]
bitwise group functions
BIT_AND(expr) [over_clause]BIT_OR(expr) [over_clause]BIT_XOR(expr) [over_clause]
other group functions
COUNT(expr) [over_clause]— non-NULLvalues, alsoNULLifCOUNT(*)- secondary index traversing — InnoDB processes
SELECT COUNT(*)statements by traversing the smallest available secondary index unless an index or optimizer hint directs the optimizer to use a different index. If a secondary index is not present, InnoDB processesSELECT COUNT(*)statements by scanning the clustered index.
- secondary index traversing — InnoDB processes
COUNT(DISTINCT expr,[expr...])GROUP_CONCAT(expr)GROUP_CONCAT([DISTINCT] expr [,expr ...] [ORDER BY {unsigned_integer | col_name | expr} [ASC | DESC] [,col_name ...]] [SEPARATOR str_val])
window functions — tbd
null_treatment— for ANSI SQL conformance, permits onlyRESPECT NULLSLEAD(expr [, N[, default]]) [null_treatment] over_clauseLAG(expr [, N[, default]]) [null_treatment] over_clauseNTILECUME_DISTDENSE_RANK() over_clause— consecutive even when duplicatesPERCENT_RANKRANK() over_clause— not consecutive when duplicateROW_NUMBER() over_clause
# Other Functions
full-text search functions — for
FULLTEXTindex types, tbdMATCH (col1,col2,...) AGAINST (expr [search_modifier]) search_modifier: { IN NATURAL LANGUAGE MODE | IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION | IN BOOLEAN MODE | WITH QUERY EXPANSION }encryption and compression
SHA1(),SHA2(),SHA()MD5()- more
lock functions
information functions
BENCHMARK(count,expr)— executes the expressionexprrepeatedlycounttimes, scalar expressions only- last query
FOUND_ROWS()— for lastLIMITROW_COUNT()LAST_INSERT_ID(),LAST_INSERT_ID(expr)
- client, current session
VERSION()USER(),SESSION_USER(),SYSTEM_USER()CONNECTION_ID()CURRENT_ROLE()CURRENT_USER,CURRENT_USER()DATABASE(),SCHEMA()
miscellaneous functions
- UUID — see docs for arguments
BIN_TO_UUID()IS_UUID()UUID()UUID_SHORT()UUID_TO_BIN()
- column related during statements
DEFAULT(col_name)—DEFAULTvalue forcol_nameGROUPING(expr [, expr] ...)— seeGROUP BYANY_VALUE(arg)— seeGROUP BY
- UUID — see docs for arguments
# Expressions
expression
expr: expr OR expr | expr || expr | expr XOR expr | expr AND expr | expr && expr | NOT expr | ! expr | boolean_primary IS [NOT] {TRUE | FALSE | UNKNOWN} | boolean_primaryboolean_primaryboolean_primary: boolean_primary IS [NOT] NULL | boolean_primary <=> predicate | boolean_primary comparison_operator predicate | boolean_primary comparison_operator {ALL | ANY} (subquery) | predicatecomparison_operatorcomparison_operator: = | >= | > | <= | < | <> | !=
predicatepredicate: bit_expr [NOT] IN (subquery) | bit_expr [NOT] IN (expr [, expr] ...) | bit_expr [NOT] BETWEEN bit_expr AND predicate | bit_expr SOUNDS LIKE bit_expr | bit_expr [NOT] LIKE simple_expr [ESCAPE simple_expr] | bit_expr [NOT] REGEXP bit_expr | bit_exprbit_exprbit_expr: bit_expr | bit_expr | bit_expr & bit_expr | bit_expr << bit_expr | bit_expr >> bit_expr | bit_expr + bit_expr | bit_expr - bit_expr | bit_expr * bit_expr | bit_expr / bit_expr | bit_expr DIV bit_expr | bit_expr MOD bit_expr | bit_expr % bit_expr | bit_expr ^ bit_expr | bit_expr + interval_expr | bit_expr - interval_expr | simple_exprsimple_exprsimple_expr: literal | identifier | function_call | simple_expr COLLATE collation_name | param_marker | variable | simple_expr || simple_expr | + simple_expr | - simple_expr | ~ simple_expr | ! simple_expr | BINARY simple_expr | (expr [, expr] ...) | ROW (expr, expr [, expr] ...) | (subquery) | EXISTS (subquery) | match_expr | case_expr | interval_exprvariable— user variables, system variables, or stored program local variables or parametersparam_marker—?inPREPARE
interval_expr— represents a temporal interval, for+,-and functions likeDATE_ADD()andDATE_SUB()INTERVAL expr unitexprhere — quantity inunit, should be in the format according tounitunitMICROSECOND,SECOND,MINUTE,HOUR,DAY,WEEK,MONTH,QUARTER,YEAR— expect numberSECOND_MICROSECOND,MINUTE_MICROSECOND,MINUTE_SECOND,HOUR_MICROSECOND,HOUR_SECOND,HOUR_MINUTE— from left part to right part, expect any punctuation delimited stringDAY_MICROSECOND,DAY_SECOND,DAY_MINUTE,DAY_HOUR— like above but with days spaced:'DAYS HOURS:MINUTES:SECONDS.MICROSECONDS'YEAR_MONTH—'YEARS-MONTHS'
# Distributed MySQL
# Partition
partition in MySQL
- partitioning types — horizontal, error when cannot decide partition
RANGEpartitioning — partitions based on column values falling within a given rangeRANGE COLUMNSpartitioning — enables the use of multiple columns in partitioning keys
LISTpartitioning — partitions based on column values matching one of a set of discrete valuesLIST COLUMNSpartitioning — enables the use of multiple columns in partitioning keys
HASHpartitioning — partitions based on user provided hash function on column valuesLINEAR HASH— data is less likely to be evenly distributed, but adding, dropping, merging, and splitting of partitions is made much fasterKEYpartitioning — similar toHASH, except that MySQL supplies the hashing function
- composite partitioning — with
SUBPARTITION - limitation — all columns used in the table's partitioning expression must be part of every unique key that the table may have, including any primary key, see docs for more
- corresponding table in
INFORMATION_SCHEMA—INFORMATION_SCHEMA.PARTITIONS
- partitioning types — horizontal, error when cannot decide partition
partition_optionsinCREATE TABLEPARTITION BY { [LINEAR] HASH(expr) | [LINEAR] KEY [ALGORITHM={1|2}] (column_list) | RANGE{(expr) | COLUMNS(column_list)} | LIST{(expr) | COLUMNS(column_list)} } [PARTITIONS num] [SUBPARTITION BY { [LINEAR] HASH(expr) | [LINEAR] KEY [ALGORITHM={1|2}] (column_list) } [SUBPARTITIONS num] ] [(partition_definition [, partition_definition] ...)]partition_definitionPARTITION partition_name [VALUES {LESS THAN {(expr | value_list) | MAXVALUE} | IN (value_list)}] [[STORAGE] ENGINE [=] engine_name] [COMMENT [=] 'string' ] [DATA DIRECTORY [=] 'data_dir'] [INDEX DIRECTORY [=] 'index_dir'] [MAX_ROWS [=] max_number_of_rows] [MIN_ROWS [=] min_number_of_rows] [TABLESPACE [=] tablespace_name] [(subpartition_definition [, subpartition_definition] ...)]subpartition_definitionSUBPARTITION logical_name [[STORAGE] ENGINE [=] engine_name] [COMMENT [=] 'string' ] [DATA DIRECTORY [=] 'data_dir'] [INDEX DIRECTORY [=] 'index_dir'] [MAX_ROWS [=] max_number_of_rows] [MIN_ROWS [=] min_number_of_rows] [TABLESPACE [=] tablespace_name]
partition_optionsinALTER TABLEpartition_options: partition_option [partition_option] ... partition_option: ADD PARTITION (partition_definition) | DROP PARTITION partition_names | DISCARD PARTITION {partition_names | ALL} TABLESPACE | IMPORT PARTITION {partition_names | ALL} TABLESPACE | TRUNCATE PARTITION {partition_names | ALL} | COALESCE PARTITION number | REORGANIZE PARTITION partition_names INTO (partition_definitions) | EXCHANGE PARTITION partition_name WITH TABLE tbl_name [{WITH|WITHOUT} VALIDATION] | ANALYZE PARTITION {partition_names | ALL} | CHECK PARTITION {partition_names | ALL} | OPTIMIZE PARTITION {partition_names | ALL} | REBUILD PARTITION {partition_names | ALL} | REPAIR PARTITION {partition_names | ALL} | REMOVE PARTITIONING- see
partition_optionsinCREATE TABLEfor other syntax
- see
PARTITIONclause in DML — see corresponding DML
# System Variables
SHOW VARIABLESSHOW [GLOBAL | SESSION] VARIABLES [LIKE 'pattern' | WHERE expr]- corresponding table in
PERFORMANCE_SCHEMA—PERFORMANCE_SCHEMA.global_variables,PERFORMANCE_SCHEMA.session_variables,PERFORMANCE_SCHEMA.persisted_variables,PERFORMANCE_SCHEMA.variables_by_thread,PERFORMANCE_SCHEMA.variables_info - CLI —
mysqladmin variables
- corresponding table in
SETSET sql_mode='TIME_TRUNCATE_FRACTIONAL'; SET @@sql_mode='TIME_TRUNCATE_FRACTIONAL';@@— indicate explicitly that a variable is a session variable@@global.,@@session.prefixes
sql_mode, separated by,SET @@sql_mode = sys.list_add(@@sql_mode, 'TIME_TRUNCATE_FRACTIONAL');- strict mode —
STRICT_ALL_TABLESorSTRICT_TRANS_TABLES- effects — warnings become errors, see docs 5.1.11 Server SQL Modes (opens new window)
- temporarily non-strict —
INSERT IGNOREorUPDATE IGNORE
NO_UNSIGNED_SUBTRACTIONPAD_CHAR_TO_FULL_LENGTHNO_ZERO_IN_DATEANSI_QUOTES— Treat"as an identifier quote character (like the`quote character) and not as a string quote characterNO_BACKSLASH_ESCAPES— Disable the use of the backslash character (\) as an escape character within strings and identifiersPIPES_AS_CONCAT
- strict mode —
system variables — tbd
time_zonemax_sort_lengthsql_auto_is_null- character set
character_set_connection