溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

MySQL中邏輯查詢的示例分析

發(fā)布時間:2021-09-18 09:53:13 來源:億速云 閱讀:106 作者:小新 欄目:MySQL數(shù)據(jù)庫

這篇文章主要介紹了MySQL中邏輯查詢的示例分析,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

在MySQL中,查詢是用于構(gòu)建DELETE、UPDATE的基礎(chǔ),因?yàn)槟阋獎h除或者更新他們時,首先就是要查出這些記錄,所以SELECT顯的尤為重要,對于查詢處理,可以分為邏輯查詢和物理查詢,邏輯查詢表示執(zhí)行SELECT語句時應(yīng)該產(chǎn)生什么樣的結(jié)果,而物理查詢表示MySQL如何得到這個結(jié)果的。

本章來說一下邏輯查詢。

在SQL語句中,最先處理的就是FROM語句,最后執(zhí)行的是LIMIT語句,如果把所有的語句都用上,如GROUP BY、ORDER BY,那么大致可以分為10個步驟,如下所示,每個操作都會產(chǎn)生一張?zhí)摂M表。

(7) select (8)distinct<select_list>

(1) from <left table>
(3) <join_type> join <right_table>
(2)    on<條件>
(4) where <條件>
(5) group by<字段list>
(6) having<條件>
(9) order by<字段>
(10) limit

下面通過一個實(shí)際例子來分析一下,首先創(chuàng)建兩張表,用戶和訂單。

mysql> create table user (userId int(11),userName varchar(255),city varchar(255), primary key (userId));
Query OK, 0 rows affected, 1 warning (0.05 sec)


mysql> create table orders(orderId int(11) ,userId int(11) ,primary key (orderId));
Query OK, 0 rows affected, 2 warnings (0.05 sec)

插入數(shù)據(jù)。

insert user values(1,"張三","內(nèi)蒙");
insert user values(2,"李四","內(nèi)蒙");
insert user values(3,"王五","北京");
insert user values(4,"迪迦","西藏");
insert user values(5,"金甲戰(zhàn)士","內(nèi)蒙");

insert orders values(10001,1);
insert orders values(10002,1);
insert orders values(10003,4);
insert orders values(10004,1);
insert orders values(10005,1);
insert orders values(10006,4);
insert orders values(10007,2);

好,現(xiàn)在來查詢一下來自內(nèi)蒙,且訂單數(shù)量小于3的用戶,SQL如下。

mysql> select userName,count(orders.orderId) as total from user 
left join orders on user.userId = orders.userId 
where city="內(nèi)蒙" 
group by user.userId 
having count(orders.orderId)<3 
order by total desc;
+--------------+-------+
| userName     | total |
+--------------+-------+
| 李四         |     1 |
| 金甲戰(zhàn)士     |     0 |
+--------------+-------+
2 rows in set (0.00 sec)

有數(shù)據(jù)有SQL,下面分析一下具體流程。

1. 笛卡爾乘積

首先要做的是對FROM語句前后的兩張表進(jìn)行笛卡爾乘積,那么什么是笛卡爾乘積?舉個例子來說,假設(shè)集合A={a, b},集合B={0, 1, 2},則兩個集合的笛卡爾積為{(a, 0), (a, 1), (a, 2), (b, 0), (b, 1), (b, 2)}。

所以,對應(yīng)上面的數(shù)據(jù),最終會產(chǎn)生一張?zhí)摂M表VT1,他將包含35行數(shù)據(jù),具體數(shù)據(jù)如下所示。

userIduserNamecityorderIduserId
1張三內(nèi)蒙100011
1張三內(nèi)蒙100021
1張三內(nèi)蒙100034
1張三內(nèi)蒙100051
1張三內(nèi)蒙100061
1張三內(nèi)蒙100054
1張三內(nèi)蒙100072
..................



5金甲戰(zhàn)士內(nèi)蒙100011
5金甲戰(zhàn)士內(nèi)蒙100021

2. ON過濾器

下一步,通過ON后面的添加過濾掉不需要的數(shù)據(jù),在上述SQL中,條件是user.userId = orders.userId ,所以通過上面生成的虛擬表VT1,除去不相關(guān)的數(shù)據(jù),生成新的虛擬表VT2,最終的結(jié)果如下。

+--------+--------------+--------+---------+--------+
| userId | userName     | city   | orderId | userId |
+--------+--------------+--------+---------+--------+
|      1 | 張三         | 內(nèi)蒙   |   10005 |      1 |
|      1 | 張三         | 內(nèi)蒙   |   10004 |      1 |
|      1 | 張三         | 內(nèi)蒙   |   10002 |      1 |
|      1 | 張三         | 內(nèi)蒙   |   10001 |      1 |
|      2 | 李四         | 內(nèi)蒙   |   10007 |      2 |
|      3 | 王五         | 北京   |    NULL |   NULL |
|      4 | 迪迦         | 西藏   |   10006 |      4 |
|      4 | 迪迦         | 西藏   |   10003 |      4 |
|      5 | 金甲戰(zhàn)士     | 內(nèi)蒙   |    NULL |   NULL |
+--------+--------------+--------+---------+--------+

3.添加外部行

這一步只有在連接類型為OUTER JOIN才發(fā)生。

LEFT OUTER JOIN把左表記為保留表,RIGHT OUTER JOIN把右表作為保留表,F(xiàn)ULL OUTER JOIN表示都作為保留表,添加外部行的工作就是在上一步的基礎(chǔ)上添加保留表中被過濾條件過濾掉的數(shù)據(jù),非保留表的數(shù)據(jù)被賦值NULL。

最終生成下面的結(jié)果,記為虛擬表VT3。

+--------+--------------+--------+---------+--------+
| userId | userName     | city   | orderId | userId |
+--------+--------------+--------+---------+--------+
|      1 | 張三         | 內(nèi)蒙   |   10005 |      1 |
|      1 | 張三         | 內(nèi)蒙   |   10004 |      1 |
|      1 | 張三         | 內(nèi)蒙   |   10002 |      1 |
|      1 | 張三         | 內(nèi)蒙   |   10001 |      1 |
|      2 | 李四         | 內(nèi)蒙   |   10007 |      2 |
|      3 | 王五         | 北京   |    NULL |   NULL |
|      4 | 迪迦         | 西藏   |   10006 |      4 |
|      4 | 迪迦         | 西藏   |   10003 |      4 |
|      5 | 金甲戰(zhàn)士     | 內(nèi)蒙   |    NULL |   NULL |
+--------+--------------+--------+---------+--------+

4. WHERE過濾器

這一步很簡單,條件為city="內(nèi)蒙" ,即只保留下city為內(nèi)蒙的列,并生成新的虛擬表VT4。最終結(jié)果如下。

+--------+--------------+--------+---------+--------+
| userId | userName     | city   | orderId | userId |
+--------+--------------+--------+---------+--------+
|      1 | 張三         | 內(nèi)蒙   |   10005 |      1 |
|      1 | 張三         | 內(nèi)蒙   |   10004 |      1 |
|      1 | 張三         | 內(nèi)蒙   |   10002 |      1 |
|      1 | 張三         | 內(nèi)蒙   |   10001 |      1 |
|      2 | 李四         | 內(nèi)蒙   |   10007 |      2 |
|      5 | 金甲戰(zhàn)士     | 內(nèi)蒙   |    NULL |   NULL |
+--------+--------------+--------+---------+--------+

5. GROUP BY 分組

這步將上一個步驟進(jìn)行分組,并生成新的虛擬表VT5,結(jié)果如下。

+--------+--------------+--------+
| userId | userName     | city   |
+--------+--------------+--------+
|      1 | 張三         | 內(nèi)蒙   |
|      2 | 李四         | 內(nèi)蒙   |
|      5 | 金甲戰(zhàn)士     | 內(nèi)蒙   |
+--------+--------------+--------+

6.HAVING篩選

分完組,我們就可以篩選了,選出count(orders.orderId)<3 的數(shù)據(jù)即可,最終結(jié)果如下。

| userId | userName     | city   | count(orders.orderId) |
+--------+--------------+--------+-----------------------+
|      2 | 李四         | 內(nèi)蒙   |                     1 |
|      5 | 金甲戰(zhàn)士     | 內(nèi)蒙   |                     0 |
+--------+--------------+--------+-----------------------+

7.處理SELECT列表

雖然SELECT是查詢中最先被指定的部分,但是直到這里才真正進(jìn)行處理,在這一步,將SELECT中指定的列從上一步產(chǎn)生的虛擬表中選出。

8.應(yīng)用DISTINCT

如果查詢語句中存在DISTINCT子句,則會創(chuàng)建一張內(nèi)存臨時表,這張內(nèi)存臨時表的表結(jié)構(gòu)和上一步產(chǎn)生的虛擬表一樣,不同的是對進(jìn)行DISTINCT操作的列增加了一個唯一索引,以此來去除重復(fù)數(shù)據(jù)。

另外對使用了GROUP BY語句的查詢,再使用DISTINCT是多余的,因?yàn)橐呀?jīng)進(jìn)行了分組,不會移除任何行。

9.排序和LIMIT

最后就是排序,返回新的虛擬表。結(jié)果如下。

+--------------+-------+
| userName     | total |
+--------------+-------+
| 李四         |     1 |
| 金甲戰(zhàn)士     |     0 |
+--------------+-------+

但是在本例子中沒有使用到LIMIT,如果使用到了,那么則從選出指定位置開始的指定行數(shù)

感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“MySQL中邏輯查詢的示例分析”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關(guān)注億速云行業(yè)資訊頻道,更多相關(guān)知識等著你來學(xué)習(xí)!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI