SQL常用場景&語句
SQL常用場景&語句
目錄一、顯示命令
顯示資料庫列表:
show databases;
顯示庫中的資料表:
use dbname;
show tables;
顯示資料表的結構:
describe tablename;
show columns from tablename;
二、建庫建表&刪庫刪表
建庫:
create database dbname;
建表:
create table tabelname (欄位設定);
刪庫:
drop database dbname;
刪表:
drop table tablename;
將表中記錄清空:
-- delete僅清空表內資料,自增id會被保留(下次繼續從這個自增id開始)
delete from tablename;
-- truncate會把自增id一起清除,truncate成功會返回0
truncate table tablename;
三、基礎資料檢索
檢索所有資料:
select * from tablename
檢索單(多)個列:
select column1 from tablename;
select column1, column2 from tablename;
檢視當前時間:
-- mysql NOW(); -- 使用方式 SELECT NOW(); 輸出格式YYYY-MM-DD HH:MM:SS CURRENT_DATE() / CURDATE() ; -- 使用方式 SELECT CURRENT_DATE() 或 SELECT CURDATE(); 輸出格式YYYY-MM-DD CURRENT_TIME() / CURTIME() ; -- 使用方式 SELECT CURRENT_TIME() 或 SELECT CURTIME(); 輸出格式HH:MM:SS -- 例子:可以在建表的時候,讓當前時間作為預設值填入表記錄 CREATE TABLE Orders ( OrderId int NOT NULL, ProductName varchar(50) NOT NULL, OrderDate datetime NOT NULL DEFAULT NOW(), PRIMARY KEY (OrderId) ) -- 如此做,在插入資料時,會沒填入OrderDate會自動填入當前時間 -- sql server select getdate()
查詢併為欄位換名:
select column1 as 列1 from tablename;
四、運算子
算數運算子
字元 | 說明 |
---|---|
+ | 加法 |
- | 減法 |
* | 乘法 |
/ 或 DIV | 除法 |
% 或 MOD | 取餘數 |
SELECT 1+2, 1-2, 1*2, 10/4, 10%4, 10 DIV 4, 10 MOD 4;
比較運算子
符號 | 描述 | 備註 |
---|---|---|
= | 等於 | |
<>, != | 不等於 | |
> | 大於 | |
< | 小於 | |
<= | 小於等於 | |
>= | 大於等於 | |
BETWEEN | 在兩值之間 | >=min&&<=max |
NOT BETWEEN | 不在兩值之間 | |
IN | 在集合中 | |
NOT IN | 不在集合中 | |
<=> | 嚴格比較兩個NULL值是否相等 | 兩個操作碼均為NULL時,其所得值為1;而當一個操作碼為NULL時,其所得值為0 |
IS NULL | 為空 | |
IS NOT NULL | 不為空 |
比較運算子經常與where搭配使用,在下一節的資料過濾中再展開,這裡主要講一下<=>
。
<=>
是安全等於,他為NULL安全的等值比較,NULL的值是沒有任何意義的。所以=號運算子不能把NULL作為有效的結果。其他功能類似=
。
-- =
select null=null;
+-----------+
| null=null |
+-----------+
| NULL |
+-----------+
-- <=>
select null<=>null;
+-------------+
| null<=>null |
+-------------+
| 1 |
+-------------+
select null<=>1;
+----------+
| null<=>1 |
+----------+
| 0 |
+----------+
<=>
與=
的區別:與 =
的區別在於當兩個操作碼均為 NULL 時,其所得值為 1 而不為 NULL,而當一個操作碼為 NULL 時,其所得值為 0而不為 NULL。
<=>
作用:
- 可以判斷一個值是否非空,例如
1 IS NULL
可以等價為1<=>NULL
。 - 當兩個運算元都有可能出現NULL值並且需要比較一致時。例如存在a,b兩個可能存在NULL值的列需要進行相等比較時,可以使用
a<=>b
邏輯運算子
和比較運算子一樣,常用於where子句中
運算子號 | 作用 |
---|---|
NOT 或 ! | 邏輯非 |
AND | 邏輯與 |
OR | 邏輯或 |
XOR | 邏輯異或 |
位運算子
運算子號 | 作用 |
---|---|
& | 按位與 |
| | 按位或 |
^ | 按位異或 |
~ | 取反 |
<< | 左移 |
>> | 右移 |
-- 位與運算子 &
SELECT 10 & 15,9 & 4 & 2;
+---------+-----------+
| 10 & 15 | 9 & 4 & 2 |
+---------+-----------+
| 10 | 0 |
+---------+-----------+
-- 位異或運算子 ^
SELECT 10^15,1^0,1^1;
+-------+-----+-----+
| 10^15 | 1^0 | 1^1 |
+-------+-----+-----+
| 5 | 1 | 0 |
+-------+-----+-----+
-- 位左移運算子 <<
SELECT 1<<2,4<<2;
+------+------+
| 1<<2 | 4<<2 |
+------+------+
| 4 | 16 |
+------+------+
-- 位右移運算子 >>
SELECT 1>>1,16>>2;
+------+-------+
| 1>>1 | 16>>2 |
+------+-------+
| 0 | 4 |
+------+-------+
-- 位取反運算子 ~
SELECT ~1,~18446744073709551614;
+----------------------+-----------------------+
| ~1 | ~18446744073709551614 |
+----------------------+-----------------------+
| 18446744073709551614 | 1 |
+----------------------+-----------------------+
五、資料過濾
使用where子句
-- 使用where子句,可以用等號來選擇查詢條件,也可以搭配各種運算子來檢索
select * from tablename where column1 = 100;
-- 與比較運算子搭配
select * from tablename where column1 > 100;
select * from tablename where column1 not in ('A', 'B');
select * from tablename where column1 between 30 and 50;
select * from tablename where column1 is not null;
-- 與邏輯運算子搭配
select * from tablename where column1 > 100 and column2 < 100;
select * from tablename where column1 > 100 or column2 < 100;
select * from tablename where column1 not 100;
-- 與位運算子搭配
select * from tablename where column1&15 > 0;
-- column1與15進行位運算,看是否大於0,column1的資料應該是整型。
-- 假設有column1中有一個數字是10,10 的補碼為 1010,15 的補碼為 1111,按位與運算之後,結果為 1010,即整數 10,這行資料就會被篩選出來。
-- 這種場景可以用於批量指定查詢條件
使用模糊查詢&萬用字元
-- 使用like操作符
select * from tablename where name like 'H%' -- 以H開頭
select * from tablename where name like '%ka%' -- 包含ka
select * from tablename where name like 'Hika__' -- 下劃線_萬用字元(用途和%一樣,不過_只匹配單個字元)
使用正則表示式
-- 使用正則表示式需要用REGEXP關鍵字,並在REGEXP後面跟上正則表示式內容
select * from tablename where name regexp 'Hikari';
select * from tablename where name regexp 'H.';
select * from tablename where name regexp 'Hikari|Irakih' -- OR匹配
子查詢
- 子查詢也稱作內查詢或者巢狀查詢
- 先於主查詢被執行,其結果將作為外層查詢的條件
- 在增刪改查中都可以使用子查詢,支援多層巢狀
-- 查詢時常與in一起使用
select * from tablename where column1 in (select * from tablename where column2 = 'aaa');
-- 在插入中使用
insert into tablename2 * from tablename1 where column1 in (select * from tablename where column2 = 'aaa');
-- 在修改中使用
update tablename2 set column3=101 where column1 in (select * from tablename where column2 = 'aaa');
-- 在刪除中使用
delete from tablename2 where column1 in (select * from tablename where column2 = 'aaa');
六、排序與限制
使用order by
排序資料:
select * from tablename order by column; -- 預設按升序排序
select * from tablename order by column ASC; -- 升序排序
select * from tablename order by column DESC; -- 降序排序
select * from tablename order by column1 DESC,column2 DESC; -- 多欄位排序
限制結果條目:select column1,column2,... from 庫名 limit 位置偏移量
select * from tablename limit 3; -- 獲取前3行資料
select * from tablename limit 3, 3; -- 3,3表示從第三行開始數,顯示後三行
select * from tablename limit 3 offset 3; -- 等價與上一條
- limit x, y 分句表示: 跳過 x 條資料,讀取 y 條資料
- limit y offset x 分句表示: 跳過 x 條資料,讀取 y 條資料
七、修改表資料&更新表
修改表中資料:
update tablename set column1=100 where name=’Hikari';
往表中插入記錄:
insert into tablename values ('xxx', 'xxx', 'xxx'); -- 這裡要能和表頭一一對上, 一定要與欄位在表中定義的順序一致
insert into tablename (column1, column2, column3) values ('xxx', 'xxx', 'xxx');
在表中增加欄位:
alter table tablename add column4 int(4) default 0;
修改欄位:
-- 修改欄位型別
alter table tablename modify column2 char(10);
-- 修改欄位名稱:ALTER TABLE 表名 CHANGE [column] 舊欄位名 新欄位名 新資料型別;
alter table tablename change column3 name varchar(16) not null comment '名稱';
-- 修改欄位預設值
alter table tablename alter column1 set default 100;
-- 刪除預設值
alter table tablename alter column1 drop default;
重新命名資料表:
alter table tablename rename tablerename;
-- 或
rename table tablename1 to tablerename1, tablename2 to tablerename2;
刪除欄位:
alter table tablename dorp column4;
修改資料表型別:
alter table tablename engine=MYISAM;
八、資料處理函式
文字處理函式:
LEFT() 返回串左邊的字元
LENGTH() 返回串的長度
LOCATE() 找出串的一個子串
LOWER() 將串轉換為小寫
LTRIM() 去掉串左邊的空格
RIGHT() 返回串右邊的字元
RTRIM() 去掉串右邊的空格
SOUNDEX() 返回串的SOUNDEX值
SUBSTRING() 返回子串的字元
UPPER() 將串轉換為大寫
日期和時間處理函式:
ADDDATE() 增加一個日期(天、周等)
ADDTIME() 增加一個時間(時、分等)
CURDATE() 返回當前日期
CURTIME() 返回當前時間
DATE() 返回日期時間的日期部分
DATEDIFF() 計算兩個日期之差
DATE_ADD() 高度靈活的日期運算函式
DATE_FORMAT() 返回一個格式化的日期或時間串
DAY() 返回一個日期的天數部分
DAYOFWEEK() 對於一個日期,返回對應的星期幾
HOUR() 返回一個時間的小時部分
MINUTE() 返回一個時間的分鐘部分
MONTH() 返回一個日期的月份部分
NOW() 返回當前日期和時間
SECOND() 返回一個時間的秒部分
TIME() 返回一個日期時間的時間部分
YEAR() 返回一個日期的年份部分
SELECT DATE("2022-04-09"); -- 2022-04-09
SELECT DATEDIFF('2001-01-01','2001-02-02') -- -32
數值處理函式:
ABS() 返回一個數的絕對值
COS() 返回一個角度的餘弦
EXP() 返回一個數的指數值
MOD(x,y) 返回除操作的餘數
PI() 返回圓周率
RAND() 返回一個隨機數
ROUND() 返回離 x 最近的整數
SIN() 返回一個角度的正弦
SQRT() 返回一個數的平方根
TAN() 返回一個角度的正切
POW(x, y) / POWER(x,y) 返回 x 的 y 次方
SELECT ABS(-1) -- 返回1
SELECT COS(2);
SELECT PI() -- 3.141593
SELECT POW(2,3) -- 8
SELECT RAND() -- 0.93099315644334
SELECT ROUND(1.23456) -- 1
聚集函式:
AVG() 返回某列的平均值
COUNT() 返回某列的行數
MAX() 返回某列的最大值
MIN() 返回某列的最小值
SUM() 返回某列值之和
SELECT COUNT(*) FROM TABLE;//總行數
SELECT COUNT(欄位) FROM TABLE;//欄位不為NULL的行數
SELECT SUM(價格欄位) FROM TABLE;//欄位值總和
SELECT AVG(價格欄位) FROM TABLE;//欄位值平均值
SELECT MAX(價格欄位) AS '最大價格' FROM TABLE;//欄位最大值
SELECT MIN (價格欄位) AS '最小价格' FROM TABLE;//欄位最小值
注:
1.當聚集函式遇到空值時,除了count(*)
外,都跳過空值而只處理非空值。
2.聚集函式只能用於select
子句和group by
中的having
子句。
九、分組查詢
- 使用GROUP BY語句來實現分組
- 通常結合聚合函式一起使用
- 可以按一個或多個欄位對結果進行分組
-- 計算各個名字出現的次數
select count(*), name from tablename group by name;
-- 與 order by 一起使用
select count(*), column2 from tablename group by column2 order by column2 desc
-- 使用with rollup
-- 比如統計一個使用者(username)的登入次數(signin_count)
select username, sum(signin_count) from user_table group by username with rollup;
-- 查詢的最後一行記錄了總登入次數(所以username那裡時NULL)
十、連線查詢
1. 內連線(join 或 inner join)
INNER JOIN 與 JOIN 是相同的。內連線只會返回符合條件的行,對於無法匹配的行則不返回。
示意圖:
select t1.column1 from tablename1 as t1 inner join tablename2 as t2 on t1.column2 = t2.column2 -- 這裡的inner join寫成join也一樣
2. 左外連線(left join)
從左表(table1)返回所有的行,即使右表(table2)中沒有匹配。如果右表中沒有匹配,則結果為 NULL。
示意圖:
select t1.column1 from tablename1 as t1 left join tablename2 as t2 on t1.column2 = t2.column2
3. 右外連線(right join)
從右表(table2)返回所有的行,即使左表(table1)中沒有匹配。如果左表中沒有匹配,則結果為 NULL。
示意圖:
select t1.column1 from tablename1 as t1 right join tablename2 as t2 on t1.column2 = t2.column2
4. 完全連線(full join)
FULL OUTER JOIN 關鍵字只要左表(table1)和右表(table2)其中一個表中存在匹配,則返回行。
示意圖:
select t1.column1 from tablename1 as t1 full join tablename2 as t2 on t1.column2 = t2.column2
十一、集合查詢
union/union all
UNION 操作符用於合併兩個或多個 SELECT 語句的結果集。
select column1 from tablename1
union
select column2 from tablename2
union和union all的區別在於前者會去掉重複元素,並會對產生的結果排序(因為union是排完序再去重),後者則簡單的合併結果後就返回了。
交集、差集用where就能實現
十二、資料庫匯出、匯入
匯出資料庫/表:
/* 格式
1. 匯出所有資料庫
mysqldump -u [資料庫使用者名稱] -p -A>[備份檔案的儲存路徑]
或
mysqldump -u [資料庫使用者名稱] -p --all-databases>[備份檔案的儲存路徑]
2. 匯出指定資料庫
mysqldump -u [資料庫使用者名稱] -p [資料庫名]>[備份檔案的儲存路徑]
3. 只匯出資料,不匯出資料結構
mysqldump -u [資料庫使用者名稱] -p -t [資料庫名]>[備份檔案的儲存路徑]
4. 匯出資料庫中的儲存過程和函式
mysqldump -u [資料庫使用者名稱] -p -R [資料庫名]>[備份檔案的儲存路徑]
5. 匯出表
mysqldump -u [資料庫使用者名稱] -p [資料庫名] [表名]>[備份檔案的儲存路徑]
*/
-- 例子
mysqldump -u root -p xxx > /home/xxx.sql
匯入資料庫:
-- source sql檔案路徑
source /home/xxx.sql
-- 使用 < 符號
-- mysql -u root –p < [備份檔案的儲存路徑]
十三、DB密碼與使用者
修改密碼:
/*
1. 首先進入目錄mysql\bin
2. 格式:mysqladmin -u使用者名稱 -p舊密碼 password 新密碼
3. 按以上格式更新密碼
*/
mysqladmin -u root -p 1234 password 4321
-- 另一種方法
UPDATE mysql.user SET password=PASSWORD("new password") WHERE User="root";
FLUSH PRIVILEGES;
顯示當前使用者:
SELECT USER();
新增使用者:
-- grant 許可權 on 資料庫.表 to 使用者名稱@登入主機 identified by “密碼”
-- *.*表示所有資料庫的所有表
-- %表示任意主機都能登入
grant select,insert,update,delete on *.* to test1”%" identified by “abc”;
grant select,insert,update,delete on mydb.* to test2@localhost identifiedby “abc”;
刪除使用者:
delete from user where user='使用者名稱' and host='localhost';