# Write your MySQL query statement below
1322. 广告效果
表: Ads
+---------------+---------+ | Column Name | Type | +---------------+---------+ | ad_id | int | | user_id | int | | action | enum | +---------------+---------+ (ad_id, user_id) 是该表的主键(具有唯一值的列的组合) 该表的每一行包含一条广告的 ID(ad_id),用户的 ID(user_id) 和用户对广告采取的行为 (action) action 列是一个枚举类型 ('Clicked', 'Viewed', 'Ignored') 。
一家公司正在运营这些广告并想计算每条广告的效果。
广告效果用点击通过率(Click-Through Rate:CTR)来衡量,公式如下:
编写解决方案找出每一条广告的 ctr
,ctr
要 保留两位小数 。
返回结果需要按 ctr
降序、按 ad_id
升序 进行排序。
返回结果示例如下:
示例 1:
输入: Ads 表: +-------+---------+---------+ | ad_id | user_id | action | +-------+---------+---------+ | 1 | 1 | Clicked | | 2 | 2 | Clicked | | 3 | 3 | Viewed | | 5 | 5 | Ignored | | 1 | 7 | Ignored | | 2 | 7 | Viewed | | 3 | 5 | Clicked | | 1 | 4 | Viewed | | 2 | 11 | Viewed | | 1 | 2 | Clicked | +-------+---------+---------+ 输出: +-------+-------+ | ad_id | ctr | +-------+-------+ | 1 | 66.67 | | 3 | 50.00 | | 2 | 33.33 | | 5 | 0.00 | +-------+-------+ 解释: 对于 ad_id = 1, ctr = (2/(2+1)) * 100 = 66.67 对于 ad_id = 2, ctr = (1/(1+2)) * 100 = 33.33 对于 ad_id = 3, ctr = (1/(1+1)) * 100 = 50.00 对于 ad_id = 5, ctr = 0.00, 注意 ad_id = 5 没有被点击 (Clicked) 或查看 (Viewed) 过 注意我们不关心 action 为 Ingnored 的广告
原站题解
mysql 解法, 执行用时: 353 ms, 内存消耗: 0 B, 提交时间: 2023-10-15 16:32:05
# Write your MySQL query statement below SELECT ad_id AS 'ad_id', ROUND( IFNULL( SUM(action='Clicked') / SUM(action IN ('Clicked', 'Viewed')) * 100 , 0) , 2) AS 'ctr' FROM Ads GROUP BY ad_id ORDER BY ctr DESC, ad_id ASC ;
pythondata 解法, 执行用时: 416 ms, 内存消耗: 61.2 MB, 提交时间: 2023-10-15 16:31:46
import pandas as pd def ads_performance(ads: pd.DataFrame) -> pd.DataFrame: ads['is_click'] = (ads['action'] == 'Clicked') ads['is_click_view'] = (ads['action'] != 'Ignored') ads['click_cnt'] = ads.groupby('ad_id')['is_click'].transform('sum') ads['total_cnt'] = ads.groupby('ad_id')['is_click_view'].transform('sum') ads['ctr'] = ads[['click_cnt', 'total_cnt']].apply(lambda x: round((0 if x[0] == 0 else x[0] / x[1]) * 100, 2), axis=1) res_df = ads[['ad_id', 'ctr']].drop_duplicates().sort_values(by=['ctr', 'ad_id'], ascending=[False, True]) return res_df