一、常用sql語句
注意,關鍵字和函數最好大寫,字段和表名小寫,這樣很容易區分。而且,表名用t_開頭,字段最好用f開頭。
1.創建數據庫t_user
CREATE DATABASE t_user;
2.刪除數據庫t_user
DROP DATABASE t_user;
3.使用數據庫t_user
USE t_user;
顯示數據庫中的表
SHOW TABLES;
4.創建數據表 t_order
表名的命名規范為表名必須用 t_ 的前綴。比如t_order
CREATE TABLE IF NOT EXISTS t_order(
id INT(11) NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT '主鍵,自增id',
order_id VARCHAR(25) NOT NULL UNIQUE COMMENT '訂單號,唯一',
pay_status TINYINT(2) UNSIGNED DEFAULT '0' COMMENT '0:未支付,1:支付成功,2:支付失敗,3:已下單,4:申請退款,5:退款成功,6:退款失敗 ',
user_id INT(11) NOT NULL COMMENT '用戶id' ,
total_price DECIMAL(25, 2) NOT NULL COMMENT '交易金額',
result text NULL COMMENT '訂單的回調結果',
create_date DATE COMMENT '購買日期',
create_time DATETIME COMMENT '購買時間',
INDEX(order_id,create_date)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
AUTO_INCREMENT 表示自增,UNSIGNED 表示無符號,UNIQUE 表示唯一約束,COMMENT為字段描述。DEFAULT表示默認值。NOT NULL表示不能為空。
5.修改字段:
ALTER TABLE t_input_invoice_order CHANGE agent_id agent_number VARCHAR(25)
添加字段:
ALTER TABLE t_input_invoice_agent
ADD merchant_id VARCHAR(25);
在指定位置(比如某一列的字段后面)添加字段,可以使用AFTER,如下:
ALTER TABLE t_input_invoice_deduction
ADD fdeduction_date DATE COMMENT '抵扣稅期'
AFTER fdeduction_month ;
刪除字段:
ALTER TABLE t_input_invoice_agent DROP COLUMN merchant_id
6.刪除數據表t_sys_role
DROP TABLE IF EXISTS t_sys_role;
6.插入數據
INSERT INTO t_sys_role VALUES(1,'0','管理員','admin');
7.查詢數據
SELECT * FROM t_sys_role;
8.修改數據
UPDATE t_sys_role SET role='user' WHERE id=1;
注意:使用UPDATE進行更新時,SET多個字段,使用逗號,隔開,而不是用AND。
正確的語句如下:
UPDATE t_sys_user SET fname='lin' , fscore='88' WHERE fid='3'
如果使用以下sql,可能會出現問題。
UPDATE t_sys_user SET fname='lin' AND fscore='88' WHERE fid='3'
9.刪除數據
DELETE FROM t_sys_role WHERE id=1;
注意:在使用DELETE和UPDATE之前,一定一定要先SELECT查詢一下,將要刪除的是哪些數據。
最好在查詢后,還"導出數據"進行備份,然后再進行數據變更。
二、建表關鍵字
0. constraints :SQL 約束
約束用於限制加入表的數據的類型。
可以在創建表時規定約束(通過 CREATE TABLE 語句),或者在表創建之后也可以(通過 ALTER TABLE 語句)。
比如,not null,unique,PRIMARY KEY,foreign key,default都屬於約束
可以用CONSTRAINT 命名約束。如下,命名外鍵約束為fk_PerOrders。
CREATE TABLE t_orders ( Id_O int NOT NULL, OrderNo int NOT NULL, Id_P int, PRIMARY KEY (Id_O), CONSTRAINT fk_PerOrders FOREIGN KEY (Id_P) REFERENCES Persons(Id_P) )
1.PRIMARY KEY 主鍵
主鍵表示該列值在表中是唯一的,不可以有重復。
主鍵必須包含唯一的值。主鍵列不能包含 NULL 值。
每個表都應該有一個主鍵,並且每個表只能有一個主鍵。
主鍵的命名規范為pk_開頭
2.AUTO_INCREMENT自增
auto_increment 就是對主鍵自動增加編號的。
3.UNSIGNED無符號
unsigned是無符號的意思,代表該字段沒有正負。
4.字段數據類型中,varchar和char的區別是什么?
varchar長度是可變的,能夠節省空間。比如說存儲"abc",CHAR(10)需要10個字符的空間來儲存,而VARCHAR(10)只需要3個字符的空間。
5.FOREIGN KEY 外鍵約束
一個表中的 FOREIGN KEY 指向另一個表中的 PRIMARY KEY。
如下示,Id_P是Orders表的外鍵,也是Persons表的主鍵。可以用CONSTRAINT 命名約束。命名外鍵約束為fk_PerOrders。
CREATE TABLE Orders ( Id_O int NOT NULL, OrderNo int NOT NULL, Id_P int, PRIMARY KEY (Id_O), CONSTRAINT fk_PerOrders FOREIGN KEY (Id_P) REFERENCES Persons(Id_P) )
6.UNIQUE 約束, 使數據庫表中的某一列或某幾列的里面的內容不重復
7. CREATE TABLE SELECT
根據查詢結果創建表格
CREATE TABLE user2 (SELECT a.* FROM user1 a WHERE a.ID='SYSTEM')
三、查詢關鍵字
0. IS NULL和IS NOT NULL。
不能使用 字段= NULL 或 字段!= NULL 在列中查找數據。可以使用以下格式:
WHERE 字段 IS NOT NULL
NULL值查詢使用IS NULL和IS NOT NULL查詢,而空值('')可以使用=或者!=、<、>、等算術運算符。
在實際開發中,建議使用空值。使用WHERE IS NULL不走索引。
Mysql里面NULL和空值的區別,詳情見: https://www.cnblogs.com/lonelyxmas/p/10371120.html
0. % 通配符,表示一個或多個字符
如下示,查詢170開頭的電話號碼。
SELECT order,age,sex FROM phone_info WHERE phoneNumber LIKE "170%"
最好不要用左模糊,會因為掃全表而變慢。
1. AS 別名,其中 AS 可以省略
普通的表可以取簡單的別名a,b,c。。而任意查詢出來的結果,也可以通過取別名作為一個表來使用。
比如,以下將(SELECT * FROM user WHERE id=1 )的查詢結果,通過取別名來使用
SELECT a.username FROM (SELECT * FROM user WHERE id=1 ) a;
字段,同樣也可以通過AS取別名。
2. JOIN 連接:用於根據兩個或多個表中的列之間的關系,從這些表中查詢數據。通過Inner JOIN ... On 實現。
JOIN其實就是把兩(多)張表合起來,從大表里面查詢的一個操作。
如下示,查找Persons中Id_P和Orders表中Id_P相同的數據。
SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo FROM Persons INNER JOIN Orders ON Persons.Id_P = Orders.Id_P ORDER BY Persons.LastName
各種JOIN的區別:
JOIN: 如果表中有至少一個匹配,則返回行
INNER JOIN 與 JOIN 是相同的。
LEFT JOIN: 即便關聯條件不符合,左邊表的數據一定會存在合並后的大表中。
RIGHT JOIN: 即便關聯條件不符合,右邊表的數據一定會存在合並后的大表中。
FULL JOIN: 只要其中一個表中存在匹配,就返回行。
3. UNION 組合查詢/聯合查詢
UNION 操作符用於合並兩個或多個 SELECT 語句的結果集。
請注意,UNION 聯合的 SELECT 語句必須擁有相同數量的列。列也必須擁有相似的數據類型。
同時,每條 SELECT 語句中的列的順序必須相同。
如下示:
SELECT Employee_Name FROM Employees_China
UNION SELECT Employee_Name FROM Employees_USA
另外,UNION和UNION ALL區別:
默認地,UNION 操作符選取不同的值。如果允許重復的值,請使用 UNION ALL。
4.SELECT INTO 查詢並插入
SELECT INTO 語句從一個表中選取數據,然后把數據插入另一個表中。
SELECT INTO 語句常用於創建表的備份復件或者用於對記錄進行存檔。
SELECT LastName,FirstName INTO Persons_backup FROM Persons
另外的,還有INSERT INTO SELECT 語句
從一個表復制數據,然后把數據插入到一個已存在的表中。目標表中任何已存在的行都不會受影響。
SQL INSERT INTO SELECT 。
我們可以從一個表中復制所有的列插入到另一個已存在的表中:
INSERT INTO TABLE2 SELECT * FROM TABLE1;
INSERT INTO table2 (column_name(s)) SELECT column_name(s) FROM table1;
5.DISTINCT 只返回不同的值。
以下返回不同的userId,不會重復:
SELECT DISTINCT userId FROM user
DISTINCT支持單列、多列的去重方式。
單列去重的方式簡明易懂,即相同值只保留1個。
多列的去重則是根據指定的去重的列信息來進行,即只有所有指定的列信息都相同,才會被認為是重復的信息。
多列去重如下 :
SELECT count( DISTINCT user_code, user_no ) FROM t_user
6.LIMIT 分頁查詢。
LIMIT X,Y 序號從0開始數,其中的X表示從第幾行開始,Y表示返回幾條記錄。
示例:每頁5行,返回第2頁的數據,即返回第6~10條記錄。
SELECT user_name FROM user LIMIT 5,5
示例:查找入職員工時間排名倒數第三的員工所有信息 。
思路:倒序,然后分頁查找,找到從第序號為2的開始的一條記錄,就是倒數第三。
SELECT * FROM employees ORDER BY hire_date DESC LIMIT 2,1
注意:Mysql並沒有TOP關鍵字。
7.子查詢
子查詢的結果,可以作為另一張表使用。
8.EXISTS 指定一個子查詢,檢測行是否存在。
用於檢查子查詢是否至少會返回一行數據,該子查詢實際上並不返回任何數據,而是返回值True或False
常用語法:not exists (子查詢)
或者 not exists (select 1 from 表名)
select 1 from 中的1是一常量(可以為任意數值),查到的所有行的值都是它,select 1效率比select * 高。
參考資料:https://blog.csdn.net/ahesihua/article/details/84275723
示例如下:
select c_insrnc_cde, c_nme_cn from t_prd_ins a where a.c_prod_no = '01' and not exists (select 1 from (select d.c_insrnc_cde, a.c_nme_cn from t_prd_ins a, tb_bas_ply_policy_rdr c, tb_bas_ply_policy_rdr_list d where a.c_insrnc_cde = d.c_insrnc_cde and d.c_policy_id = c.c_policy_id and d.c_seq_no = c.c_seq_no and c.c_reach_area = '00701' ) t where t.c_insrnc_cde = a.c_insrnc_cde);
9.查看表結構、查看字段的命令,如下:
desc 表名;
show columns from 表名;
describe 表名;
show create table 表名;
10.其他:IN()、OR()、LIKE
四、分組關鍵字
1.GROUP BY 分組
將查詢結果按某一列或多列的值分組
如下示:
SELECT Cno,count(sno) FROM course GROUP BY Cno;
一張表,一旦分組完成后,查詢后只能得到組相關的信息。可以通過count(),sum(),max(),min(),avg()統計。
--統計分組后各種情況的數量
SELECT COUNT(*),age,sex FROM staff WHERE 1=1 and create_date>='2018-05-07 00:00:00' GROUP BY age,sex ORDER BY age ASC
2.HAVING 分組篩選
對由SUM()或其它集合函數運算結果的輸出進行限制。可以對分組添加限制條件。如下示:
SELECT store_name, SUM(sales) FROM Store_Information GROUP BY store_name HAVING SUM(sales) > 1500
3.COUNT(column_name) 函數返回指定列的值的數目
COUNT(DISTINCT column_name) 函數返回指定列的不同值的數目:
4.CASE... WHEN
類似於java中的switch()語句。
有兩種表現形式:
CASE WHEN SEX = '1' THEN '男' WHEN SEX= '2' THEN '女' ELSE '未知' END
或者是:
CASE sex WHEN '1' THEN '男' WHEN '2' THEN '女' ELSE '未知' END;
可用於查詢中,也可以用於變更中。
示例如下,查詢示例如下:
SELECT id,name,create_time, (CASE WHEN status = 0 THEN '失敗' WHEN status = 1 THEN '成功' WHEN status = 2 THEN '等待中' ELSE '其它' END) AS result FROM t_order
變更示例如下,變更salary表中的性別:
UPDATE salary
SET
sex=CASE sex
WHEN 'm' THEN 'f'
ELSE 'm'
END;
示例2,將數字型的年月拼接起來,比如,將數字字段2019和2,拼接成一個日期2019-02,
CAST(fdeduction_month AS CHAR)表示將數字類型轉化為字符類型。
UPDATE t_input_invoice_deduction SET fdeduction_date=CONCAT(fdeduction_year, '-', CASE WHEN fdeduction_month<10
THEN CONCAT('0',CAST(fdeduction_month AS CHAR)) ELSE CAST(fdeduction_month AS CHAR) END )
Case...When還可以作為COUNT的條件。
比如,count( CASE WHEN err_str is not null THEN 1 ELSE NULL END )表示如果err_str不是空那么就計數1,用於計算err_str不為空的數量
類似於編程語言中的if else。是判斷語句
比如:
SELECT MOND_ID,INTERFACE_CODE,COUNT(*) as REQUEST_COUNT, count( CASE WHEN errstr is not null THEN 1 ELSE NULL END ) as FAILURE_COUNT FROM vbase.ESB_TRACE_20180428 WHERE 1=1 and create_date>='2018-04-28 09:00:00' and create_date<'2018-04-28 09:30:00' and INTERFACE_CODE='Svc_ProvisionRet' GROUP BY MOND_ID,INTERFACE_CODE ORDER BY MOND_ID ASC
四、字符串處理
1.CONCAT (Str1,Str2)
返回結果為連接參數產生的字符串。如有任何一個參數為NULL ,則返回值為 NULL。
示例如下:
SELECT name FROM user WHERE name LIKE CONCAT('%','ming','%')
2.GROUP_CONCAT(字段):將一個或多個字段的多行數據,把所有值合並成一行。默認按逗號,分隔
比如emp_no字段有三行數據,分別為10007、10008、10010,那么GROUP_CONCAT(emp_no)的值為合並后的 10007,10008,10010
示例:按照dept_no進行匯總,屬於同一個部門的emp_no按照逗號進行連接,結果給出dept_no以及連接出的結果employees
SELECT dept_no,GROUP_CONCAT(emp_no) as employees FROM dept_emp GROUP BY dept_no
如果想使用其他的分隔符 ,可以使用GROUP_CONCAT(字段 separator '分隔符') 。
示例如下:
select dept_no,group_concat(emp_no separator ';') from dept_emp group by dept_no;
3.REPLACE() 替換
4.SUBSTRING(str,from,to) 截取字符串
str為字符串,from表示起始下標,to表示末尾下標。from和to這兩個數字都包含邊界。比如以下sql,表示從第一個下標到第十的下標。
SUBSTRING('2019-08-07 17:34:57' ,1 , 10);
結果為2019-08-07
5.LEFT()、RIGHT().
6.CAST(字段名 AS CHAR)表示將字段轉化為字符類型。
7.TRIM(字符)會同時刪除字符串前后出現的空白字符
LTRIM(字串): 將所有字串開頭的空白字符移除。
RTRIM(字串): 將所有字串結尾的空白字符移除。
四、日期處理
NOW():表示當前日期及時間
CURDATE():表示當前日期
CURTIME() :表示當時的時間(不包含日期)
四、INDEX索引
索引對於操作者,僅僅提供創建、刪除和修改的功能。操作者在增刪改查過程中,系統會自動調用索引。
可以在表中創建索引,以便更加快速高效地查詢數據。
索引的命名規范為idx_開頭。比如idx_name
1.添加索引。
CREATE INDEX 索引名 ON 表名(字段名)
創建一個簡單的索引,名為 idx_name,在 t_person 表的 last_name 列,如下示:
CREATE INDEX idx_name ON t_person(last_name)
2.ADD INDEX 添加索引:
ALTER TABLE 表名 ADD INDEX 索引名 (字段名1[,字段名2 …]);
例子: ALTER TABLE t_employee ADD INDEX idx_emp_name (name);
3.SHOW INDEX 顯示索引
例如:SHOW INDEX FROM t_person
五、EXPLAIN 執行計划
查看SELECT語句的執行計划
在Sql語句前面加一個EXPLAIN即可。
詳情見: Mysql性能優化EXPLAIN
六、練習題目:
基礎題: 牛客網Sql實戰
進階題: sql語句練習50題