成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

從 LeetCode 的題目再看 MySQL Explain

數(shù)據(jù)庫(kù) MySQL
今天阿粉主要是想通過(guò) LeetCode 上面的一個(gè)題目來(lái)再帶大家看看 MySQL 的變量使用以及通過(guò) Explain 的解析看看SQL 的執(zhí)行過(guò)程。

[[376540]]

本文轉(zhuǎn)載自微信公眾號(hào)「Java極客技術(shù)」,作者鴨血粉絲 。轉(zhuǎn)載本文請(qǐng)聯(lián)系Java極客技術(shù)公眾號(hào)。  

今天阿粉主要是想通過(guò) LeetCode 上面的一個(gè)題目來(lái)再帶大家看看 MySQL 的變量使用以及通過(guò) Explain 的解析看看SQL 的執(zhí)行過(guò)程。雖然平時(shí)在工作中對(duì)于 MySQL 使用的很多,但是相對(duì)于 MySQL 的變量使用相對(duì)還是較少的,所以阿粉在剛看到的時(shí)候還是有點(diǎn)懵的,不過(guò)我相信大家肯定不會(huì)像阿粉一樣,畢竟能關(guān)注我們公眾號(hào)的讀者都是優(yōu)秀的。

題目

題目描述:編寫一個(gè) SQL 查詢,查找所有至少連續(xù)出現(xiàn)三次的數(shù)字。并且給了一個(gè)示例,阿粉按照題目給的示例在本地創(chuàng)建了 Logs 表和插入相應(yīng)的數(shù)據(jù),如下:

我們可以看到在給定上面的 Logs 表中, 1 是唯一連續(xù)出現(xiàn)至少三次的數(shù)字,所以最后輸出的結(jié)果是 1。

原始題目:LeetCode 180

剛看到題目的時(shí)候,阿粉一瞬間還是沒(méi)反應(yīng)過(guò)來(lái),不知道該如何著手進(jìn)行,思索了一下考慮是否可以用自連接來(lái)實(shí)現(xiàn)呢?然后根據(jù)題目的意思就寫出了如下的 SQL。

  1. SELECT DISTINCT 
  2.  l1.num  
  3. FROM 
  4.  `Logs` l1, 
  5.  `Logs` l2, 
  6.  `Logs` l3  
  7. WHERE 
  8.  l1.num = l2.num  
  9.  AND l2.num = l3.num  
  10.  AND l1.id = l2.id - 1  
  11.  AND l2.id = l3.id - 1 

寫完過(guò)后阿粉第一次提交,提示下面錯(cuò)誤,可以看到是最后沒(méi)有將返回重命名,調(diào)整了一下 SQL,就l1.num 改成l1.num as ConsecutiveNums 再次提交,得到的第二張通過(guò)的圖。

看開(kāi)始看到通過(guò),阿粉還在想這道題也沒(méi)什么啊,還是 so easy 的嘛。但是突然阿粉轉(zhuǎn)念一想,這個(gè)題目說(shuō)的是連續(xù)出現(xiàn),并沒(méi)有說(shuō) ID 是連續(xù)的啊,如果 ID 不連續(xù)的話,這種就不對(duì)了,還有就是如果需要連續(xù) 4 次出現(xiàn)的,5 次出現(xiàn)的數(shù)字呢?總不能一直自連接下去吧。如果寫成這樣那整個(gè) SQL 就太不靈活了。

隨后阿粉就看了一下官方解答以及相關(guān)評(píng)論,果不其然雖然官方給出的解答跟阿粉的一致,但是下面的評(píng)論卻有很多小伙伴都在說(shuō)這個(gè) ID 不連續(xù)的問(wèn)題。

既然反饋這種做法有問(wèn)題,那自然就會(huì)有好事之者會(huì)想到解決辦法,果然評(píng)論區(qū)的一個(gè)大佬給出了下面的這種解法

剛看到這個(gè)解法的時(shí)候,阿粉一下子沒(méi)有看懂,把這個(gè)代碼進(jìn)行了提交,果然也是正常的通過(guò)了。而且這種解法不會(huì)被出現(xiàn)幾次的條件給限制。抱著學(xué)習(xí)的心態(tài),阿粉準(zhǔn)備研究一下這條 SQL 里面的內(nèi)容。

SQL 拆解

首先這條 SQL 里面有這么幾個(gè)地方讓阿粉迷惑,第一個(gè)是@ 符號(hào),然后是:= 然后還有個(gè) case when then 語(yǔ)法,平日里在 CRUD 的時(shí)候沒(méi)遇到過(guò)這種寫法,不過(guò)不知道沒(méi)關(guān)系,Google 一下就好了。網(wǎng)上查了下,@prev 表示的是聲明變量,:=操作是 MySQL 的賦值操作,case when then when 后面接的是判斷條件,條件成立則會(huì)返回then 后面的結(jié)果,需要注意的是 case 只會(huì)返回第一個(gè)符合條件的結(jié)果,剩下將會(huì)被忽略。

簡(jiǎn)單的了解了上面幾個(gè)知識(shí)點(diǎn)過(guò)后,我們就可以對(duì)下面這條 SQL 進(jìn)行拆解了。

  1. select distinct Num as ConsecutiveNums 
  2. from ( 
  3.   select Num,  
  4.     case  
  5.       when @currnet = Num then @count := @count + 1 
  6.       when (@currnet := Num) is not null then @count := 1 
  7.     end as CNT 
  8.   from Logs, (select @currnet := null,@count := 0) as t 
  9. as temp 
  10. where temp.CNT >= 3 
  1. 最外層的 select distinct Num as ConsecutiveNums from () as temp where temp.CNT >= 3 ; 我們可以看到中間的小括號(hào)里面被派生成了一個(gè)臨時(shí)表,表名叫做 temp,并且 temp 表中有兩個(gè)字段分別是Num,CNT。其實(shí)Num 則是表Logs 里面的數(shù)字,CNT 則是連續(xù)出現(xiàn)的累積次數(shù),最后的where temp.CNT >= 3 則是在根據(jù)要求連續(xù)出現(xiàn)的次數(shù)進(jìn)行查詢。
  2. 派生語(yǔ)句SELECT Num,CASE WHEN @currnet=Num THEN @count:=@count+1 WHEN (@currnet:=Num) IS NOT NULL THEN @count:=1 END AS CNT FROM LOGS,(SELECT @currnet:=NULL,@count:=NULL) AS t 包含兩個(gè)部分,一個(gè)是Select 中的case when then 另一個(gè)是from 中的 (select @currnet:= null,@count := null) as t 其中select @currnet:= null,@count := null 也是一個(gè)派生表,這里通過(guò)聲明兩個(gè)變量@currnet, @count 并賦值為null 。
  3. 中間派生的表 temp 的內(nèi)容如下,通過(guò)生成記錄每個(gè)數(shù)字出現(xiàn)的次數(shù)的臨時(shí)表來(lái)查詢數(shù)據(jù)。

下面我們通過(guò)explain 命令看下整個(gè) SQL 的執(zhí)行過(guò)程,:

  • 從select_type中我們可以看到總共派生了兩個(gè)表,跟我們上面分析的一致;
  • ID 為 3 的派生表的內(nèi)容是select @current := null,@count := 0 定義兩個(gè)變量并賦值,并且 id 越大越先執(zhí)行;
  • case 語(yǔ)句中第一個(gè)when 中判斷當(dāng)前掃描到的 num 值與定義的變量是否一致,如果一致則 count 加一,不一致則進(jìn)行下一個(gè)when 條件判斷,并將count 賦值為 1 返回;
  • 經(jīng)過(guò)全表掃描過(guò)后,就得到了上面的中間表 temp 的內(nèi)容;

不得不說(shuō),上面的方案是很完美的,不存在 ID 是否連續(xù)的問(wèn)題,也不會(huì)多層自連接,而且也可以根據(jù)要求找出連續(xù)出現(xiàn)的次數(shù),相對(duì)靈活。剛開(kāi)始看到這個(gè) SQL 的時(shí)候,阿粉并不清楚整個(gè)執(zhí)行的過(guò)程,然后通過(guò) explain 才漸漸明白整個(gè)執(zhí)行過(guò)程, 而且對(duì)于在 SQL 中使用變量也有了一定的了解。

 

責(zé)任編輯:武曉燕 來(lái)源: Java極客技術(shù)
相關(guān)推薦

2010-10-12 13:55:41

MySQL EXPLA

2017-07-27 20:00:47

MySQLEXPLAIN命令

2014-02-04 07:59:27

2011-08-18 11:31:06

MySQL性能分析explain

2025-02-18 12:50:00

MySQL命令數(shù)據(jù)庫(kù)

2017-04-07 14:30:26

2025-02-19 07:49:36

2010-05-21 16:55:47

MySQL EXPLA

2024-12-11 13:14:27

2023-09-21 10:55:51

MysqlSQL語(yǔ)句

2009-12-10 16:12:07

EXPLAIN

2011-04-19 12:32:41

2021-03-01 08:20:06

AndroidFileProvideContentProv

2022-02-15 07:36:21

SQLEXPLAIN數(shù)據(jù)庫(kù)

2024-09-12 15:16:14

2010-05-19 10:37:06

MySQL expla

2023-09-05 07:29:01

2020-10-19 19:45:58

MySQL數(shù)據(jù)庫(kù)優(yōu)化

2019-07-16 11:06:09

TCP四次揮手半關(guān)閉

2019-09-17 15:13:05

MySQLEXPLAIN數(shù)據(jù)庫(kù)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 欧美一区二区在线播放 | 黄网址在线观看 | 综合久久综合久久 | 欧美日韩国产一区二区三区 | 一区二区三区视频在线观看 | 午夜久久久久久久久久一区二区 | 欧美伊人影院 | av二区三区 | 亚洲一区二区三区 | 精品乱码一区二区三四区视频 | 久久在线免费 | 欧美激情国产日韩精品一区18 | 91精品国产一区二区三区动漫 | 日韩激情免费 | 国产一二三区在线 | 国产盗摄视频 | 围产精品久久久久久久 | 日本精品久久久久久久 | 日一区二区 | 九九热精品视频 | 91久久久久久久久久久久久 | 国产成人精品一区二区三区四区 | 日韩精品久久久 | 国产一区二区三区免费视频 | 最新免费黄色网址 | 成人av一区| 免费网站国产 | www.成人免费视频 | 久久久精品一区 | 国产精品资源在线观看 | 亚洲综合视频 | 国产99久久 | 亚洲风情在线观看 | 久久精品网 | 在线观看免费av网站 | 久久精品国产久精国产 | 久久久久久久久毛片 | 97碰碰碰| 国产精品久久久亚洲 | 成年人视频在线免费观看 | 国产精品美女久久久久久免费 |