# 基礎語法 https://blog.csdn.net/m0_37989980/article/details/103413942 CRUD 提供給資料庫管理員的基本操作,CRUD(Create, Read, Update and Delete)。 1. 語法: select [distinct ...
基礎語法
https://blog.csdn.net/m0_37989980/article/details/103413942
CRUD
提供給資料庫管理員的基本操作,CRUD(Create, Read, Update and Delete)。
1. 語法:
select [distinct]
欄位列表
from
表名列表
where
條件列表
group by
分組欄位
having
分組之後的條件
order by
排序
limit
分頁限定
offset
位數
DDL:操作資料庫、表
DDL Data Definition Language
1. 操作資料庫:CRUD
1. C(Create):創建
* 創建資料庫:
* create database 資料庫名稱;
* 創建資料庫,判斷不存在,再創建:
* create database if not exists 資料庫名稱;
* 創建資料庫,並指定字元集
* create database 資料庫名稱 character set 字元集名;
* 練習: 創建db4資料庫,判斷是否存在,並制定字元集為gbk
* create database if not exists db4 character set gbk;
2. R(Retrieve):查詢
* 查詢所有資料庫的名稱:
* show databases;
* 查詢某個資料庫的字元集:查詢某個資料庫的創建語句
* show create database 資料庫名稱;
3. U(Update):修改
* 修改資料庫的字元集
* alter database 資料庫名稱 character set 字元集名稱;
4. D(Delete):刪除
* 刪除資料庫
* drop database 資料庫名稱;
* 判斷資料庫存在,存在再刪除
* drop database if exists 資料庫名稱;
5. 使用資料庫
* 查詢當前正在使用的資料庫名稱
* select database();
* 使用資料庫
* use 資料庫名稱;
2. 操作表
1. C(Create):創建
1. 語法:
create table 表名(
列名1 數據類型1,
列名2 數據類型2,
....
列名n 數據類型n
);
* 註意:最後一列,不需要加逗號(,)
* 資料庫類型:
1. int:整數類型
* age int,
2. double:小數類型
* score double(5,2)
3. date:日期,只包含年月日,yyyy-MM-dd
4. datetime:日期,包含年月日時分秒 yyyy-MM-dd HH:mm:ss
5. timestamp:時間錯類型 包含年月日時分秒 yyyy-MM-dd HH:mm:ss
* 如果將來不給這個欄位賦值,或賦值為null,則預設使用當前的系統時間,來自動賦值
6. varchar:字元串
* name varchar(20):姓名最大20個字元
* zhangsan 8個字元 張三 2個字元
* 創建表
create table student(
id int,
name varchar(32),
age int ,
score double(4,1),
birthday date,
insert_time timestamp
);
* 複製表:
* create table 表名 like 被覆制的表名;
2. R(Retrieve):查詢
* 查詢某個資料庫中所有的表名稱
* show tables;
* 查詢表結構
* desc 表名;
3. U(Update):修改
1. 修改表名
alter table 表名 rename to 新的表名;
2. 修改表的字元集
alter table 表名 character set 字元集名稱;
3. 添加一列
alter table 表名 add 列名 數據類型;
4. 修改列名稱 類型
alter table 表名 change 列名 新列別 新數據類型;
alter table 表名 modify 列名 新數據類型;
5. 刪除列
alter table 表名 drop 列名;
4. D(Delete):刪除
* drop table 表名;
* drop table if exists 表名 ;
DML:增刪改表中數據
DML Data Manipulation Language Manipulation:操縱;推拿;(熟練的)控制,使用;(對賬目等的)偽造,篡改;(對儲存在電腦上的信息的)操作,處理
1. 添加數據:
* 語法:
* insert into 表名(列名1,列名2,...列名n) values(值1,值2,...值n);
* 註意:
1. 列名和值要一一對應。
2. 如果表名後,不定義列名,則預設給所有列添加值
insert into 表名 values(值1,值2,...值n);
3. 除了數字類型,其他類型需要使用引號(單雙都可以)引起來
2. 刪除數據:
* 語法:
* delete from 表名 [where 條件]
* 註意:
1. 如果不加條件,則刪除表中所有記錄。
2. 如果要刪除所有記錄
1. delete from 表名; -- 不推薦使用。有多少條記錄就會執行多少次刪除操作
2. TRUNCATE TABLE 表名; -- 推薦使用,效率更高 先刪除表,然後再創建一張一樣的表。
3. 修改數據:
* 語法:
* update 表名 set 列名1 = 值1, 列名2 = 值2,... [where 條件];
* 註意:
1. 如果不加任何條件,則會將表中所有記錄全部修改。
DQL:查詢表中的記錄
* select * from 表名;
1. 語法:
select
欄位列表
from
表名列表
where
條件列表
group by
分組欄位
having
分組之後的條件
order by
排序
limit
分頁限定
2. 基礎查詢
1. 多個欄位的查詢
select 欄位名1,欄位名2... from 表名;
* 註意:
* 如果查詢所有欄位,則可以使用*來替代欄位列表。
2. 去除重覆:
* distinct
3. 計算列
* 一般可以使用四則運算計算一些列的值。(一般只會進行數值型的計算)
* ifnull(表達式1,表達式2):null參與的運算,計算結果都為null
* 表達式1:哪個欄位需要判斷是否為null
* 如果該欄位為null後的替換值。
4. 起別名:
* as:as也可以省略
3. 條件查詢
1. where子句後跟條件
2. 運算符
* > 、< 、<= 、>= 、= 、<>
* BETWEEN...AND
* IN( 集合)
* LIKE:模糊查詢
* 占位符:
* _:單個任意字元
* %:多個任意字元
* IS NULL
* and 或 &&
* or 或 ||
* not 或 !
1. 排序查詢
* 語法:order by 子句
* order by 排序欄位1 排序方式1 , 排序欄位2 排序方式2...
* 排序方式:
* ASC:升序,預設的。
* DESC:降序。
* 註意:
* 如果有多個排序條件,則當前邊的條件值一樣時,才會判斷第二條件。
2. 聚合函數:將一列數據作為一個整體,進行縱向的計算。
1. count:計算個數
1. 一般選擇非空的列:主鍵
2. count(*)
2. max:計算最大值
3. min:計算最小值
4. sum:計算和
5. avg:計算平均值
* 註意:聚合函數的計算,排除null值。
解決方案:
1. 選擇不包含非空的列進行計算
2. IFNULL函數
3. 分組查詢:
1. 語法:group by 分組欄位;
2. 註意:
1. 分組之後查詢的欄位:分組欄位、聚合函數
2. where 和 having 的區別?
1. where 在分組之前進行限定,如果不滿足條件,則不參與分組。having在分組之後進行限定,如果不滿足結果,則不會被查詢出來
2. where 後不可以跟聚合函數,having可以進行聚合函數的判斷。
創建資料庫
CREATE DATABASE `review`;
USE review;
CREATE TABLE `one`(
`id` INT,
`name` VARCHAR(40),
`pwd` VARCHAR(40)
)ENGINE=INNODB DEFAULT CHARSET=utf8;
ALTER TABLE `one` MODIFY id INT PRIMARY KEY;
增加
insert
INSERT INTO `one` VALUES(1,"第一個","123"),(2,"第二個","123");
replace
REPLACE INTO `one` VALUES(1,"第一個","123");
區別: 當插入時,如果有重覆的數據,則先將重覆的數據刪除,然後再插入,所以相同時,他不會增加行數
刪除
語法
DELETE FROM <表名> [WHERE 子句] [ORDER BY 子句] [LIMIT 子句]
語法說明如下:
- `<表名>`:指定要刪除數據的表名。
- `ORDER BY` 子句:可選項。表示刪除時,表中各行將按照子句中指定的順序進行刪除。
- `WHERE` 子句:可選項。表示為刪除操作限定刪除條件,若省略該子句,則代表刪除該表中的所有行。
- `LIMIT` 子句:可選項。用於告知伺服器在控制命令被返回到客戶端前被刪除行的最大值。
# 註意:在不使用 WHERE 條件的時候,將刪除所有數據。
alter 刪除欄位
方法1
ALTER TABLE `one` ADD `mm` INT ;
ALTER TABLE `one` DROP `mm`
方法2
DELETE FROM `one` WHERE id=1;
delete刪除表
下麵是刪除這個表
DELETE FROM `mm`;
裡面也是可以使用not in 的
例如
DELETE FROM `mm` where id not in (1,3,4); -- 除了1,3,4其他全部刪除
更改
U(Update):修改
1. 修改表名
alter table 表名 rename to 新的表名;
2. 修改表的字元集
alter table 表名 character set 字元集名稱;
3. 添加一列
alter table 表名 add 列名 數據類型;
4. 修改列名稱 類型
alter table 表名 change 列名 新列別 新數據類型;
alter table 表名 modify 列名 新數據類型;
5. 刪除列
alter table 表名 drop 列名;
-- 修改表名
ALTER TABLE review rename to review_blog;
-- 修改字元集
ALTER TABLE review_blog character set utf8;
-- 添加欄位
ALTER TABLE review_blog add sex VARCHAR(30);
-- 修改欄位
ALTER TABLE review_blog change sex sexId VARCHAR(40);
-- 刪除欄位
ALTER TABLE review_blog DROP sexId
更改欄位
更改欄位名
ALTER TABLE `one` CHANGE `mm` `sex` INT;
增加欄位
alter table 表名 add 欄位
刪除欄位
alter table 表名 drop 欄位
關鍵字
distinct去重
SELECT DISTINCT `name`,`sex` FROM `one`;
in
# in是在where查詢中,能夠賦值多個參數
select * from 表 where id in(參數1,參數2)
order by排序
SELECT column_name,column_name
FROM table_name
ORDER BY column_name,column_name ASC|DESC;
#以一個欄位進行排序,desc是降序
IFNULL
mysql limit和offset用法
limit和offset用法
mysql里分頁一般用limit來實現
1. select* from article LIMIT 1,3
2.select * from article LIMIT 3 OFFSET 1
上面兩種寫法都表示取2,3,4三條條數據
當limit後面跟兩個參數的時候,第一個數表示要跳過的數量,後一位表示要取的數量,例如
select* from article LIMIT 1,3 就是跳過1條數據,從第2條數據開始取,取3條數據,也就是取2,3,4三條數據
當 limit後面跟一個參數的時候,該參數表示要取的數據的數量
例如 select* from article LIMIT 3 表示直接取前三條數據,類似sqlserver里的top語法。
當 limit和offset組合使用的時候,limit後面只能有一個參數,表示要取的的數量,offset表示要跳過的數量 。
例如select * from article LIMIT 3 OFFSET 1 表示跳過1條數據,從第2條數據開始取,取3條數據,也就是取2,3,4三條數據
MySQL IFNULL函數是MySQL控制流函數之一,它接受兩個參數,如果不是NULL,則返回第一個參數。 否則,IFNULL函數返回第二個參數。兩個參數可以是文字值或表達式。以下說明瞭IFNULL函數的語法:IFNULL(expression_1,expression_2);
如果expression_1不為NULL,則IFNULL函數返回expression_1; 否則返回expression_2的結果。IFNULL函數根據使用的上下文返回字元串或數字。如果要返回基於TRUE或FALSE條件的值,而不是NULL,則應使用IF函數。
select ifnull((select distinct salary from Employee order by salary desc limit 1 offset 1),null) as SecondHighestSalary;
IF
IF(expr1,expr2,expr3)
如果 expr1 是TRUE (expr1 <> 0 and expr1 <> NULL),則 IF()的返回值為expr2; 否則返回值則為 expr3。IF() 的返回值為數字值或字元串值,具體情況視其所在語境而定。
使用:如果id=1,則第一個值,否則第二個值
SELECT if(id=1,'123','000') FROM student;
通配符
% 替代 0 個或多個字元
_ 替代一個字元
[charlist] 字元列中的任何單一字元
[^charlist]
或
[!charlist] 不在字元列中的任何單一字元
應該只需要講講最後2個就行了
#先看一條SQL語句
SELECT * FROM `one` WHERE `name` REGEXP '[abc]'
#查詢名字以a或者b或者c開頭的
//REGEXP是正則表達式
mysql中常用字元
MySQL REGEXP:正則表達式查詢 (biancheng.net)
on和where的區別
- on是使用,他在連接查詢裡面使用,例如left join ......on
(63條消息) SQL中JOIN操作後接ON和WHERE關鍵字的區別_liitdar的博客-CSDN博客
# ON 條件是在生成臨時表時使用的條件,它不管 ON 中的條件是否為真,都會返回左邊表中的記錄;
WHERE 條件是在臨時表已經生成後,對臨時表進行的過濾條件。因為此時已經沒有 LEFT JOIN 的含義(必須返回左側表的記錄)了,所以如果 WHERE 條件不為真的記錄就會被過濾掉。
連接查詢
SQL INNER JOIN 關鍵字 | 菜鳥教程 (runoob.com)
註意:
FULL OUTER JOIN 在MySQL中不支持
count(數量)
MySQL學習筆記:count(1)、count(*)、count(欄位)的區別 - Hider1214 - 博客園 (cnblogs.com)
#count的意思是 查詢返回數據的數量
方法如下
count(*)
count(1)
count(欄位)
# COUNT(*) 的統計結果中,會包含值為NULL的行數。
# count(欄位)會判斷他是否為空,如果為空,則不加
# count(1)掃描主鍵
效率:count(欄位)慢於其他2個
1,比較count(*)和count(欄位名)的區別:前者對行的數目進行計算,包含null,後者對特定的列的值具有的行數進行計算,不包含null,得到的結果將是除去值為null和重覆數據後的結果。
2.count(1)跟count(主鍵)一樣,只掃描主鍵
3.count(*)和count(主鍵)使用方式一樣,但是在性能上有略微的區別,mysql對前者做了優化。
count(主鍵)不一定比count(其餘索引快)。
count(欄位),該欄位非主鍵的情況最好不要出現,因為該方式不走索引。
group by 分組
# group by 對數據進行分組,分組的欄位必須在查詢的欄位中能夠找到, 分組的id在前面查詢必須要有
例如 select id,name from 表 group by id;
# 作用:
只要是對裡面的一個欄位進行細分時進行應用
可以看看Case使用的最後一個SQL,case就在這章
# 小提示:
分組可以清除重覆的
having
# where不能在聚合函數中使用,所以使用Having
聚合函數
包括:AVG(),COUNT(),MIN(),MAX()和SUM()。
limit
4. 分頁查詢
1. 語法:limit 開始的索引,每頁查詢的條數;
2. 公式:開始的索引 = (當前的頁碼 - 1) * 每頁顯示的條數
3. limit 是一個MySQL"方言"
select * from article LIMIT 3 OFFSET 1
check
# 當你創建表時,需要對數據添加一些約束時,可以使用check(欄位加約束),多個裡面可以添加in
mysql> CREATE TABLE tb_emp7
-> (
-> id INT(11) PRIMARY KEY,
-> name VARCHAR(25),
-> deptId INT(11),
-> salary FLOAT,
-> CHECK(salary>0 AND salary<100),
-> FOREIGN KEY(deptId) REFERENCES tb_dept1(id)
-> );
Query OK, 0 rows affected (0.37 sec)
case表達式
CASE <表達式>
WHEN <值1> THEN <操作>
WHEN <值2> THEN <操作>
...
ELSE <操作>
END
- 各個分支
<表達式>
返回的數據類型要統一; - CASE寫完後不能丟了END
- ELSE可省略但不建議省,沒有值時可寫 ELSE NULL。
--簡單格式 CASE表達式
CASE input_expression
WHEN when_expression THEN result_expression [ ...n ]
[ ELSE else_result_expression ]
END
--搜索模式
CASE
WHEN Boolean_expression THEN result_expression [ ...n ]
[ ELSE else_result_expression ]
END
input_expression(簡單格式):
指定一個有效的表達式(可以是常量、變數、列屬性),只要表達式返回的是單個數據值。
when_expression(簡單格式):
在簡單格式中,此處填寫的內容是用於和input_expression表達式進行等值比較的。when_expression的內容可以是任何有效的表達式,可以指定多個。
input_expression和when_expression的註意事項(簡單格式):
在簡單模式中,input_expression和when_expression表達式計算的結果值,要求數據類型必須相同,如果不滿足則兩個結果值必須滿足隱式轉換的條件。如果兩個條件都不滿足,則會提示“數據類型轉換失敗”。
- 區別
-
方式1
結合分組統計數據,把一個欄位的裡面的數據進行分組和歸類
-
方式2
分條件更新欄位值
(一)需求: 將工資低於3000的員工漲幅工資20%,工資等於高於3000的員工漲幅8%,數據如下:
可能有人看到這個需求的第一反應,想直接可以直接通過如下兩條update語句直接更新:
update t_salary set salary = salary + (salary * 0.2) where salary < 3000;
update t_salary set salary = salary + (salary * 0.08) where salary >= 3000;
但是,如果是這樣執行的話實際上會存在問題,比如:原來工資在2900的員工,執行完第一條語句後工資會變成3480,此時,再執行第二條更新語句,因為滿足工資大於三千,則又會去添加多8%的工資,這樣明顯就是不符合我們的需求的,所以,如果想完成這個需求,又不想寫太複雜的sql,可以通過case函數完成這個功能。
-
方式
(一)需求: 將表中數據按照每個學生姓名 、科目、成績進行排序,數據如下:
dense_rank()
可以參考這片
https://www.cnblogs.com/rain-me/p/16195023.html
常用函數
year函數
SELECT YEAR(NOW())
項目使用
select year(FROM_UNIXTIME(create_date/1000)) year,month(FROM_UNIXTIME(create_date/1000)) month, count(*) count
from ms_article
group by year,month;
# FROM_UNIXTIME函數是格式化:
# FROM_UNIXTIME(unix_timestamp,format)他裡面是一個時間戳,上面是一個毫秒,所有需要/1000
時間戳
1. 秒級別時間戳
自19700101 00:00:00以來按秒算,SQL如下:
* mysql> select unix_timestamp(now());
+-----------------------+
| unix_timestamp(now()) |
+-----------------------+
| 1541604376 |
+-----------------------+
1 row in set (0.00 sec)
2. 當前時間戳
* mysql> select current_timestamp();
+---------------------+
| current_timestamp() |
+---------------------+
| 2019-01-04 20:37:19 |
+---------------------+
1 row in set (0.00 sec)
約束
唯一約束
ALTER TABLE <數據表名> ADD CONSTRAINT <唯一約束名> UNIQUE(<列名>);
欄位的值不能重覆
創建唯一約束
例如,下麵的SQL創建一個新的表名為CUSTOMERS,並添加了五列。在這裡,AGE列設置為唯一的,所以不能有兩個記錄使用相同的年齡:
CREATE TABLE CUSTOMERS(
ID INT NOT NULL,
NAME VARCHAR (20) NOT NULL,
AGE INT NOT NULL UNIQUE,
ADDRESS CHAR (25) ,
SALARY DECIMAL (18, 2),
PRIMARY KEY (ID));
如果CUSTOMERS表已經創建,然後要將唯一約束添加到AGE列,類似如下的聲明:
ALTER TABLE CUSTOMERS
MODIFY AGE INT NOT NULL UNIQUE;
還可以使用下麵的語法,它支持命名的多個列的約束:
ALTER TABLE CUSTOMERS
ADD CONSTRAINT myUniqueConstraint UNIQUE(AGE, SALARY);
刪除唯一約束
如果正在使用MySQL,那麼可以使用下麵的語法:
ALTER TABLE CUSTOMERS
DROP INDEX myUniqueConstraint;
外鍵約束
# 外鍵約束:foreign key,讓表於表產生關係,從而保證數據的正確性。
1. 在創建表時,可以添加外鍵
* 語法:
create table 表名(
....
外鍵列
constraint 外鍵名稱 foreign key (外鍵列名稱) references 主表名稱(主表列名稱)
);
2. 刪除外鍵
ALTER TABLE 表名 DROP FOREIGN KEY 外鍵名稱;
3. 創建表之後,添加外鍵
ALTER TABLE 表名 ADD CONSTRAINT 外鍵名稱 FOREIGN KEY (外鍵欄位名稱) REFERENCES 主表名稱(主表列名稱);
4. 如果創建外鍵時忘記添加外鍵名,mysql 會給你一個預設的外鍵名,使用下麵的SQL語句將他查詢出來
SHOW CREATE TABLE em;