日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > 数据库 >内容正文

数据库

【总结记录】《MySQL必知必会》读后笔记,结合 leetcode 例题理解

發(fā)布時(shí)間:2024/7/23 数据库 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【总结记录】《MySQL必知必会》读后笔记,结合 leetcode 例题理解 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

  • 一. 《MySQL知會(huì)》讀后筆記
      • 1. 零散的前文知識(shí)
      • 2. 連接數(shù)據(jù)庫(kù)
      • 3. 檢索數(shù)據(jù)(重點(diǎn)開始了)
      • 4. 排序、過濾數(shù)據(jù)
      • 5. 通配符、正則表達(dá)式
      • 6. 匯總數(shù)據(jù)
      • 7. 分組數(shù)據(jù)
          • (1)GROUP BY(數(shù)據(jù)分組)
          • (2)HAVING (過濾分組)
          • (3)GROUP BY 和 ORDER BY 的區(qū)別
      • 8. 子查詢 && 聯(lián)結(jié)
          • (1)子查詢
          • (2)聯(lián)結(jié)
          • (3)高級(jí)聯(lián)結(jié)
      • 9. 組合查詢
  • 二. leetcode 實(shí)戰(zhàn)

這篇文章主要是為了學(xué)習(xí)查詢的 sql 語(yǔ)句~
主要是《MySQL必知必會(huì)》的筆記,也可能會(huì)加入其他額外查詢的知識(shí)
結(jié)合 leetcode 的 sql 例題理解

一. 《MySQL知會(huì)》讀后筆記

1. 零散的前文知識(shí)

  • 數(shù)據(jù)庫(kù)表名唯一

  • 主鍵(一列、或一組列):唯一區(qū)分表中各行,需要滿足條件:

  • 任意兩行都不具有相同主鍵值
  • 每個(gè)行都要有主鍵(主鍵列不允許NULL值
  • 主鍵的好習(xí)慣:(主要就是保持主鍵值穩(wěn)定啦)

  • 不更新主鍵列中的值
  • 不重用主鍵列的值
  • 不在主鍵列中使用可能會(huì)更改的值
  • 為什么用 MySQL?

  • 開源,免費(fèi)
  • 性能好,執(zhí)行快
  • 可信賴、簡(jiǎn)單

2. 連接數(shù)據(jù)庫(kù)

安裝、開啟 MySQL 之類的內(nèi)容,可以去其他博客看看,我這里就不造輪子了= =

  • 選擇數(shù)據(jù)庫(kù)
  • USE databaseName;
  • 查看數(shù)據(jù)庫(kù)
  • SHOW DATABASES;
  • 查看數(shù)據(jù)庫(kù)中的表
  • SHOW TABLES;

    tips:自動(dòng)增量 auto_increment,用于訂單編號(hào)、用戶ID等地方。這個(gè)屬性會(huì)讓 MySQL 自動(dòng)地為每個(gè)行分配下一個(gè)可用編號(hào)。

    3. 檢索數(shù)據(jù)(重點(diǎn)開始了)

    • SQL 語(yǔ)句的結(jié)束:用分號(hào)‘;'結(jié)束
    • 大小寫:不區(qū)分,但是建議關(guān)鍵字大寫,列和表名小寫(可讀性高)
    • 空格和換行:被省略,但是可以用來增加可讀性
    • 檢索多個(gè)列:用逗號(hào) ‘,’
    SELECT id, name, price FROM products;
    • 檢索所有列:用 * 通配符(不必要就不用,會(huì)降低檢索和應(yīng)用程序的性能
    SELECT * FROM products;
    • 檢索不同的行:用 DISTINCT 關(guān)鍵字
      注意:DISTINCT 應(yīng)用于所有列,而非只是前置列(見下列代碼)
    SELECT DISTINCT id FROM products; SELECT DISTINCT id, price; # (1,100)和 (1,200)都會(huì)顯示,即使 id 一樣
    • 限制結(jié)果:LIMIT 子句,只返回第一行或前幾行(也可以選定開始行)
    SELECT name FROM products LIMIT 5; # 只要前 5 行 SELECT name FROM products LIMIT 3, 5; # 從行 3 開始的 5 行 # 行數(shù)不夠時(shí),有幾行返幾行
    • 使用完全限定的表名:可以完全限定表名來引用列
    SELECT product.name FROM products;

    4. 排序、過濾數(shù)據(jù)

    • ORDER BY 子句:默認(rèn)升序,可以通過 DESC 關(guān)鍵字變成降序
    SELECT name FROM products ORDER BY id; # 默認(rèn)升序 SELECT name FROM products ORDER BY price, id; # 按多個(gè)列排序,從左到右(后面的可能用不到) SELECT name FROM products ORDER BY id DESC; # 變成降序 SELECT name FROM products ORDER BY price DESC, id; # 可以部分降序,在需要降序的列后面加 DESC 即可 注意:ORDER BY 子句必須在 FROM 子句之后
    • 過濾數(shù)據(jù) WHERE:
    # = != < <= > >= 等于、不等于、大于小于 SELECT name FROM products WHERE name = 'fuses'; # 字符串用單引號(hào) # BETWEEN 指定值,雙閉區(qū)間 SELECT name FROM products WHERE price BETWEEN 5 AND 10 # 用 AND,范圍[5, 10]
    • 空值檢查:對(duì)于 NULL,需要用 IS NULL,而 = NULL 是不行的。(IS NOT NULL同理)
    SELECT name FROM products WHERE name != NULL # 無效 SELECT name FROM products WHERE name IS NOT NULL # 有效
    • NULL 與不匹配:過濾時(shí),NULL 一定會(huì)被過濾,因?yàn)閿?shù)據(jù)庫(kù)不知道它們是否匹配,所以匹配過濾、不匹配過濾時(shí)都不會(huì)返回它們
    • AND、OR 操作法:用法見代碼,注意 AND 優(yōu)先級(jí)比 OR 高,建議用括號(hào)
    SELECT id FROM products WHERE id > 5 AND id < 10; SELECT id FROM products WHERE id > 5 OR id % 2 = 0; SELECT id FROM products WHERE (id = 2 OR id = 3) AND price >= 100; # 括號(hào)優(yōu)先級(jí)最高 SELECT id FROM products WHERE id = 2 OR id = 3 AND price >= 100; # 不加括號(hào),則等同于 id = 2 OR (id = 3 AND price >= 100),意義不同了
    • IN 操作符:指定范圍,等同于 OR,優(yōu)點(diǎn):
  • 對(duì)于長(zhǎng)的合法清單,IN 的語(yǔ)法更清楚
  • 一般比 OR 更快
  • 最大的優(yōu)點(diǎn)是可以包含其他 SELECT 語(yǔ)句,更加動(dòng)態(tài)地建立 WHERE 子句(后面講)
  • SELECT id FROM products WHERE id IN (1, 2, 5); SELECT id FROM products WHERE id = 1 OR id = 2 OR id = 5; # 等同
    • NOT 操作符:唯一功能,否定之后跟的所有條件。對(duì)于復(fù)雜子句很有用。
    SELECT id FROM products WHERE id NOT IN (1, 2, 5);

    5. 通配符、正則表達(dá)式

    這塊感覺用得不多,簡(jiǎn)單寫寫吧

    • LIKE 操作符:后跟通配符(百分號(hào)通配符、下劃線通配符)
    • 百分號(hào)通配符:% 表示任何字符出現(xiàn)任意次數(shù)
    SELECT id FROM products WHERE name LIKE 'jet%'; # 尋找 jet 開頭的產(chǎn)品 SELECT id FROM products WHERE name LIKE '%jet%'; # 可以在任意位置使用多個(gè) # 可以修改配置,選擇【區(qū)分大小寫】。不能匹配 NULL
    • 下劃線通配符:_ 只能匹配單個(gè)字符,而不是多個(gè)字符
    SELECT id FROM products WHERE name LIKE '_ jojo'; # 得到 '1 jojo' 和 '2 jojo',以此類推
    • 注意:使用通配符所花時(shí)間更長(zhǎng),不要過度使用
    • 正則表達(dá)式:用于匹配文本的特殊的串,可用于查找、替換、提取等功能的一種特殊語(yǔ)言
    # 用 REGEXP 關(guān)鍵字開頭(regular expression),不區(qū)分大小寫 # 和 LIKE 的重要區(qū)別:匹配整個(gè)列(LIKE),還是匹配部分列值 (REGEXP) # . 任一字符 SELECT id FROM products WHERE name REGEXP '.000'; # 得到 JetPack 1000 和 JetPack 2000# | 或 SELECT id FROM products WHERE name REGEXP '1000|2000'; # 得到 JetPack 1000 和 JetPack # [123] 括號(hào)內(nèi)的任一字符 SELECT id FROM products WHERE name REGEXP '[123] Ton'; # 得到 '1 Ton a' 和 '2 Ton b' # 可以用 [0-9] 來代替 [0123456789],字母同理# // 匹配特殊字符,如 //. SELECT id FROM products WHERE name REGEXP '\\.'; # 得到 'Ball.' # 也用來引用元字符,如 //f(換頁(yè))、//n(換行)等# 匹配多個(gè)實(shí)例 SELECT id FROM products WHERE name REGEXP '\\([0-9] sticks?\\)'; # 得到'(1 sticks)'、'(9 stick)'等內(nèi)容,?使得前一個(gè)字符可選(此處為 s)

    6. 匯總數(shù)據(jù)

    • 有平均值、計(jì)數(shù)、最大值、最小值、總和等
    # AVG:只能用于單個(gè)列(獲取多個(gè)列,則需多個(gè)AVG函數(shù)),忽略列值為 NULL 的行 SELECT AVG(price) AS avg_price # 用 AS 來重命名獲取的新列 FROM products WHERE id = 3;# COUNT():不一定忽略 NULL 值 SELECT COUNT(*) FROM customers; # 不忽略 NULL 值 SELECT COUNT(name) FROM customers; # 忽略 NULL 值# MAX()、MIN():忽略 NULL 值,允許對(duì)非數(shù)值數(shù)據(jù)使用(如文本等)# SUM() 忽略 NULL 值# 聚集不同值:通過 DISTINCT 實(shí)現(xiàn)(必須用列名) SELECT AVG(DISTINCT price) FROM products # 忽略重復(fù)價(jià)格,計(jì)算平均值

    7. 分組數(shù)據(jù)

    注意 GROUP BY 和 HAVING 的作用區(qū)別噢!

    (1)GROUP BY(數(shù)據(jù)分組)
    • 必須出現(xiàn)在 WHERE 子句之后,ORDER BY 子句之前
    • 代碼示例:
    SELECT id, COUNT(*) FROM products GROUP BY id; # 通過供應(yīng)商 id 分組,獲取各個(gè)供應(yīng)商提供的商品種類數(shù)量
    (2)HAVING (過濾分組)
    • WHERE 過濾的是行,而不是分組,因此我們需要引入 HAVING 來進(jìn)行分組的過濾。
    • 也就是說:WHERE 與 HAVING 的區(qū)別在于過濾對(duì)象(行 or 分組)
    • HAVING 支持所有的 WHERE 操作符
    • 代碼示例(引用上面 GROUP BY 的例子):
    SELECT id, COUNT(*) FROM products GROUP BY id HAVING COUNT(*) >= 2; # 過濾種類小于 2 的分組
    (3)GROUP BY 和 ORDER BY 的區(qū)別
    • ORDER BY 是排序的唯一方法
    ORDER BYGROUP BY
    作用排序產(chǎn)生的輸出分組行,但輸出可能不是分組的順序
    不一定必須使用每個(gè)選擇列表達(dá)式

    8. 子查詢 && 聯(lián)結(jié)

    一般來說子查詢更好理解,聯(lián)結(jié)效率更高

    (1)子查詢
    • 總是從內(nèi)向外處理。
    • 并不總是最有效方法
    • 最常見的使用是WHERE子句的 IN 操作符中。
    • 代碼例子
    SELECT order_num FROM orderitems WHERE prod_id = 'TNT2'; # 得到 5、7 SELECT cust_id FROM orders WHERE order_num IN (5, 7) # 由上面查詢得到的5、7繼續(xù)檢索# 其實(shí)上面的兩個(gè) sql 語(yǔ)句,可以通過一個(gè)子查詢完成 SELECT cust_id FROM orders WHERE order_num IN (SELECT order_num FROM orderitems WHERE prod_id = 'TNT2' );
    • 可以由此寫出功能強(qiáng)、且靈活的 SQL 語(yǔ)句
    • 對(duì)于嵌套個(gè)數(shù)沒有限制,但是由于性能限制,不能嵌套太多的子查詢。
    (2)聯(lián)結(jié)
    • 這是 SQL 最強(qiáng)大的功能之一噢~
    • 外鍵:某個(gè)表中的一列,包含另一個(gè)表的主鍵值,定義了兩個(gè)表之間的關(guān)系。好處如下:
    • 信息不重復(fù),不浪費(fèi)時(shí)間、空間
    • 外鍵對(duì)應(yīng)表格的信息變動(dòng),只需改變其表的值,以它為外鍵的表則不被干擾(因?yàn)槠渌碇还芡怄I嘛!而外鍵是對(duì)應(yīng)表格的主鍵,因此不會(huì)改變)
    • 因?yàn)閿?shù)據(jù)無重復(fù),因此可以保證數(shù)據(jù)一致性
    • 總之,關(guān)系數(shù)據(jù)可以有效地存儲(chǔ)方便地處理。因此關(guān)系型數(shù)據(jù)庫(kù)的可伸縮性遠(yuǎn)比非關(guān)系型數(shù)據(jù)庫(kù)要好。

    可伸縮性:能夠適應(yīng)不斷增加的工作量而不失敗(資本家狂喜)

    • 為什么要使用聯(lián)結(jié)?
      為了使用單條 SELECT 語(yǔ)句,檢索出存儲(chǔ)在多個(gè)表中的數(shù)據(jù)
    • 創(chuàng)建方法:規(guī)定要聯(lián)結(jié)的所有表,以及它們?nèi)绾温?lián)結(jié)即可。
    SELECT vend_name, prod_name, prod_price FROM vendors, products WHERE vendors.vend_id = products.vend_id ORDER BY vend_name, prod_name;
    • 笛卡爾積:由沒有聯(lián)結(jié)條件的表關(guān)系返回的結(jié)果(檢索出的行的數(shù)目的表1行數(shù) * 表2行數(shù)
    • 目前為止所用的聯(lián)結(jié)稱為等值聯(lián)結(jié),也稱為內(nèi)部聯(lián)結(jié),可以使用這樣的語(yǔ)法實(shí)現(xiàn)
    # 和上面的句子效果相同,規(guī)范首選 INNER JOIN ... ON SELECT vend_name, prod_name, prod_price FROM vendors INNER JOIN products ON vendors.vend_id = products.vend_id
    • 聯(lián)結(jié)多個(gè)表:聯(lián)結(jié)表的數(shù)目無限制,但是越多越耗費(fèi)資源,下降性能
    • 多做實(shí)驗(yàn):為實(shí)現(xiàn)任一SQL操作,一般存在不止一種方法。性能可能會(huì)受操作類型、表中數(shù)據(jù)量、是否存在索引或鍵,以及其他一些條件的影響。
    (3)高級(jí)聯(lián)結(jié)
    • 使用表別名:主要理由有兩個(gè):
    • 縮短 SQL 語(yǔ)句
    • 允許在單條 SELECT 語(yǔ)句中,多次使用相同的表
    SELECT cust_name, cust_contact FROM customers AS c, orders AS o, orderitems AS oi WHERE c.cust_id = o.cust_idAND oi.order_num = o.order_numAND prod_id = 'TNT2';
    • 自聯(lián)結(jié)同表子查詢,用自聯(lián)結(jié)替代會(huì)更好。(見下兩SQL語(yǔ)句對(duì)比)
    # 子查詢 SELECT id, name FROM products WHERE v_id = (SELECT v_id FROM products WHERE id = 'DTNTR' );# 自聯(lián)結(jié) SELECT p1.id, p1.name FROM products p1, products p2 WHERE p1.v_id = p2.v_id # 保證每行的供應(yīng)商都相同AND p2.id = 'DTNTP'
    • 外部聯(lián)結(jié):聯(lián)結(jié)包括了相關(guān)表中沒有關(guān)聯(lián)行的行。
      某些場(chǎng)景需要使用,比如列出所有產(chǎn)品,以及訂購(gòu)數(shù)量,包括 沒有人訂購(gòu)的產(chǎn)品
    • 用 OUTER JOIN。需要指定左聯(lián)、還是右聯(lián)(LEFT、RIGHT)
    SELECT customers.cust_id, orders.order_num FROM customers LEFT OUTER JOIN orders # OUTER 應(yīng)該是可以省略的 ON customers.cust_id = orders.cust_id;

    9. 組合查詢

    沒咋用過,簡(jiǎn)單寫寫= =

    • 需要使用組合查詢的兩種情況
    • 單個(gè)查詢中,從不同的表返回類似結(jié)構(gòu)的數(shù)據(jù)
    • 對(duì)單個(gè)表執(zhí)行多個(gè)查詢,按單個(gè)查詢返回?cái)?shù)據(jù)
    • 用 UNION,可以組合多個(gè) SELECT 語(yǔ)句,將它們的結(jié)果組合成單個(gè)結(jié)果集
    • 使用方法:很簡(jiǎn)單,在 SELECT 語(yǔ)句之間放上 UNION 即可
    SELECT vend_id, prod_id, prod_price FROM products WHERE prod_price <= 5 UNION # 來了!聯(lián)結(jié)起來!! SELECT vend_id, prod_id, prod_price FROM products WHERE vend_id IN (1001, 1002);
    • 列數(shù)據(jù)類型必須兼容,但不必完全相同
    • UNION 會(huì)自動(dòng)去除重復(fù)行
    • 如果不想去除重復(fù)行,可以用 UNION ALL
    • 對(duì) UNION 組合查詢,只能用一條 ORDER BY 子句,必須出現(xiàn)在最后一條 SELECT 語(yǔ)句之后

    二. leetcode 實(shí)戰(zhàn)

    175. 組合兩個(gè)表

    • 考察外聯(lián)結(jié)性質(zhì):可以包括沒有關(guān)聯(lián)的行。
    SELECT FirstName, LastName, City, State FROM Person p LEFT JOIN Address a # 因?yàn)闊o論 person 是否有地址信息,都要提供 ON p.PersonID = a.PersonID; # 因此使用 LEFT JOIN ON 外聯(lián)結(jié),可以包括相關(guān)表中沒有關(guān)聯(lián)行的行

    176. 第二高的薪水

    • 子查詢,先找出第一高的薪水,再依此作 WHERE 條件篩數(shù)據(jù)
    # Write your MySQL query statement below SELECT MAX(Salary) AS SecondHighestSalary FROM Employee WHERE Salary < (SELECT MAX(Salary) FROM Employee) # 先找最高值

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

    • 自聯(lián)結(jié)!組合成 < 員工信息 + 對(duì)應(yīng)經(jīng)理信息> 的行即可
      (經(jīng)理:你禮貌嗎?)
    # 自聯(lián)結(jié) SELECT e1.Name AS Employee FROM Employee e1, Employee e2 WHERE e2.ID = e1.ManagerIDAND e2.Salary < e1.Salary;

    182. 查找重復(fù)的電子郵箱

    • 考察數(shù)據(jù)分組、分組篩選(思路見注釋)
    # 先按照 Email 分組,然后找出所有 COUNT > 1 的分組即可 SELECT Email FROM Person GROUP BY Email Having COUNT(ID) > 1;

    183. 從不訂購(gòu)的客戶

    • 考察外聯(lián)結(jié)保持 NULL 值的性質(zhì)
    • 以及 IS NULL 進(jìn)行空值判斷
    SELECT Name AS Customers FROM Customers c LEFT JOIN Orders o ON c.ID = o.CustomerID # 外聯(lián)結(jié),保留 NULL WHERE o.ID IS NULL; # 通過 IS NULL 進(jìn)行篩選

    184. 部門工資最高的員工

    • 第一道 medium 題出現(xiàn)了!
    • 考察了內(nèi)聯(lián)結(jié)、子查詢、分組以及聚合函數(shù),比較全面的題。難點(diǎn)在于理清思路。
    • 關(guān)鍵思路:找出 <部門最高工資 - 部門> 的“鍵值對(duì)”
    # 總體思路:先找到 <部門 - 部門最多工資>,然后再進(jìn)行 部門&&工資 的匹配即可 SELECT d.name AS Department,e.name AS Employee,e.Salary FROMEmployee e, Department d # 兩個(gè)表之間的內(nèi)聯(lián)結(jié),獲取部門名 WHEREe.departmentID = d.IDAND(e.salary, e.departmentID) IN # 這邊需要加上部門ID,限定不同部門的 MAX_salary(SELECT MAX(salary), departmentID FROM Employee GROUP BY DepartmentID); # 通過部門ID進(jìn)行數(shù)據(jù)分組,然后再通過 MAX 選取出分組的 MAX 值

    596. 超過5名學(xué)生的課

    • 雖然是 easy,但是也不錯(cuò)的一道題
    • 關(guān)鍵點(diǎn)在于:學(xué)生在同一門課中不應(yīng)被重復(fù)計(jì)算(可能重修,需要去重)
    • 考察了 DISTINCT 和聚合函數(shù)的結(jié)合使用噢!
    SELECT class FROM courses GROUP BY class # 通過 class 進(jìn)行分組 Having COUNT(DISTINCT student) >= 5; # 通過 DISTINCT 進(jìn)行去重

    620. 有趣的電影

    • 誒,也還不錯(cuò)的一道題
    • 考察了 ORDER BY、DESC 的使用
    SELECT * FROM cinema WHERE description != 'boring' AND id % 2 = 1 ORDER BY rating DESC; # 排序,用到 ORDER BY; 降序,用到 DESC.

    結(jié)尾:
    爆肝了屬于是…沒想到一邊看一邊寫筆記,還是花了一天的時(shí)間才整完這篇博客= =
    sql 語(yǔ)句得好好記得用法呀~

    總結(jié)

    以上是生活随笔為你收集整理的【总结记录】《MySQL必知必会》读后笔记,结合 leetcode 例题理解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。