文章沿着設計一個假想的應用 awesome_app
爲主線,從零建立修改數據庫,表格,字段屬性,索引,字符集,默認值,自增,增刪改查,多表查詢,內置函數等實用 SQL 語句。收藏此文,告別零散又低效地搜索常常使用的 SQL 語句。全部 SQL 都在 MySQL 下經過驗證,可留着往後回顧參考,也可跟着動手一塊兒作,若是未安裝 MySQL 可參考 《macOS 安裝 mysql》 (windows 安裝大同小異)。mysql
語法:create database db_namesql
示例:建立應用數據庫 awesome_app
數據庫
create database `awesome_app`
複製代碼
語法:create table table_name ( ... columns )windows
示例:建立用戶表 users
app
create table `users`
(
`id` int,
`name` char(10),
`avatar` varchar(300),
`regtime` date
)
複製代碼
語法:create index index_name on table_name (column_name)函數
示例:爲用戶 id
建立索引 idx_id
post
create index `idx_id` on `users` (`id`)
/* 建立惟一索引 */
create unique index `idx_id` on `users` (`id`)
複製代碼
更經常使用的方式是在建立表語句全部列定義的後面添加一行
primary key (column_name)
。ui
語法:alter table table_name add primary key (column_name)spa
示例:將用戶 id
設爲主鍵設計
alter table users add primary key (`id`)
複製代碼
更經常使用的方式是在建立表語句中添加自增列
id int not null auto_increment
。
alter table `users` modify `id` int not null auto_increment
複製代碼
語法:
示例:新增註冊用戶
insert into `users` values (1, 'ken', 'http://cdn.awesome_app.com/path/to/xxx/avatar1.jpg', curdate())
/* 指定列插入 */
insert into `users` (`name`, `avatar`) values ('bill', 'http://cdn.awesome_app.com/path/to/xxx/avatar2.jpg')
複製代碼
語法:
示例:
update `users` set `regtime`=curdate() where `regtime` is null
/* 一次修改多列 */
update `users` set `name`='steven',`avatar`='http://cdn.awesome_app.com/path/to/xxx/steven.jpg' where `id`=1
複製代碼
utf8
alter database `awesome_app` default character set utf8
複製代碼
utf8
alter table `users` convert to character set utf8
複製代碼
utf8
alter table `users` modify `name` char(10) character set utf8
複製代碼
alter table `users` modify `regtime` datetime not null
複製代碼
alter table `users` alter `regtime` set default '2019-10-12 00:00:00'
/* 設置默認爲當前時間 current_timestamp,須要從新定義整個列 */
alter table `users` modify `regtime` datetime not null default current_timestamp
複製代碼
alter table `users` modify `id` int not null auto_increment comment '用戶ID';
alter table `users` modify `name` char(10) comment '用戶名';
alter table `users` modify `avatar` varchar(300) comment '用戶頭像';
alter table `users` modify `regtime` datetime not null default current_timestamp comment '註冊時間';
複製代碼
修改後,查看改動後的列:
mysql> show full columns from users;
+---------+--------------+-----------------+------+-----+-------------------+----------------+---------------------------------+--------------+
| Field | Type | Collation | Null | Key | Default | Extra | Privileges | Comment |
+---------+--------------+-----------------+------+-----+-------------------+----------------+---------------------------------+--------------+
| id | int(11) | NULL | NO | PRI | NULL | auto_increment | select,insert,update,references | 用戶ID |
| name | char(10) | utf8_general_ci | YES | | NULL | | select,insert,update,references | 用戶名 |
| avatar | varchar(300) | utf8_general_ci | YES | | NULL | | select,insert,update,references | 用戶頭像 |
| regtime | datetime | NULL | NO | | CURRENT_TIMESTAMP | | select,insert,update,references | 註冊時間 |
+---------+--------------+-----------------+------+-----+-------------------+----------------+---------------------------------+--------------+
複製代碼
語法:delete from table_name where condition
示例:刪除用戶名未填寫的用戶
# 先增長一條用戶名爲空的用戶
mysql> insert into `users` (`regtime`) values (curdate());
mysql> select * from users;
+----+--------+----------------------------------------------------+------------+
| id | name | avatar | regtime |
+----+--------+----------------------------------------------------+------------+
| 1 | steven | http://cdn.awesome_app.com/path/to/xxx/steven.jpg | 2019-10-12 |
| 2 | bill | http://cdn.awesome_app.com/path/to/xxx/avatar2.jpg | 2019-10-12 |
| 3 | NULL | NULL | 2019-10-12 |
+----+--------+----------------------------------------------------+------------+
# 刪除用戶名爲空的行
mysql> delete from `users` where `name` is null;
mysql> select * from users;
+----+--------+----------------------------------------------------+------------+
| id | name | avatar | regtime |
+----+--------+----------------------------------------------------+------------+
| 1 | steven | http://cdn.awesome_app.com/path/to/xxx/steven.jpg | 2019-10-12 |
| 2 | bill | http://cdn.awesome_app.com/path/to/xxx/avatar2.jpg | 2019-10-12 |
+----+--------+----------------------------------------------------+------------+
複製代碼
drop database if exists `awesome_app`
複製代碼
drop table if exists `users`
複製代碼
這個操做至關於先 drop table
再 create table
,所以須要有 drop
權限。
truncate table `users`
複製代碼
drop index `idx_id` on `users`
複製代碼
SELECT
[ALL | DISTINCT | DISTINCTROW ]
[HIGH_PRIORITY]
[STRAIGHT_JOIN]
[SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
[SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]
select_expr [, select_expr ...]
[FROM table_references
[PARTITION partition_list]
[WHERE where_condition]
[GROUP BY {col_name | expr | position}
[ASC | DESC], ... [WITH ROLLUP]]
[HAVING where_condition]
[ORDER BY {col_name | expr | position}
[ASC | DESC], ...]
[LIMIT {[offset,] row_count | row_count OFFSET offset}]
[PROCEDURE procedure_name(argument_list)]
[INTO OUTFILE 'file_name'
[CHARACTER SET charset_name]
export_options
| INTO DUMPFILE 'file_name'
| INTO var_name [, var_name]]
[FOR UPDATE | LOCK IN SHARE MODE]]
複製代碼
insert into users (`name`, `avatar`) values
('張三', 'http://cdn.awesome_app.com/path/to/xxx/3.jpg'),
('李四', 'http://cdn.awesome_app.com/path/to/xxx/4.jpg'),
('王五', 'http://cdn.awesome_app.com/path/to/xxx/5.jpg'),
('馬六', 'http://cdn.awesome_app.com/path/to/xxx/6.jpg'),
('肖七', 'http://cdn.awesome_app.com/path/to/xxx/7.jpg'),
('劉八', 'http://cdn.awesome_app.com/path/to/xxx/8.jpg'),
('楊九', 'http://cdn.awesome_app.com/path/to/xxx/9.jpg'),
('鄭十', 'http://cdn.awesome_app.com/path/to/xxx/10.jpg');
/* 增長重複行 */
insert into users (`name`, `avatar`) values
('張三', 'http://cdn.awesome_app.com/path/to/xxx/3.jpg'),
('李四', 'http://cdn.awesome_app.com/path/to/xxx/4.jpg'),
('王五', 'http://cdn.awesome_app.com/path/to/xxx/5.jpg');
複製代碼
mysql> select * from users;
+----+--------+----------------------------------------------------+---------------------+
| id | name | avatar | regtime |
+----+--------+----------------------------------------------------+---------------------+
| 1 | steven | http://cdn.awesome_app.com/path/to/xxx/steven.jpg | 2019-10-12 00:00:00 |
| 2 | bill | http://cdn.awesome_app.com/path/to/xxx/avatar2.jpg | 2019-10-12 00:00:00 |
| 3 | 張三 | http://cdn.awesome_app.com/path/to/xxx/3.jpg | 2019-10-13 10:58:37 |
| 4 | 李四 | http://cdn.awesome_app.com/path/to/xxx/4.jpg | 2019-10-13 10:58:37 |
| 5 | 王五 | http://cdn.awesome_app.com/path/to/xxx/5.jpg | 2019-10-13 10:58:37 |
| 6 | 馬六 | http://cdn.awesome_app.com/path/to/xxx/6.jpg | 2019-10-13 10:58:37 |
| 7 | 肖七 | http://cdn.awesome_app.com/path/to/xxx/7.jpg | 2019-10-13 10:58:37 |
| 8 | 劉八 | http://cdn.awesome_app.com/path/to/xxx/8.jpg | 2019-10-13 10:58:37 |
| 9 | 楊九 | http://cdn.awesome_app.com/path/to/xxx/9.jpg | 2019-10-13 10:58:37 |
| 10 | 鄭十 | http://cdn.awesome_app.com/path/to/xxx/10.jpg | 2019-10-13 10:58:37 |
| 11 | 張三 | http://cdn.awesome_app.com/path/to/xxx/3.jpg | 2019-10-13 11:20:17 |
| 12 | 李四 | http://cdn.awesome_app.com/path/to/xxx/4.jpg | 2019-10-13 11:20:17 |
| 13 | 王五 | http://cdn.awesome_app.com/path/to/xxx/5.jpg | 2019-10-13 11:20:17 |
+----+--------+----------------------------------------------------+---------------------+
複製代碼
mysql> select id,name from users;
+----+--------+
| id | name |
+----+--------+
| 1 | steven |
| 2 | bill |
| 3 | 張三 |
| 4 | 李四 |
| 5 | 王五 |
| 6 | 馬六 |
| 7 | 肖七 |
| 8 | 劉八 |
| 9 | 楊九 |
| 10 | 鄭十 |
| 11 | 張三 |
| 12 | 李四 |
| 13 | 王五 |
+----+--------+
複製代碼
mysql> select distinct name,avatar from users;
+--------+----------------------------------------------------+
| name | avatar |
+--------+----------------------------------------------------+
| steven | http://cdn.awesome_app.com/path/to/xxx/steven.jpg |
| bill | http://cdn.awesome_app.com/path/to/xxx/avatar2.jpg |
| 張三 | http://cdn.awesome_app.com/path/to/xxx/3.jpg |
| 李四 | http://cdn.awesome_app.com/path/to/xxx/4.jpg |
| 王五 | http://cdn.awesome_app.com/path/to/xxx/5.jpg |
| 馬六 | http://cdn.awesome_app.com/path/to/xxx/6.jpg |
| 肖七 | http://cdn.awesome_app.com/path/to/xxx/7.jpg |
| 劉八 | http://cdn.awesome_app.com/path/to/xxx/8.jpg |
| 楊九 | http://cdn.awesome_app.com/path/to/xxx/9.jpg |
| 鄭十 | http://cdn.awesome_app.com/path/to/xxx/10.jpg |
+--------+----------------------------------------------------+
複製代碼
查詢前幾行
mysql> select id,name from users limit 2;
+----+--------+
| id | name |
+----+--------+
| 1 | steven |
| 2 | bill |
+----+--------+
複製代碼
查詢從指定偏移(第一行爲偏移爲0)開始的幾行
mysql> select id,name from users limit 2,3;
+----+--------+
| id | name |
+----+--------+
| 3 | 張三 |
| 4 | 李四 |
| 5 | 王五 |
+----+--------+
複製代碼
# 正序
mysql> select distinct name from users order by name asc limit 3;
+--------+
| name |
+--------+
| bill |
| steven |
| 劉八 |
+--------+
# 倒序
mysql> select id,name from users order by id desc limit 3;
+----+--------+
| id | name |
+----+--------+
| 13 | 王五 |
| 12 | 李四 |
| 11 | 張三 |
+----+--------+
複製代碼
增長城市字段
alter table `users` add `city` varchar(10) comment '用戶所在城市' after `name`;
update `users` set `city`='舊金山' where `id`=1;
update `users` set `city`='西雅圖' where `id`=2;
update `users` set `city`='北京' where `id` in (3,5,7);
update `users` set `city`='上海' where `id` in (4,6,8);
update `users` set `city`='廣州' where `id` between 9 and 10;
update `users` set `city`='深圳' where `id` between 11 and 13;
複製代碼
按城市分組統計用戶數
mysql> select city, count(name) as num_of_user from users group by city;
+-----------+-------------+
| city | num_of_user |
+-----------+-------------+
| 上海 | 3 |
| 北京 | 3 |
| 廣州 | 2 |
| 舊金山 | 1 |
| 深圳 | 3 |
| 西雅圖 | 1 |
+-----------+-------------+
mysql> select city, count(name) as num_of_user from users group by city having num_of_user=1;
+-----------+-------------+
| city | num_of_user |
+-----------+-------------+
| 舊金山 | 1 |
| 西雅圖 | 1 |
+-----------+-------------+
mysql> select city, count(name) as num_of_user from users group by city having num_of_user>2;
+--------+-------------+
| city | num_of_user |
+--------+-------------+
| 上海 | 3 |
| 北京 | 3 |
| 深圳 | 3 |
+--------+-------------+
複製代碼
create table if not exists `orders`
(
`id` int not null primary key auto_increment comment '訂單ID',
`title` varchar(50) not null comment '訂單標題',
`user_id` int not null comment '用戶ID',
`cretime` timestamp not null default current_timestamp comment '建立時間'
);
create table if not exists `groups`
(
`id` int not null primary key auto_increment comment '用戶組ID',
`title` varchar(50) not null comment '用戶組標題',
`cretime` timestamp not null default current_timestamp comment '建立時間'
);
alter table `users` add `group_id` int comment '用戶分組' after `city`;
insert into `groups` (`title`) values ('大佬'), ('萌新'), ('菜雞');
insert into `orders` (`title`, `user_id`) values ('《大佬是怎樣煉成的?》', 3), ('《MySQL 從萌新到刪庫跑路》', 6), ('《菜雞踩坑記》', 9);
update `users` set `group_id`=1 where `id` between 1 and 2;
update `users` set `group_id`=2 where `id` in (4, 6, 8, 10, 12);
update `users` set `group_id`=3 where `id` in (3, 5, 13);
複製代碼
join
用於在多個表中查詢相互匹配的數據。
mysql> select `users`.`name` as `user_name`, `orders`.`title` as `order_title` from `users`, `orders` where `orders`.`user_id`=`users`.`id`;
+-----------+--------------------------------------+
| user_name | order_title |
+-----------+--------------------------------------+
| 張三 | 《大佬是怎樣煉成的?》 |
| 馬六 | 《MySQL 從萌新到刪庫跑路》 |
| 楊九 | 《菜雞踩坑記》 |
+-----------+--------------------------------------+
複製代碼
inner join
內部鏈接。效果與 join
同樣 , 但用法不一樣,join
使用 where
,inner join
使用 on
。
mysql> select `users`.`name` as `user_name`, `orders`.`title` as `order_title` from `users` inner join `orders` on `orders`.`user_id`=`users`.`id`;
+-----------+--------------------------------------+
| user_name | order_title |
+-----------+--------------------------------------+
| 張三 | 《大佬是怎樣煉成的?》 |
| 馬六 | 《MySQL 從萌新到刪庫跑路》 |
| 楊九 | 《菜雞踩坑記》 |
+-----------+--------------------------------------+
複製代碼
left join
左鏈接。返回左表全部行,即便右表中沒有匹配的行,不匹配的用 NULL
填充。
mysql> select `users`.`name` as `user_name`, `orders`.`title` as `order_title` from `users` left join `orders` on `orders`.`user_id`=`users`.`id`;
+-----------+--------------------------------------+
| user_name | order_title |
+-----------+--------------------------------------+
| 張三 | 《大佬是怎樣煉成的?》 |
| 馬六 | 《MySQL 從萌新到刪庫跑路》 |
| 楊九 | 《菜雞踩坑記》 |
| steven | NULL |
| bill | NULL |
| 李四 | NULL |
| 王五 | NULL |
| 肖七 | NULL |
| 劉八 | NULL |
| 鄭十 | NULL |
| 張三 | NULL |
| 李四 | NULL |
| 王五 | NULL |
+-----------+--------------------------------------+
複製代碼
right join
右鏈接。和 left join
正好相反,會返回右表全部行,即便左表中沒有匹配的行,不匹配的用 NULL
填充。
mysql> select `groups`.`title` as `group_title`, `users`.`name` as `user_name` from `groups` right join `users` on `users`.`group_id`=`groups`.`id`;
+-------------+-----------+
| group_title | user_name |
+-------------+-----------+
| 大佬 | steven |
| 大佬 | bill |
| 萌新 | 李四 |
| 萌新 | 馬六 |
| 萌新 | 劉八 |
| 萌新 | 鄭十 |
| 萌新 | 李四 |
| 菜雞 | 張三 |
| 菜雞 | 王五 |
| 菜雞 | 王五 |
| NULL | 肖七 |
| NULL | 楊九 |
| NULL | 張三 |
+-------------+-----------+
複製代碼
union
用於合併兩個或多個查詢結果,合併的查詢結果必須具備相同數量的列,而且列擁有形似的數據類型,同時列的順序相同。
mysql> (select `id`, `title` from `groups`) union (select `id`, `title` from `orders`);
+----+--------------------------------------+
| id | title |
+----+--------------------------------------+
| 1 | 大佬 |
| 2 | 萌新 |
| 3 | 菜雞 |
| 1 | 《大佬是怎樣煉成的?》 |
| 2 | 《MySQL 從萌新到刪庫跑路》 |
| 3 | 《菜雞踩坑記》 |
+----+--------------------------------------+
複製代碼
select function(column) from table_name
合計函數的操做面向一系列的值,並返回一個單一的值。一般與 group by
語句一塊兒用。
函數 | 描述 |
---|---|
avg(column) | 返回某列的平均值 |
count(column) | 返回某列的行數(不包括 NULL 值) |
count(*) | 返回被選行數 |
first(column) | 返回在指定的域中第一個記錄的值 |
last(column) | 返回在指定的域中最後一個記錄的值 |
max(column) | 返回某列的最高值 |
min(column) | 返回某列的最低值 |
sum(column) | 返回某列的總和 |
函數 | 描述 |
---|---|
ucase(c) | 轉換爲大寫 |
lcase(c) | 轉換爲小寫 |
mid(c, start[, end]) | 從文本提取字符 |
len(c) | 返回文本長度 |
instr(c, char) | 返回在文本中指定字符的數值位置 |
left(c, number_of_char) | 返回文本的左側部分 |
right(c, number_of_char) | 返回文本的右側部分 |
round(c, decimals) | 對數值指定小數位數四捨五入 |
mod(x, y) | 取餘(求模) |
now() | 返回當前的系統日期 |
format(c, format) | 格式化顯示 |
datediff(d, date1, date2) | 日期計算 |
若是未安裝 MySQL 可參考 《macOS 安裝 mysql》 (windows 安裝大同小異)。
本文首發公號