一、题目要求:
表:Emails+-------------+---------+
| Column Name | Type |
+-------------+---------+
| id | int |
| email | varchar |
+-------------+---------+
id 是这张表的主键(有不同值的列)。
这张表的每一行包含一个电子邮件地址。电子邮件地址不包含大写字母。
编写一个解决方案来找到所有 不同的电子邮件域名 并且计数与每个域名相关联的 记录。只考虑 以 .com 结尾 的域名。返回结果表以 email_domains 升序 排列。结果格式如下所示。示例 1:输入:
Emails 表:
+-----+-----------------------+
| id | email |
+-----+-----------------------+
| 336 | hwkiy@test.edu |
| 489 | adcmaf@outlook.com |
| 449 | vrzmwyum@yahoo.com |
| 95 | tof@test.edu |
| 320 | jxhbagkpm@example.org |
| 411 | zxcf@outlook.com |
+----+------------------------+
输出:
+--------------+-------+
| email_domain | count |
+--------------+-------+
| outlook.com | 2 |
| yahoo.com | 1 |
+--------------+-------+
解释:
- 以“.com”结束的合法域名只有“outlook.com”和“yahoo.com”,数量分别为 2 和 1。
输出表以 email_domains 升序排列。
二、pandas解法:
pandas解决这个需求可以用正则表达式来表示
import pandas as pddef find_unique_email_domains(emails: pd.DataFrame) -> pd.DataFrame:#新建空值数据框data = pd.DataFrame()#取出Series类型的对应列,并且通过字符串匹配找到符合要求的字符串,保存到data空数据框的新建列中data['email_domain'] = emails['email'].str.extract(r'@([a-z]+\.com$)')#记得删除空值data=data.dropna()#新建数字1列,便于后续的统计data['count'] = 1#进行分组统计,直接将1列分组后进行累加的聚合操作即可data_last = data.groupby('email_domain').agg({'count':'sum'}).reset_index()return data_last
由于这里正则表达式要查找的是@后的域名(不包含@),所以正则表达式查找的是@后小括号里的表达式,结尾,即$符号前以\.com表示
三、MySQL的两种解法:
(1)利用SUBSTRING_INDEX函数
SUBSTRING_INDEX(string,str,n)
#表示返回string字符串从str开始的第n个字符
这里我就可以在select字段中截取到@后的字符了,在WHERE利用函数RIGHT匹配字符串“.com”,再进行分组聚合即可完成查询
# Write your MySQL query statement below
SELECT SUBSTRING_INDEX(email,"@",-1) AS email_domain,count(email) AS count
FROM Emails
WHERE RIGHT(email,4)=".com"
GROUP BY email_domain
ORDER BY email_domain
(2)利用SUBSTRING和LOCATE的函数组合
SUBSTRING(str,start,len) #返回从字符串str从strat位置起的len个长度的字符串
LOCATE(substring,string,start_position) #表示从string字符串的start_position位置开始的,查找substring的位置
SUBSTRING函数的参数只能输入数字,这样就不能精确截取字符串了,而LOCATE函数可以将某个字符转化为其在字符串的位置数字,用LOCATE函数找出@的数字位置,然后将该数字传递给SUBSTRING函数的start参数即可完成截取
# Write your MySQL query statement below
SELECT SUBSTRING(email, LOCATE('@', email)+1) AS email_domain,COUNT(*) AS count
FROM Emails
WHERE RIGHT(email,4) = '.com'
GROUP BY email_domain
ORDER BY email_domain
注意:这里的LOCATE要+1,因为域名不包含@
补充:为了避免命名BUG,MySQL的字段执行顺序为:
-
FROM
-
WHERE
-
GROUP BY
-
HAVING
-
SELECT
-
ORDER BY
-
LIMIT