高新網(wǎng)站開發(fā)1年經(jīng)驗(yàn)互聯(lián)網(wǎng)電商平臺(tái)
?🎉歡迎您來到我的MySQL基礎(chǔ)復(fù)習(xí)專欄
☆* o(≧▽≦)o *☆哈嘍~我是小小惡斯法克🍹
?博客主頁:小小惡斯法克的博客
🎈該系列文章專欄:力扣刷題講解-MySQL
🍹文章作者技術(shù)和水平很有限,如果文中出現(xiàn)錯(cuò)誤,希望大家能指正🙏
📜 感謝大家的關(guān)注!???
??
目錄
🚀查找重復(fù)的電子郵箱
🚀查找沒有買東西的顧客
🚀總結(jié)?
🚀查找重復(fù)的電子郵箱
表:?
Person
+-------------+---------+ | Column Name | Type | +-------------+---------+ | id | int | | email | varchar | +-------------+---------+ id 是該表的主鍵(具有唯一值的列)。 此表的每一行都包含一封電子郵件。電子郵件不包含大寫字母。 編寫解決方案來報(bào)告所有重復(fù)的電子郵件。 請(qǐng)注意,可以保證電子郵件字段不為 NULL。
以?任意順序?返回結(jié)果表。
結(jié)果格式如下例。
示例?1:
輸入:
Person 表:
+----+---------+
| id | email |
+----+---------+
| 1 | a@b.com |
| 2 | c@d.com |
| 3 | a@b.com |
+----+---------+
輸出:
+---------+
| Email |
+---------+
| a@b.com |
+---------+
解釋: a@b.com 出現(xiàn)了兩次。
解法一:
1.自連接
2.因?yàn)閷?shí)際上就這一個(gè)表,一般這類題目都是首選用自連接的方法
3.那么自連接就是需要起別名
4.這里我們肯定是把它想成兩個(gè)表,一個(gè)p1,一個(gè)p2
5.那么我們自連接后面的on的條件是什么?
6.因?yàn)橐抑貜?fù)的郵箱,所以我們肯定是找兩個(gè)表相同的郵箱,即p1.email = p2.email
7.但是只有這一個(gè)條件肯定是不夠的,因?yàn)槟氵@里是把它想成了兩張表,但實(shí)際上這兩張表本來就是一樣的,它們兩的字段email里面的value本身也就是一樣的,你只有這一個(gè)條件,沒有任何意義
8.所以還需要一個(gè)條件,就是我們是根據(jù)不同的id相同的email,這才叫重復(fù)
9.連接兩個(gè)不同的條件用and
10.兩個(gè)表中id要不相同的去比較,即p1.Id != p2.Id
11.所以寫為select p1.Email?from Person p1 ?join Person ?p2 on p1.Email = p2.Email AND p1.Id!=p2.Id
12.但此時(shí)還是不對(duì)的,因?yàn)閕d為1的email=id為3的email,然后id為3的email=id為1的email,相當(dāng)于最后輸出email,會(huì)輸出兩次一樣的,重復(fù)了
13.那么最后一步就是去重,用關(guān)鍵字distinct,代碼如下
select distinct(p1.Email) from Person p1
join Person p2 on p1.Email = p2.Email AND p1.Id!=p2.Id
執(zhí)行:
?
解法二:
1.使用 GROUP BY 和 HAVING 子句
2.這個(gè)解法首先按照電子郵件地址分組,然后使用 HAVING 子句篩選出出現(xiàn)次數(shù)大于 1 的電子郵件地址,從而找出重復(fù)的電子郵件。
SELECT email
FROM Person
GROUP BY email
HAVING COUNT(email) > 1;
解法三:
1.使用子查詢
2.這個(gè)解法使用了子查詢,首先在子查詢中找出重復(fù)的電子郵件,然后在外部查詢中選擇出現(xiàn)在子查詢結(jié)果中的電子郵件。
3.這個(gè)意思就相當(dāng)于把解法2作為一個(gè)嵌套select,只是沒有去重,然后外部再套一個(gè)select用于去找子查詢中的email
5.用where去篩查子查詢中的電子郵件
6.代碼如下:
SELECT email
FROM Person
WHERE email IN (SELECT emailFROM PersonGROUP BY emailHAVING COUNT(email) > 1
);
不過博主比較推薦用第一種和第二種,邏輯比較清晰,最后一種相當(dāng)于畫蛇添足
🚀查找沒有買東西的顧客
Customers
?表:+-------------+---------+ | Column Name | Type | +-------------+---------+ | id | int | | name | varchar | +-------------+---------+ 在 SQL 中,id 是該表的主鍵。 該表的每一行都表示客戶的 ID 和名稱。
Orders
?表:+-------------+------+ | Column Name | Type | +-------------+------+ | id | int | | customerId | int | +-------------+------+ 在 SQL 中,id 是該表的主鍵。 customerId 是 Customers 表中 ID 的外鍵( Pandas 中的連接鍵)。 該表的每一行都表示訂單的 ID 和訂購該訂單的客戶的 ID。
找出所有從不點(diǎn)任何東西的顧客。
以?任意順序?返回結(jié)果表。
結(jié)果格式如下所示。
示例 1:
輸入:
Customers 表:
+----+-------+
| id | name |
+----+-------+
| 1 | Joe |
| 2 | Henry |
| 3 | Sam |
| 4 | Max |
+----+-------+
Orders 表:
+----+------------+
| id | customerId |
+----+------------+
| 1 | 3 |
| 2 | 1 |
+----+------------+
輸出:
+-----------+
| Customers |
+-----------+
| Henry |
| Max |
+-----------+
解法一:
1.要找出所有從不點(diǎn)任何東西的顧客,我們可以使用 SQL 中的 LEFT JOIN 和 IS NULL 來解決這個(gè)問題。
2.左外連接相當(dāng)于查詢左表的所有數(shù)據(jù),也包含了左表和右表交集部分的數(shù)據(jù)
3.所以我們肯定是select * from??Customers left join? Orders on 條件
4.我們肯定是要給表取一個(gè)別名比較方便簡(jiǎn)潔
5.SELECT *?FROM Customers c LEFT JOIN Orders o ON 條件
6.那么現(xiàn)在最重要的其實(shí)就是我們的ON后面的連接條件到底是什么?
7.即用Orders的外鍵,去關(guān)聯(lián)Customers的主鍵,因?yàn)閷?shí)際上Orders的外鍵代表的就是Customers的主鍵,所有條件是O.customerId = C.Id?
8.即SELECT * FROM Customers c LEFT JOIN Orders o ON c.id = o.customerId
9.此時(shí)只是左外連接成功了,但是我們還沒有完成,它只是把所有數(shù)據(jù)返回了,這時(shí)候我們要進(jìn)行篩選
10.篩選我們用到where條件,那么where后面的條件如何寫呢?
8..我們會(huì)把左表的所有數(shù)據(jù)返回,包括沒有買東西的顧客和他們的訂單,那么沒有買東西的顧客就是null
9.我們?cè)儆脀here子句去過濾出Orders 表中沒有對(duì)應(yīng)訂單的顧客,即 o.id IS NULL。這樣就能找出所有從不點(diǎn)任何東西的顧客。
10.SELECT *?FROM Customers c LEFT JOIN Orders o ON?c.id = o.customerId?WHERE o.id IS NULL;
11.再把*優(yōu)化一下,代碼如下:
SELECT c.name AS Customers
FROM Customers c
LEFT JOIN Orders o ON c.id = o.customerId
WHERE o.id IS NULL;
🚀總結(jié)?
這個(gè)查詢首先從 Customers 表中選擇顧客的名稱,并左連接 Orders 表,以便找出所有顧客和他們的訂單。然后使用 WHERE 子句過濾出在 Orders 表中沒有對(duì)應(yīng)訂單的顧客,即 o.id IS NULL。這樣就能找出所有從不點(diǎn)任何東西的顧客。
在這個(gè)示例中,查詢的結(jié)果會(huì)返回 Henry 和 Max,因?yàn)樗麄冊(cè)?Orders 表中沒有對(duì)應(yīng)的訂單記錄。
解法二:
1.運(yùn)用not in去找Customers表中誰的id,沒有在Orders表中的CustomerId中
2.意思也就是,這4個(gè)人,誰沒有顧客訂單,我們就返回誰的名字
3.select * from?Customers c where c.id not in? (select CustomerId from Orders)?
4.優(yōu)化一下*,返回名字,然后字段取需要的別名Customers
5.代碼如下
select Name Customers
from Customers c
where c.Id not in (select CustomerId from Orders
)