sql(基于mysql)速記一

一.概述

首先這是之前一版極其瑣碎的blog的鏈接.然后這篇博客不會涉及存儲過程觸發(fā)器等內(nèi)容(后續(xù)會補(bǔ)充),僅僅按照增刪改查這四個點(diǎn)來做基本的介紹以及記錄,畢竟工作中很大一部分需要的也是這些內(nèi)容~

二.素材準(zhǔn)備

為這次的記錄建好database以及user.(表結(jié)構(gòu)素材來自mysql必知必會)

create database notereview;

create user review@localhost identified by 'xxxxx';

grant all on notereview.* to review@localhost;

flush privileges;

三.查詢

基礎(chǔ)語句

查詢子語句有一個基本的模板:

    FROM xxx WHERE xxx GROUP BY xxx HAVING xxxx ORDER BY xxx LIMIT xxxxx

WHERE和條件連接

這里的WHERE就是查詢條件,簡單的條件過濾比如 =,<>,!=,<,>,<=,>=,BETWEEN,IN,NOT等.

還有就是對于NULL的檢查:IS NULL,IS NOT NULL

上面是使用單條子語句所可能用到的關(guān)鍵詞,如果是多條子語句可以通過AND 或者 OR 連接.其中 AND 的優(yōu)先級是高于 OR的.也就是說:

SELECT a,b,c FROM tableName WHERE conditionA OR conditionB AND conditionC;

相當(dāng)于是查詢同時(shí)滿足條件B和C,或者滿足條件A的數(shù)據(jù).舉個例子:

create table if not exists products(
    prod_id varcahr(10) not null auto_increment,
    vend_id int not null,
    prod_name varchar(255) not null,
    prod_price decimal(10,2) not null,
    prod_desc text not null,
    primary key(prod_id)
)engine = InnoDb default charset=utf8mb4 comment = '產(chǎn)品表';
SELECT prod_name,vend_id,prod_price FROM products  WHERE vend_id = 1002 OR vend_id = 1003 AND prod_price >= 10;
prod_name vend_id prod_price
Detonator 1003 13.00
Bird seed 1003 10.00
Fuses 1002 3.42
Oil can 1002 8.99
Safe 1003 50.00

其中Fuses的價(jià)格為3.42不滿足大于等于10的要求但是滿足了vend_id為1002的要求.

LIMIT 和 ORDER BY

然后是LIMIT以及ORDER BY,基礎(chǔ)模板為:

    xxx ORDER BY xxxx [DESC][,xxxx [desc]] LIMIT index[,offset];

也就是說按照一定規(guī)則排序后,從index行開始(包含index),返回最多offset行數(shù)據(jù),這里需要注意的是index是從0開始計(jì)算的,也就是說LIMIT 1,1其實(shí)返回的是第二行.

ORDER BY 默認(rèn)是升序,如果是DESC則是降序,其中可以按照多個字段排序,實(shí)際結(jié)果是按照排序字段的出現(xiàn)的優(yōu)先級來確定的,舉個例子:

SELECT prod_name,vend_id,prod_price FROM products where prod_price >10 ORDER BY prod_price DESC,vend_id ASC;
prod_name vend_id prod_price
JetPack 2000 1005 55.00
Safe 1003 35.00
JetPack 1000 1005 35.00
2 ton anvil 1001 14.99
Detonator 1003 13.00

這邊的結(jié)果可以看出雖然 JetPack 1000 的vend_id 也是1005但是排序的第一條件是按照prod_price 降序,所以他不能處在第一位,又因?yàn)榈诙€條件是按照 vend_id 升序,所以他最終處在第三位.

SELECT prod_name,vend_id,prod_price FROM products where prod_price >10 ORDER BY prod_price DESC,vend_id ASC limit 2,10;
prod_name vend_id prod_price
JetPack 1000 1005 35.00
2 ton anvil 1001 14.99
Detonator 1003 13.00

這里的結(jié)果對比上面的可以看出LIMIT 2,10 確實(shí)是從第三條開始返回的,如果數(shù)據(jù)不夠則會返回他所能返回的最多的數(shù)據(jù).

GROUP BY 和 HAVING

按照上面的順序,接下來是分組查詢GROUP BYHAVING.這兩者一般配合使用.HAVING 可以當(dāng)成是在使用GROUP BY時(shí)的WHERE,用來過濾分組后的數(shù)據(jù).其中SELECT 后接的表字段(聚合函數(shù)除外)必須出現(xiàn)在GROUP BY后.舉個例子,查詢products表中能夠提供多種產(chǎn)品的商戶(即產(chǎn)品多余一種),列出商戶id以及所能提供的產(chǎn)品數(shù)量并按照產(chǎn)品種類數(shù)降序排序列出.

SELECT vend_id,count(*) AS prods from products GROUP BY vend_id HAVING prods > 1 ORDER BY prods DESC;

結(jié)果如下:

vend_id prods
1003 7
1001 3
1002 2
1005 2

這里列出幾個常用的聚合函數(shù):

聚合函數(shù) 作用
AVG() 返回某列的平均值
COUNT() 返回某列的行數(shù)
MAX() 返回某列的最大值
MIN() 返回某列的最小值
SUM() 返回某列值之和

like 和正則

這邊 like和正則簡單提下,因?yàn)樾蕟栴}推薦放在搜索條件的最后面

WHERE xxxx  like 'xxx'

SELECT  prod_id FROM products WHERE prod_id LIKE 'JP%';
prod_id
JP1000
JP2000

%表示這里可以出現(xiàn)0,1或多個字符.這條語句相當(dāng)于查詢JP開頭的數(shù)據(jù)(注意NULL不會匹配)

同樣也可以通過正則來達(dá)到一樣的效果:

SELECT  prod_id FROM products WHERE prod_id REGEXP 'JP*';

# 這個則不行,因?yàn)閎inary相當(dāng)于是大小寫敏感匹配
SELECT  prod_id FROM products WHERE prod_id REGEXP BINARY 'jp*';

聯(lián)結(jié)查詢

等值聯(lián)結(jié)/內(nèi)部聯(lián)結(jié)

這個其實(shí)就是我們常用的 INNER JOIN或者多表?xiàng)l件查詢

#等值聯(lián)結(jié) 
SELECT a.x,b.x FROM a,b WHERE a.xxx = b.xxx;
#內(nèi)聯(lián)結(jié)
SELECT a.x,b.x FROM a INNER JOIN b ON a.xxx = b.xxx;

這里相當(dāng)于是那表a的每一行和表b的每一行去做匹配并留下符合條件的數(shù)據(jù)

這里有個特殊的比如自聯(lián)結(jié):

SELECT p1.prod_id,p1.prod_name FROM products AS p1,products AS p2 WHERE p1.vend_id = p2.vend_id AND p2.prod_id = 'DTNTR';

這里使用了別名是因?yàn)槭潜韕roducts和自己聯(lián)結(jié)防止指代不情.這句sql的結(jié)果是挑選DTNTR的商戶所能生產(chǎn)的所有商品

結(jié)果如下:

prod_id prod_name
DTNTR Detonator
FB Bird seed
FC Carrots
SAFE Safe
SLING Sling
TNT1 TNT (1 stick)
TNT2 TNT (5 sticks)

另外的LEFT JOIN,RIGHT JOIN就是所謂的左聯(lián)結(jié)右聯(lián)結(jié).什么聯(lián)結(jié)就是以那邊的數(shù)據(jù)為準(zhǔn),那邊的數(shù)據(jù)最全,如果右邊沒有匹配的數(shù)據(jù)則以NULL的形式展示.

組合查詢

UNION:其實(shí)是相當(dāng)于將多條SELECT的結(jié)果組合。默認(rèn)是去除重復(fù)行的,UNION ALL 則是不去重噠

# 結(jié)果見表1
SELECT vend_id,prod_id,prod_price FROM products WHERE prod_price <= 5;

#結(jié)果見表2
SELECT vend_id,prod_id,prod_price FROM products WHERE vend_id IN(1001,1002);

#結(jié)果見表3
SELECT vend_id,prod_id,prod_price FROM products WHERE prod_price <= 5 UNION SELECT vend_id,prod_id,prod_price FROM products WHERE vend_id IN(1001,1002);

#結(jié)果見表4
SELECT vend_id,prod_id,prod_price FROM products WHERE prod_price <= 5 UNION  ALL SELECT vend_id,prod_id,prod_price FROM products WHERE vend_id IN(1001,1002);

表1:

vend_id prod_id prod_price
1003 FC 2.50
1002 FU1 3.42
1003 SLING 4.49
1003 TNT1 2.50

表2:

vend_id prod_id prod_price
1001 ANV01 5.99
1001 ANV02 9.99
1001 ANV03 14.99
1002 FU1 3.42
1002 OL1 8.99

表3:

vend_id prod_id prod_price
1003 FC 2.50
1002 FU1 3.42
1003 SLING 4.49
1003 TNT1 2.50
1001 ANV01 5.99
1001 ANV02 9.99
1001 ANV03 14.99
1002 OL1 8.99

表4:

vend_id prod_id prod_price
1003 FC 2.50
1002 FU1 3.42
1003 SLING 4.49
1003 TNT1 2.50
1001 ANV01 5.99
1001 ANV02 9.99
1001 ANV03 14.99
1002 FU1 3.42
1002 OL1 8.99

這里因?yàn)槭菍⒔Y(jié)果合并,所以查詢字段必須一致~

四.插入

這個則是insert語句

 INSERT INTO targetName(columnName[,columnName]…) values(columnValue[,columnValue])[,(…)];

這里再提下遷移數(shù)據(jù)到新表:

INSERT INTO newTable SELECT * FROM oldTable;

#如果結(jié)構(gòu)不一致的話

INSERT INTO 新表(字段1,字段2,.......) SELECT 字段1,字段2,...... FROM 舊表;

五.刪除

DELETE FROM tableName WHERE xxx = xxx;

這里記得注意WHERE條件~
然后 TRUNCATE TABLE tableName 不過這個需要注意的是他不會激活觸發(fā)器,并且不會涉及事務(wù),所以效率很高但是注意備份數(shù)據(jù),畢竟不能回滾.

六.更新

UPDATE targetName SET columnName = xxx [,columnName2 = xxxx] WHERE xxx = xxxx;
UPDATE products SET prod_price = 35.00 WHERE prod_id ='SAFE';

同樣不要忘記WHERE 條件哈~

七.幾個練習(xí)(from leetcode-cn)

交換工資(?性別)

給定一個 salary 表,如下所示,有 m = 男性 和 f = 女性 的值。交換所有的 f 和 m 值(例如,將所有 f 值更改為 m,反之亦然)。要求只使用一個更新(Update)語句,并且沒有中間的臨時(shí)表。

注意,您必只能寫一個 Update 語句,請不要編寫任何 Select 語句。

id name sex salary
1 A m 2500
2 B f 1500
3 C m 5500
4 D f 500
# 這里使用了 CASE WHEN
UPDATE salary
SET
    sex = CASE sex
        WHEN 'm' THEN 'f'
        ELSE 'm'
    END;


# if的話
UPDATE salary
SET 
 sex = IF(sex='m','f','m');

# 這里就不涉及代碼思路解決了比如字符串變換

超過經(jīng)理收入的員工

Employee 表包含所有員工,他們的經(jīng)理也屬于員工。每個員工都有一個 Id,此外還有一列對應(yīng)員工的經(jīng)理的 Id。

Id Name Salary ManagerId
1 Joe 70000 3
2 Henry 80000 4
3 Sam 60000 NULL
4 Max 90000 NULL
SELECT  a.Name AS Employee   FROM Employee AS a,Employee AS b where a.ManagerId = b.Id AND a.Salary > b.Salary;

不訂購任何東西的客戶

某網(wǎng)站包含兩個表,Customers 表和 Orders 表。編寫一個 SQL 查詢,找出所有從不訂購任何東西的客戶。

Customers 表:

Id Name
1 Joe
2 Henry
3 Sam
4 Max

Orders 表:

Id CustomerId
1 3
2 1
SELECT Name AS Customers from Customers  where Id NOT IN (select CustomerId from Orders);
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容