MySQL–第4关:查询用户日活数及支付金额

MySQL--第4关:查询用户日活数及支付金额 -- WhiteNight's Site

标签:MySQL

非常好的题,爱来自中国。

题目
没啥用

任务描述

现有3张业务表,详见如下:

需要输出结果如下,没有支付的日期不需要显示,请写出对应的MYSQL

示例1 输入: CREATE TABLE new_user( user_id int(11) NOT NULL, is_new int(11) NOT NULL, PRIMARY KEY (user_id) ); CREATE TABLE user_pay( user_id int(11) NOT NULL, pay_money int(11) NOT NULL, dt char(20) NOT NULL ); CREATE TABLE login_record( user_id int(11) NOT NULL, login_time char(20) NOT NULL, dt char(20) NOT NULL ); insert into new_user values(1,0); insert into new_user values(2,1); insert into new_user values(3,1); insert into new_user values(4,0); insert into new_user values(5,0); insert into new_user values(6,1); insert into new_user values(7,0); insert into new_user values(8,1); insert into user_pay values(1,30,'2021-11-10′); insert into user_pay values(1,100,'2021-11-10′); insert into user_pay values(2,500,'2021-11-11′); insert into user_pay values(2,200,'2021-11-12′); insert into user_pay values(3,1000,'2021-11-10′); insert into user_pay values(4,800,'2021-11-12′); insert into user_pay values(6,1200,'2021-11-10′); insert into user_pay values(6,700,'2021-11-14′); insert into login_record values(1,'8:00′,'2021-11-10′); insert into login_record values(1,'12:00′,'2021-11-10′); insert into login_record values(1,'13:00′,'2021-11-10′); insert into login_record values(2,'16:00′,'2021-11-10′); insert into login_record values(2,'12:35′,'2021-11-11′); insert into login_record values(2,'18:34′,'2021-11-12′); insert into login_record values(3,'20:00′,'2021-11-10′); insert into login_record values(4,'21:00′,'2021-11-12′); insert into login_record values(5,'21:00′,'2021-11-13′); insert into login_record values(6,'22:30′,'2021-11-10′); insert into login_record values(6,'13:30′,'2021-11-14′);

输出: dt dau dau_new total_pay total_pay_new 2021-11-10 4 3 2330 2200 2021-11-11 1 1 500 500 2021-11-12 2 1 1000 200 2021-11-14 1 1 700 700

解题思路
看图

记录下几个用到的知识点:

  • 通过派生表来去重。如果我需要从一个已经去重过的结果集中挑选结果,那就是要用到派生表。需要注意的是既然叫派生表,那么你应该把它当成独立的一张表看。即返回的字段数要大于等于你select的字段数。
  • 聚合函数中的IF。可以在聚合函数里面加IF来计算满足某个条件的数据。需要注意的是如果不满足条件需要返回NULL。因为聚合函数计算的是结果集中"存在",即非NULL的数据。所以返回0对于聚合函数而言是"存在",返回NULL才是"不存在"。
  • 左联结+聚合函数。左联结中无法匹配的地方会被填上NULL表示"不存在可匹配的数据"。为什么方便聚合函数的计算原因如上条所述。

其实从输出中反推就行了,一步一步去LEFT JOIN新表+条件判断去筛选结果,最后从左到右逐步得出输出结果。

复制代码
USE myusers;
########## Begin ##########
SELECT A.dt,COUNT(DISTINCT A.user_id) AS dau,SUM(B.is_new) AS dau_new
,SUM(C.pay_money) AS total_pay
,SUM(IF(B.is_new=1,C.pay_money,NULL)) AS total_pay_new
FROM(SELECT DISTINCT user_id,dt
FROM login_record)A
LEFT JOIN new_user AS B
ON A.user_id=B.user_id
LEFT JOIN user_pay AS C
ON C.user_id=A.user_id AND C.dt=A.dt
GROUP BY A.dt
HAVING SUM(C.pay_money) IS NOT NULL

########## End ##########

This Website © 2023 by White Night is licensed under CC BY-NC-SA 4.0

相关推荐
默阳12341 小时前
2026年Android中高级面试题专栏(Android进阶篇)
android
这个DBA有点耶1 小时前
2026年分布式数据库有哪些主流选择?先评估这5个维度再决定
数据库·分布式·dba
古法安卓2 小时前
Android-日志系统源码解析
android·java·android studio
恋猫de小郭3 小时前
Android 17 + OkHttp 5.5.0 ,全新 ECH 下你的 HTTPS 域名可以请求时被安全隐藏
android·前端·flutter
小强闯江湖3 小时前
不只是让 AI 写代码:ViewCompose 把 Android UI 做成了可编译、可渲染的闭环
android·人工智能·kotlin
这个DBA有点耶4 小时前
从MySQL 5.7到8.0:JSON查询性能差在哪?虚拟列索引vs多值索引怎么选
数据库·mysql·架构
胡写代码4 小时前
数据库审计字段,别再每张表各写一套了——我统一成这 6 个字段
数据库
hunterandroid4 小时前
StateFlow 与 SharedFlow 的边界:状态与事件的正确建模
android·前端
YF02114 小时前
Android遥控器对频详解
android·android things
码农coding6 小时前
android12 WindowManagerService窗口的布局过程
android·源码