主頁 > 資料庫 > MySQL必須掌握的技能有哪些?超細長文帶你掌握MySQL【建議收藏】

MySQL必須掌握的技能有哪些?超細長文帶你掌握MySQL【建議收藏】

2021-09-04 08:18:48 資料庫

大家不要只收藏不點贊啊!支持一下吧

目錄

  • 必須要看的前言
  • 1 什么是資料庫、SQL和MySQL?
    • 1.1 資料庫基礎
      • 1.1.1 什么是資料庫
      • 1.1.2 表
      • 1.1.3 列和資料型別
      • 1.1.4 行
      • 1.1.5 主鍵
    • 1.2 什么是SQL
    • 1.3 MySQL簡介
  • 2 排序
  • 3 過濾
    • 3.1 基礎操作
    • 3.2 LIKE 運算子
      • 3.2.1 百分號通配符(%)
      • 3.2.2 下劃線通配符(_)
    • 3.3 正則運算式搜索
      • 3.3.1 空白的元字符
      • 3.3.2 匹配字符類
      • 3.3.3 重復元字符
      • 3.3.4 定位元字符
  • 4 資料處理函式
    • 4.1 字串函式
    • 4.2 日期和時間處理函式
    • 4.3 數值處理函式
  • 5 匯總資料
    • 5.1 聚合函式
    • 5.2 聚集不同值
  • 6 分組資料
    • 6.1 創建分組
    • 6.2 過濾分組
    • 6.3 分組和排序
    • 6.4 SELECT子句順序
  • 7 聯結表
    • 7.1 內部鏈接
    • 7.2 聯結多個表
    • 7.3 創建高級聯結
    • 7.4 外部聯結 OUTER JOIN
    • 7.5 組合查詢 UNION
      • 7.5.1 UNION和UNION ALL的區別
  • 8 插入資料
  • 9 修改資料
  • 10 洗掉資料
  • 11 MySQL引擎型別
  • 12 MySQL特性
  • 13 視圖
    • 13.1 什么是視圖?
    • 13.2 為什么使用視圖?
    • 13.3 使用視圖
  • 14 匯出資料
  • 15 視窗函式
    • 15.1 rank()、dense_rank()和row_number()
    • 15.2 CUME_DIST()和PERCENT_RANK()
    • 15.3 FIRST_VALUE()和LAST_VALUE()
    • 15.4 LAG()和LEAD()
    • 15.5 NTH_VALUE()
    • 15.6 NTILE()

必須要看的前言

收藏本篇文章,意味著你擁有了一份超級完善的MySQL“語言書籍”,本篇博客幾乎涵蓋了所有MySQL知識點,文中也有特別標注了哪些是面試提問熱點或者是應該著重掌握的知識點,你也可以把這篇博客當作一本小“詞典”,遇到遺忘了的知識點也隨時可以查閱,總而言之,希望大家喜歡這篇博客,也更希望這篇博客能給大家帶來幫助,

1 什么是資料庫、SQL和MySQL?

那在了解MySQL之前,我們需要先了解一下什么是SQL,了解SQL之前,先了解資料庫有哪些基礎知識點?

1.1 資料庫基礎

1.1.1 什么是資料庫

🔴 資料庫是一個以某種有組織的方式存盤的資料集合,即保存有組織的資料的容器(通常是一個檔案或一組檔案),

1.1.2 表

🔴 表是一種結構化的檔案,可用來存盤某種特定型別的資料,即某種特定型別資料的結構化清單,

1.1.3 列和資料型別

🔴 列:表中的一個欄位,所有表都是由一個或多個列組成的,

🔴 資料型別:所容許的資料的型別,每個表列都有相應的資料型別,它限制(或容許)該列中存盤的資料,

1.1.4 行

🔴 表中的資料是按行存盤的,所保存的每個記錄存盤在自己的行內,如果將表想象為網格,網格中垂直的列為表列,水平行為表行,

1.1.5 主鍵

🔴 列(或一組列),其值能夠唯一區分表中每個行,

表中每一行都應該有可以唯一標識自己的一列(或一組列),一個顧客表可以使用顧客編號列,而訂單表可以使用訂單ID,雇員表可以使用雇員ID或雇員社會保險號,

主鍵通常定義在表的一列上,但這并不是必需的,也可以一起使用多個列作為主鍵,在使用多列作為主鍵時,上述條件必須應用到構成主鍵的所有列,所有列值的組合必須是唯一的(但單個列的值可以不唯一),

1.2 什么是SQL

🔴 SQL是結構化查詢語言(Structured Query Language)的縮寫,是一種專門用來與資料庫通信的語言,

簡單來講,SQL就是程式員與資料庫聯系的工具,幾乎所有重要的DBMS(資料庫管理系統)都支持SQL,

1.3 MySQL簡介

🔴 MySQL是一種DBMS,也就是一種資料庫軟體,

而且很多的公司和開發人員都喜歡用MySQL,為啥?因為人家是開放源代碼的,免費使用,而且MySQL執行速度很快,且容易安裝和使用,


簡單介紹完這些背景知識后,后面有關如何連接資料庫以及如何用SELECT陳述句進行簡單的檢索操作我就不講了,直接上正菜,


2 排序

🔴 ORDER BY默認使用升序排列(同末尾加ASC),DESC關鍵字只應用到直接位于前面的列名

  • 使用多個列排序,不同的列使用的順序不同
SELECT prod_id, prod_price, prod_name
FROM product
ORDER BY prod_price DESC, prod_name;
  • 使用ORDER BY 和 LIMIT組合獲取最N值
SELECT prod_price
FROM products
ORDER BY prod_price DESC
LIMIT 1;

🔴 LIMIT用法講解:
LIMIT 5 等價于 LIMIT 0, 5, 即查詢(0+1)到(0+5)的資料,也就是1-5的資料,也就是說這里的0是查詢的資料起點的前一位,5是查詢的數量,
LIMIT 2 OFFSET 3 等價于 LIMIT 3 2,即查詢(3+1)到(3+2)的資料,也就是4-5的資料,也就是說這里的3是查詢的資料起點的前一位,2是查詢的數量,

3 過濾

🔴 WHERE 子句可操作內容

運算子說明
=等于
<>不等于
!=不等于
<小于
<=小于等于
>大于
>=大于等于
BETWEEN … AND …指定兩個值之間

3.1 基礎操作

  • 獲取范圍值
SELECT prod_name, prod_price
FROM products
WHERE prod_price BETWEEN 5 AND 10;
  • 空值檢查
SELECT prod_name
FROM products
WHERE prod_price IS NULL
# WHERE IFNULL(prod_price)
  • IN取的合法值由逗號分隔的清單
SELECT prod_name, prod_price
FROM products
WHERE vend_id IN (1002,1003)
ORDER BY prod_name

IN運算子一般比OR運算子速度更快,此外,IN可以包含其他SELECT陳述句,能夠動態簡歷WHERE子句,

AND、OR、NOT這些運算子沒啥好說的,但是要注意,任何時候使用具有AND和OR運算子的WHERE子句,都應該使用圓括號明確地分組運算子,不要過分依賴默認計算次序,即使它確實是你想要的東西也是如此,使用圓括號沒有什么壞處,它能消除歧義,

另外,應盡量避免在 WHERE子句中使用上述運算子合like運算子,否則將引擎放棄使用索引而進行全表掃描,

3.2 LIKE 運算子

🔴 LIKE運算子可以用于模糊搜索時使用,即你不知道完整的資料如何,但你知道部分資訊,就可以用到LIKE,例如,怎樣搜索產品名中包含文本anvil的所有產品?用簡單的比較運算子肯定不行,必須使用通配符,

注意:通配符搜索花費的時間更多;在確定是要通配符時,除非絕對有必要,不要把他們放在搜索模式的開始處,否則搜索起來是最慢的,

3.2.1 百分號通配符(%)

🔴 %表示任何字符出現的任意次數,

  • 以下代碼找出所有以詞per開頭的產品
SELECT prod_id, prod_name
FROM products
WHERE prod_name LIKE 'per%'
  • 同樣,也可以是
WHERE prod_name LIKE '%anvil%'

3.2.2 下劃線通配符(_)

🔴 用處與%一樣,但是只能匹配單個字符,
也就是說%可以匹配0-無窮的字符,但_只能匹配單個字符,

3.3 正則運算式搜索

隨著過濾條件的復雜性的增加,WHERE子句本身的復雜性也有必要增加,這個時候,就需要用到正則運算式了,

正則運算式的作用是匹配文本,將一個模式(正則運算式)與一個文本串進行比較,MySQL用WHERE子句對正則運算式提供了初步的支持,允許你指定正則運算式,過濾SELECT檢索出的資料,

  • 如下代碼所示,如果對應的列中出現了REGEXP后面的字串,則回傳它,
WHERE prod_name REGEXP '1000'

正則字串匹配不區分大小寫,如果需要區分可以使用REGEXP BINARY 'JetPack'

正則運算式中要匹配. -等特殊字符需要加反義字符\\

3.3.1 空白的元字符

元字符含義
\\f換頁
\\n換行
\\r回車
\\t制表
\\v縱向制表

3.3.2 匹配字符類

元字符含義
[:alnum:]任意字母和數字(同[a-zA-Z0-9])
[:alpha:]任意字符(同[a-zA-Z])
[:blank:]空格和制表(同[\\t])
[:cntrl:]ASCII控制字符(ASCII 0到31和127)
[:digit:]任意數字(同[0-9])
[:graph:]與[:print:]相同,但不包括空格
[:lower:]任意小寫字母(同[a-z])
[:print:]任意可列印字符
[:punct:]既不在[:alnum:]又不在[:cntrl:]中的任意字符
[:space:]包括空格在內的任意空白字符(同[\\f \\n \\r \\t \\v])
[:upper:]任意大寫字母(同[A-Z])
[:xdigit:]任意十六進制數字(同[a-fA-F0-9])

3.3.3 重復元字符

元字符含義
*0個或多個匹配
+1個或多個匹配(等于{1,})
?0個或1個匹配(等于{0,1})
{n}指定數目的匹配
{n,}不少于指定數目的匹配
{n,m}匹配數目的范圍(m不超過255)

  • 匹配連在一起的四位數字:
WHERE prod_name REGEXP '[[:digit:]]{4}'
  • 簡單的正則運算式測驗
SELECT 'hello' REGEXP '[0-9]'

正確會回傳1,否則0,

3.3.4 定位元字符

元字符含義
^文本的開始
$文本的結尾
[[:<:]]詞的開始
[[:>:]]詞的結尾

LIKE和REGEXP的不同在于,LIKE匹配整個串而REGEXP匹配子串,利用定位符,通過用^開始每個運算式,用$結束每個運算式,可以使REGEXP的作用與LIKE一樣,

4 資料處理函式

與其他大多數計算機語言一樣,SQL支持利用函式來處理資料,函式一般是在資料上執行的,它給資料的轉換和處理提供了方便,

4.1 字串函式

函式含義
Left()回傳串左邊的字符
Length()回傳串的長度
Locate()找出串的一個子串
Lower()將串轉換為小寫
LTrim()去掉串左邊的空格
Right()回傳串右邊的字符
RTrim()去掉串右邊的空格
SubString()回傳子串的字符
Upper()將串轉換為大寫

4.2 日期和時間處理函式

函式含義
AddDate()增加一個日期(天、周等)
AddTime()增加一個時間(時、分等)
CurDate()回傳當前日期
CurTime()回傳當前時間
Date()回傳日期時間的日期部分
DateDiff()計算兩個日期之差
Date_Add()高度靈活的日期運算函式
Date_Format()回傳一個格式化的日期或時間串
Day()回傳一個日期的天數部分
DayOfWeek()對于一個日期,回傳對應的星期幾
Hour()回傳一個時間的小時部分
Minute()回傳一個時間的分鐘部分
Month()回傳一個日期的月份部分
Now()回傳當前日期和時間
Second()回傳一個時間的秒部分
Time()回傳一個日期時間的時間部分
Year()回傳一個日期的年份部分
  • 如果要的是日期,一定要使用Date()
SELECT cust_id, order_num
FORM orders
WHERE Date(order_date) = '2005-09-01';
  • 檢索一段時間
WHERE Date(order_date) BETWEEN '2005-09-01' AND '2005-09-30';
# WHERE Year(order_date) = 2005 AND Month(order_date) = 9;

4.3 數值處理函式

函式含義
Abs()回傳一個數的絕對值
Cos()回傳一個角度的余弦
Exp()回傳一個數的指數值
Mod()回傳除操作的余數
Pi()回傳圓周率
Rand()回傳一個亂數
Sin()回傳一個角度的正弦
Sqrt()回傳一個數的平方根
Tan()回傳一個角度的正切

5 匯總資料

5.1 聚合函式

函式含義
AVG()回傳某列的平均值
COUNT()回傳某列的行數
MAX()回傳某列的最大值
MIN()回傳某列的最小值
SUM()回傳某列值之和

這里詳細介紹一下COUNT函式,考點來著,

  • 使用COUNT(*)對表中行的數目進行計數,不管包含的是空值還是非空值,如果是統計行數的話建議就用COUNT(*),
  • 使用COUNT(column)對特定列中具有值得行進行計數,忽略NULL,
  • COUNT(1)與COUNT(*)執行結果和效率基本沒差,

5.2 聚集不同值

  • 如果只需要包含不同的值,指定DISTINCT引數,否則ALL會被作為默認,這里看做是去重操作,
SELECT AVG(DISTINCT prod_price) AS avg_price
FROM products
WHERE vend_id = 1003;

6 分組資料

6.1 創建分組

SELECT vend_id, COUNT(*) AS num_prods
FROM products
GROUP BY vend_id

如上代碼中,groupby將會對vend_id進行排序并分組資料,

如果分組列中有NULL值,則NULL會被作為一個分組回傳,如果列中有多行NULl值,他們會被分成一組,

GROUP BY子句必須出現在WHERE之后,ORDER BY之前,

6.2 過濾分組

🔴 HAVING 子句:WHERE過濾行,HAVING過濾分組,同樣可以理解為,WHERE在資料分組前進行過濾,HAVING在資料分組后進行過濾,

SELECT cust_id, COUNT(*) AS orders
FROM orders
GROUP BY cust_id
HAVING COUNT(*) >= 2; 
  • 同時進行WHERE和HAVING
SELECT vend_id, COUNT(*) AS num_prods
FROM products
WHERE prod_price >= 10 --首先限制需要的產品價格是10以上的
GROUP BY vend_id
HAVING COUNT(*) >= 2; --然后限制分組后數量需要大于等于2

6.3 分組和排序

🔴 在使用GROUP BY子句的同時,也應該給出ORDER BY子句,這是保證資料正確排序的唯一方法,

SELECT order_num, SUM(quantity*item_price) AS ordertotal
FROM orderitems
GROUP BY order_num
HAVING SUM(quantity*item_price) >= 50
ORDER BY ordertotal;

6.4 SELECT子句順序

  1. SELECT
  2. FROM
  3. WHERE
  4. GROUP BY
  5. HAVING
  6. ORDER BY
  7. LIMIT

7 聯結表

如果資料存盤在多個表中,怎樣用單條SELECT陳述句檢索出資料?

答案是使用聯結,簡單地說,聯結是一種機制,用來在一條SELECT陳述句中關聯表,因此稱之為聯結,使用特殊的語法,可以聯結多個表回傳一組輸出,聯結在運行時關聯表中正確的行,

7.1 內部鏈接

SELECT vend_name, prod_name, prod_price
FROM vendors INNER JOIN products
  ON vendors.vend_id = products.vend_id;

7.2 聯結多個表

SELECT prod_name, vend_name, prod_price, quantity
FROM orderitems, products, vendors
WHERE products.vend_id = vendors.vend_id
  AND orderitems.prod_id = products.prod_id
  AND order_num = 123;

此種關聯處理是相當耗費資源的,

7.3 創建高級聯結

通過AS關鍵字使用別名,兩點好處:縮短SQL陳述句;允許在單挑SELECT陳述句中多次使用相同的表,

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'

如上代碼中使用兩個相同的表分別作為p1, p2,WHERE中選取p2中產品ID為DTNTR的列,此時p2.vend_id就是DTNTR的生產商;p1.vend_id = p2.vend_id 此時意味在p1選取DTNTR的生產商,

7.4 外部聯結 OUTER JOIN

這個其實也是考點,

SQL中的關聯/查詢的方式一共有4種,分別是INNER JOIN(內連接,INNER可以省略)、LEFT OUTER JOIN(左連接,OUTER可以省略)RIGHT OUTER JOIN(右連接,OUTER可以省略)以及FULL JOIN(全連接),

連接方式含義
INNER JOIN只保留兩張表中完全匹配的結果集,
LEFT JOIN回傳左表所有的行,而右表中沒有匹配的記錄則會表示為null,
RIGHT JOIN回傳右表所有的行,而左表中沒有匹配的記錄則會表示為null,
FULL JOIN在兩張表進行連接查詢時,回傳左表和右表中所有沒有匹配的行,

值得注意的是,MySQL中是不支持全連接的,但我們可以利用左連接和右連接實作全連接,

SELECT * FROM t1
LEFT JOIN t2 ON t1.id = t2.id
UNION
SELECT * FROM t1
RIGHT JOIN t2 ON t1.id = t2.id

7.5 組合查詢 UNION

緊跟上文,UNION是啥嘞?

如果說上述提到的各種連接方式概括為一種形式的話,那就是表與表之間左右連接,而UNION則是上下連接,

UNION的使用很簡單,所需做的只是給出每條SELECT陳述句,在各條陳述句之間放上關鍵字UNION,

在進行并時有幾條規則需要注意,

  • UNION必須由兩潭訓兩條以上的SELECT陳述句組成,陳述句之間用關鍵字UNION分隔(因此,如果組合4條SELECT陳述句,將要使用3個UNION關鍵字),
  • UNION中的每個查詢必須包含相同的列、運算式或聚集函式(不過各個列不需要以相同的次序列出),
  • 列資料型別必須兼容:型別不必完全相同,但必須是DBMS可以隱含地轉換的型別(例如,不同的數值型別或不同的日期型別),

最終生成的表的欄位名會以第一個表的欄位名為準,

7.5.1 UNION和UNION ALL的區別

簡單來講,就是使用UNION會洗掉重復的記錄,而UNION ALL則不會,從效率上看,UNION ALL執行效率高于UNION,如果沒有去重的需求,就選用UNION ALL,

8 插入資料

INSERT INTO Customers
VALUES(1,
	'Paul',
	'USA',
	NULL
);

雖然這種語法很簡單,但并不安全,應該盡量避免使用,上面的SQL陳述句高度依賴于表中列的定義次序,并且還依賴于其次序容易獲得的資訊,即使可得到這種次序資訊,也不能保證下一次表結構變動后各個列保持完全相同的次序,因此,撰寫依賴于特定列次序的SQL陳述句是很不安全的,如果這樣做,有時難免會出問題,

撰寫INSERT陳述句的更安全(不過更煩瑣)的方法如下:

INSERT INTO Customers(customer_id,
	customer_name,
	country,
	email)
VALUES(1,
	'Paul',
	'USA',
	NULL
	),
	(2,
	'Wu',
	'CHINA',
	NULL
);

其優點是,即使表的結構改變,此INSERT陳述句仍然能正確作業,

如何提高整體性能?

資料庫經常被多個客戶訪問,對處理什么請求以及用什么次序處理進行管理是MySQL的任務,INSERT操作可能很耗時(特別是有很多索引需要更新時),而且它可能降低等待處理的SELECT陳述句的性能,

如果資料檢索是最重要的(通常是這樣),則你可以通過在
INSERT和INTO之間添加關鍵字LOW_PRIORITY,指示MySQL
降低INSERT陳述句的優先級,如下所示:

INSERT LOW_PRIORITY INTO

順便說一下,這也適用于下一章介紹的UPDATE和DELETE陳述句,

9 修改資料

UPDATE customers
SET cust_email = 'elmer@fudd.com'
WHERE cust_id = 10005;

10 洗掉資料

🔴 DELETE陳述句從表中洗掉行,甚至是洗掉表中所有行,但是,DELETE不洗掉表本身,

DELETE FROM customers
WHERE cust_id = 10005;

如果想從表中洗掉所有行,不要使用DELETE,可使用TRUNCATE TABLE陳述句,它完成相同的作業,但速度更快(TRUNCATE實際是洗掉原來的表并重新創建一個表,而不是逐行洗掉表中的資料),

11 MySQL引擎型別

MySQL與其他DBMS不一樣,它具有多種引擎,它打包多個引擎,這些引擎都隱藏在MySQL服務器內,全都能執行CREATE TABLE和SELECT等命令,

為什么要發行多種引擎呢?因為它們具有各自不同的功能和特性,
為不同的任務選擇正確的引擎能獲得良好的功能和靈活性,

以下是幾個需要知道的引擎:

  • InnoDB是一個可靠的事務處理引擎,它不支持全文本搜索;
  • MEMORY在功能等同于MyISAM,但由于資料存盤在記憶體(不是磁盤)中,速度很快(特別適合于臨時表);
  • MyISAM是一個性能極高的引擎(往往是默認引擎),它支持全文本搜索,但不支持事務處理,

12 MySQL特性

特性含義
原子性一個事務中的所有操作,要么全部完成,要么全部不完成,如果事務程序中發生錯誤,會被回滾到開始的狀態,
一致性事務執行前后,資料庫的完整性沒有被破壞,這意味著寫入的所有資訊都要符合預設的規則,
隔離性資料庫允許多個并發事務同時進行讀寫和修改,隔離性可以放置多個事務并發執行時由于交叉執行導致資料不一致,
持久性事務處理結束后,對資料的修改是永久的,即使系統故障也不會丟失,

13 視圖

13.1 什么是視圖?

🔴 視圖是虛擬的表,與包含資料的表不一樣,視圖只包含使用時動態檢索資料的查詢,

來看一個例子:

SELECT cust_name, cust_contact
FROM customers, orders, orderitems
WHERE customers.cust_id = orders.cust_id 
	AND orderitems.order_num = orders.order_num 
	AND prod_id = 'TNT2'

此查詢用來檢索訂購了某個特定產品的客戶,任何需要這個資料的
人都必須理解相關表的結構,并且知道如何創建查詢和對表進行聯結,為了檢索其他產品(或多個產品)的相同資料,必須修改最后的WHERE子句,

現在,假如可以把整個查詢包裝成一個名為productcustomers的虛
擬表,則可以如下輕松地檢索出相同的資料:

SELECT cust_name, cust_contact
FROM productcustomers
WHERE prod_id = 'TNT2'

這就是視圖的作用,productcustomers是一個視圖,作為視圖,它
不包含表中應該有的任何列或資料,它包含的是一個SQL查詢(與上面用
以正確聯結表的相同的查詢),

13.2 為什么使用視圖?

  • 重用SQL陳述句,
  • 簡化復雜的SQL操作,在撰寫查詢后,可以方便地重用它而不必
    知道它的基本查詢細節,
  • 使用表的組成部分而不是整個表,
  • 保護資料,可以給用戶授予表的特定部分的訪問權限而不是整個
    表的訪問權限,
  • 更改資料格式和表示,視圖可回傳與底層表的表示和格式不同的
    資料,

13.3 使用視圖

  • 視圖不包含表中應該有的任何列或資料,只包含一個SQL查詢,
  • 視圖使用CREATE VIEW陳述句來創建,
  • SHOW CREATE VIEW viewname; 來查看創建視圖的陳述句,
  • CREATE OR REPLACE VIEW來更新視圖,
CREATE VIEW productcustomers AS
SELECT cust_name, cust_contact, prod_id
FROM customers, orders, orderitems
WHERE customers.cust_id = orders.cust_id
  AND orderitems.order_num = orders.order_num
  • 以上視圖聯結了三個表,回傳了已經訂購任意產品的所有客戶的串列,
SELECT cust_name, cust_contact
FROM productcustomers
WHERE prod_id = 'TNT2';
  • 或者也可以使用視圖來重新格式化出檢索出來的資料,
CREATE VIEW vendorlocations AS
SELECT Concat(RTrim(vend_name), '(',RTrim(vend_country),')')
       AS vend_title
FROM vendors
ORDER BY vend_name

14 匯出資料

代碼如下:

SELECT * FROM customers
INTO OUTFILE 'customers.txt'
FIELDS TERMINATED BY ',' ENCLOSED BY ''''
LINES TERMINATED BY '\r\n';

15 視窗函式

這個就是面試時的高頻考點啦,

以下資料來源begtut,

🔴 視窗函式的視窗表示范圍,可以理解為將原資料劃分范圍,也就是分組,然后用函式實作某些目的,相比于GROUP BY , 視窗函式不會減少原來的行數

  • 語法: SELECT 視窗函式 OVER (PARTITION BY 用于分組的列名 ORDER BY 用于排序的列)
  • 專用視窗函式:rank(), dense_rank(), row_numer()

當然啦,那些聚合函式在這里要用也可以用,

SELECT *,
	rank() over (PARTITION BY class_id ORDER BY SCORE DESC ) AS ranking
FROM class

15.1 rank()、dense_rank()和row_number()

三個函式的主要區別是如何處理并列情況:

  • rank()中的并列情況會占用下一個名詞的位置, 1,1,1,4
  • dense_rank() 不會占用下一個名詞 1,1,1,2
  • row_number()中,會忽略并列的情況, 1,2,3,4

15.2 CUME_DIST()和PERCENT_RANK()

🔴 CUME_DIST()是一個視窗函式,它回傳一組值中值的累積分布,它表示值小于或等于行的值除以總行數的行數,重復的列值接收相同的CUME_DIST()值,計算的時候,取重復值的最后一行的位置

SELECT name,
    score,
    ROW_NUMBER() OVER (ORDER BY score) row_num,
    CUME_DIST() OVER (ORDER BY score) cume_dist_val
FROM scores; 

輸出結果:

namescorerow_numcume_dist_val
Jones5510.2
Williams5520.2
Brown6230.4
Taylor6240.4
Thomas7250.6
Wilson7260.6
Smith8170.7
Davies8480.8
Evans8790.9
Johnson100101

🔴 PERCENT_RANK()和CUME_DIST()一樣,是計算某個值在一組有序的資料中累計的分布,但不同在于計算分布結果的方法:(rank - 1) / (total_rows - 1),在此公式中,rank是指定行的等級,total_rows是要計算的行數,復的列值接收相同的CUME_DIST()值,計算的時候,取重復值的第一行的位,具體如下:

SELECT name,
    score,
    ROW_NUMBER() OVER (ORDER BY score) row_num,
    PERCENT_RANK() OVER (ORDER BY score) cume_dist_val
FROM scores; 

輸出結果:

namescorerow_numpercent_rank_val
Jones5510.2
Williams5520.2
Brown6230.4
Taylor6240.4
Thomas7250.6
Wilson7260.6
Smith8170.7
Davies8480.8
Evans8790.9
Johnson100101

15.3 FIRST_VALUE()和LAST_VALUE()

🔴 FIRST_VALUE()是一個視窗函式,允許您選擇視窗框架,磁區或結果集的第一行,

SELECT employee_name,
    hours,
    FIRST_VALUE(employee_name) OVER (
        ORDER BY hours
    ) least_over_time
FROM overtime; 

輸出結果:

employee_namehoursleast_over_time
Steve Patterson29Steve Patterson
Diane Murphy37Steve Patterson
Jeff Firrelli40Steve Patterson
Gerard Bondur47Steve Patterson
Loui Bondur49Steve Patterson
William Patterson58Steve Patterson

在此示例中,ORDER BY子句按結果集對行中的行進行了按小時排序,并FIRST_VALUE()選擇了第一行,表示加班時間最短的員工,

如果反過來想取加班時間最長的員工,則將FIRST_VALUE()改成LAST_VALUE()

15.4 LAG()和LEAD()

🔴 LAG()函式:從同一結果集中的當前行訪問上n行的資料,

語法:LAG(param1, param2, param3)

  • param1 欄位名
  • param2 前面第幾行
  • param3 當前面第幾行沒有值時范圍的值,沒有設定的話就自動回傳NULL,
WITH productline_sales AS (
    SELECT productline,
           YEAR(orderDate) order_year,
           ROUND(SUM(quantityOrdered * priceEach),0) order_value
    FROM orders
    INNER JOIN orderdetails USING (orderNumber)
    INNER JOIN products USING (productCode)
    GROUP BY productline, order_year
)
SELECT productline, 
    order_year, 
    order_value,
    LAG(order_value, 1) OVER (
        PARTITION BY productLine
        ORDER BY order_year
    ) prev_year_order_value
FROM productline_sales; 

輸出結果:

productlineorder_yearorder_valueprev_year_order_value
Classic Cars20131374832NULL
Classic Cars201417631371374832
Classic Cars20157159541763137
Motorcycles2013348909NULL
Motorcycles2014527244348909
Motorcycles2015245273527244

🔴 LEAD()函式:從同一結果集中的當前行訪問后n行的資料,

將上述代碼中的LAG函式改為LEAD函式,

此時的輸出結果:

productlineorder_yearorder_valueprev_year_order_value
Classic Cars201313748321763137
Classic Cars20141763137715954
Classic Cars2015715954NULL
Motorcycles2013348909527244
Motorcycles2014527244245273
Motorcycles2015245273NULL

15.5 NTH_VALUE()

🔴 NTH_VALUE()是一個視窗函式,允許您從有序行集中的第N行獲取值,

SELECT employee_name,
    salary,
    NTH_VALUE(employee_name, 2) OVER  (
        ORDER BY salary DESC
    ) second_highest_salary
FROM basic_pays; 

輸出結果:

employee_namesalarysecond_highest_salary
Larry Bott11798NULL
Gerard Bondur11472Gerard Bondur
Pamela Castillo11303Gerard Bondur
Barry Jones10586Gerard Bondur
George Vanauf10563Gerard Bondur

15.6 NTILE()

🔴 NTILE()函式將排序磁區中的行劃分為特定數量的組,從每個組分配一個從一開始的桶號,對于每一行,NTILE()函式回傳一個桶號,表示行所屬的組,

SELECT val, 
    NTILE(4) OVER (
        ORDER BY val
    ) group_no
FROM ntileDemo;

輸出結果:

valgroup_no
11
21
31
42
52
63
73
84
94

從輸出中可以看出,第一組有三行,而其他組有兩行,
也就是說,如果不平均,余n個資料,那排在前n的組就會各多一個,


學習更多資料分析技能和掌握實戰專案,可以關注我的資料分析專欄,

CSDN@報告,今天也有好好學習

轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/297364.html

標籤:其他

上一篇:Redis+Nginx+設計模式+Spring全家桶+SQL+Dubbo技術好文精選整理

下一篇:博客反抄襲作業的一些思考和嘗試

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • GPU虛擬機創建時間深度優化

    **?桔妹導讀:**GPU虛擬機實體創建速度慢是公有云面臨的普遍問題,由于通常情況下創建虛擬機屬于低頻操作而未引起業界的重視,實際生產中還是存在對GPU實體創建時間有苛刻要求的業務場景。本文將介紹滴滴云在解決該問題時的思路、方法、并展示最終的優化成果。 從公有云服務商那里購買過虛擬主機的資深用戶,一 ......

    uj5u.com 2020-09-10 06:09:13 more
  • 可編程網卡芯片在滴滴云網路的應用實踐

    **?桔妹導讀:**隨著云規模不斷擴大以及業務層面對延遲、帶寬的要求越來越高,采用DPDK 加速網路報文處理的方式在橫向縱向擴展都出現了局限性。可編程芯片成為業界熱點。本文主要講述了可編程網卡芯片在滴滴云網路中的應用實踐,遇到的問題、帶來的收益以及開源社區貢獻。 #1. 資料中心面臨的問題 隨著滴滴 ......

    uj5u.com 2020-09-10 06:10:21 more
  • 滴滴資料通道服務演進之路

    **?桔妹導讀:**滴滴資料通道引擎承載著全公司的資料同步,為下游實時和離線場景提供了必不可少的源資料。隨著任務量的不斷增加,資料通道的整體架構也隨之發生改變。本文介紹了滴滴資料通道的發展歷程,遇到的問題以及今后的規劃。 #1. 背景 資料,對于任何一家互聯網公司來說都是非常重要的資產,公司的大資料 ......

    uj5u.com 2020-09-10 06:11:05 more
  • 滴滴AI Labs斬獲國際機器翻譯大賽中譯英方向世界第三

    **桔妹導讀:**深耕人工智能領域,致力于探索AI讓出行更美好的滴滴AI Labs再次斬獲國際大獎,這次獲獎的專案是什么呢?一起來看看詳細報道吧! 近日,由國際計算語言學協會ACL(The Association for Computational Linguistics)舉辦的世界最具影響力的機器 ......

    uj5u.com 2020-09-10 06:11:29 more
  • MPP (Massively Parallel Processing)大規模并行處理

    1、什么是mpp? MPP (Massively Parallel Processing),即大規模并行處理,在資料庫非共享集群中,每個節點都有獨立的磁盤存盤系統和記憶體系統,業務資料根據資料庫模型和應用特點劃分到各個節點上,每臺資料節點通過專用網路或者商業通用網路互相連接,彼此協同計算,作為整體提供 ......

    uj5u.com 2020-09-10 06:11:41 more
  • 滴滴資料倉庫指標體系建設實踐

    **桔妹導讀:**指標體系是什么?如何使用OSM模型和AARRR模型搭建指標體系?如何統一流程、規范化、工具化管理指標體系?本文會對建設的方法論結合滴滴資料指標體系建設實踐進行解答分析。 #1. 什么是指標體系 ##1.1 指標體系定義 指標體系是將零散單點的具有相互聯系的指標,系統化的組織起來,通 ......

    uj5u.com 2020-09-10 06:12:52 more
  • 單表千萬行資料庫 LIKE 搜索優化手記

    我們經常在資料庫中使用 LIKE 運算子來完成對資料的模糊搜索,LIKE 運算子用于在 WHERE 子句中搜索列中的指定模式。 如果需要查找客戶表中所有姓氏是“張”的資料,可以使用下面的 SQL 陳述句: SELECT * FROM Customer WHERE Name LIKE '張%' 如果需要 ......

    uj5u.com 2020-09-10 06:13:25 more
  • 滴滴Ceph分布式存盤系統優化之鎖優化

    **桔妹導讀:**Ceph是國際知名的開源分布式存盤系統,在工業界和學術界都有著重要的影響。Ceph的架構和演算法設計發表在國際系統領域頂級會議OSDI、SOSP、SC等上。Ceph社區得到Red Hat、SUSE、Intel等大公司的大力支持。Ceph是國際云計算領域應用最廣泛的開源分布式存盤系統, ......

    uj5u.com 2020-09-10 06:14:51 more
  • es~通過ElasticsearchTemplate進行聚合~嵌套聚合

    之前寫過《es~通過ElasticsearchTemplate進行聚合操作》的文章,這一次主要寫一個嵌套的聚合,例如先對sex集合,再對desc聚合,最后再對age求和,共三層嵌套。 Aggregations的部分特性類似于SQL語言中的group by,avg,sum等函式,Aggregation ......

    uj5u.com 2020-09-10 06:14:59 more
  • 爬蟲日志監控 -- Elastc Stack(ELK)部署

    傻瓜式部署,只需替換IP與用戶 導讀: 現ELK四大組件分別為:Elasticsearch(核心)、logstash(處理)、filebeat(采集)、kibana(可視化) 下載均在https://www.elastic.co/cn/downloads/下tar包,各組件版本最好一致,配合fdm會 ......

    uj5u.com 2020-09-10 06:15:05 more
最新发布
  • day02-2-商鋪查詢快取

    功能02-商鋪查詢快取 3.商鋪詳情快取查詢 3.1什么是快取? 快取就是資料交換的緩沖區(稱作Cache),是存盤資料的臨時地方,一般讀寫性能較高。 快取的作用: 降低后端負載 提高讀寫效率,降低回應時間 快取的成本: 資料一致性成本 代碼維護成本 運維成本 3.2需求說明 如下,當我們點擊商店詳 ......

    uj5u.com 2023-04-20 08:33:24 more
  • MySQL中binlog備份腳本分享

    關于MySQL的二進制日志(binlog),我們都知道二進制日志(binlog)非常重要,尤其當你需要point to point災難恢復的時侯,所以我們要對其進行備份。關于二進制日志(binlog)的備份,可以基于flush logs方式先切換binlog,然后拷貝&壓縮到到遠程服務器或本地服務器 ......

    uj5u.com 2023-04-20 08:28:06 more
  • day02-短信登錄

    功能實作02 2.功能01-短信登錄 2.1基于Session實作登錄 2.1.1思路分析 2.1.2代碼實作 2.1.2.1發送短信驗證碼 發送短信驗證碼: 發送驗證碼的介面為:http://127.0.0.1:8080/api/user/code?phone=xxxxx<手機號> 請求方式:PO ......

    uj5u.com 2023-04-20 08:27:27 more
  • 快取與資料庫雙寫一致性幾種策略分析

    本文將對幾種快取與資料庫保證資料一致性的使用方式進行分析。為保證高并發性能,以下分析場景不考慮執行的原子性及加鎖等強一致性要求的場景,僅追求最終一致性。 ......

    uj5u.com 2023-04-20 08:26:48 more
  • sql陳述句優化

    問題查找及措施 問題查找 需要找到具體的代碼,對其進行一對一優化,而非一直把關注點放在服務器和sql平臺 降低簡化每個事務中處理的問題,盡量不要讓一個事務拖太長的時間 例如檔案上傳時,應將檔案上傳這一步放在事務外面 微軟建議 4.啟動sql定時執行計劃 怎么啟動sqlserver代理服務-百度經驗 ......

    uj5u.com 2023-04-20 08:26:35 more
  • 云時代,MySQL到ClickHouse資料同步產品對比推薦

    ClickHouse 在執行分析查詢時的速度優勢很好的彌補了MySQL的不足,但是對于很多開發者和DBA來說,如何將MySQL穩定、高效、簡單的同步到 ClickHouse 卻很困難。本文對比了 NineData、MaterializeMySQL(ClickHouse自帶)、Bifrost 三款產品... ......

    uj5u.com 2023-04-20 08:26:29 more
  • sql陳述句優化

    問題查找及措施 問題查找 需要找到具體的代碼,對其進行一對一優化,而非一直把關注點放在服務器和sql平臺 降低簡化每個事務中處理的問題,盡量不要讓一個事務拖太長的時間 例如檔案上傳時,應將檔案上傳這一步放在事務外面 微軟建議 4.啟動sql定時執行計劃 怎么啟動sqlserver代理服務-百度經驗 ......

    uj5u.com 2023-04-20 08:25:13 more
  • Redis 報”OutOfDirectMemoryError“(堆外記憶體溢位)

    Redis 報錯“OutOfDirectMemoryError(堆外記憶體溢位) ”問題如下: 一、報錯資訊: 使用 Redis 的業務介面 ,產生 OutOfDirectMemoryError(堆外記憶體溢位),如圖: 格式化后的報錯資訊: { "timestamp": "2023-04-17 22: ......

    uj5u.com 2023-04-20 08:24:54 more
  • day02-2-商鋪查詢快取

    功能02-商鋪查詢快取 3.商鋪詳情快取查詢 3.1什么是快取? 快取就是資料交換的緩沖區(稱作Cache),是存盤資料的臨時地方,一般讀寫性能較高。 快取的作用: 降低后端負載 提高讀寫效率,降低回應時間 快取的成本: 資料一致性成本 代碼維護成本 運維成本 3.2需求說明 如下,當我們點擊商店詳 ......

    uj5u.com 2023-04-20 08:24:03 more
  • day02-短信登錄

    功能實作02 2.功能01-短信登錄 2.1基于Session實作登錄 2.1.1思路分析 2.1.2代碼實作 2.1.2.1發送短信驗證碼 發送短信驗證碼: 發送驗證碼的介面為:http://127.0.0.1:8080/api/user/code?phone=xxxxx<手機號> 請求方式:PO ......

    uj5u.com 2023-04-20 08:23:11 more