【数据分析面试】11. 计算账户关闭率(SQL:评估不同查询方法的性能效率)

news2025/1/19 16:22:49

在这里插入图片描述

题目

给定一个账户状态表,编写一个查询以获取在2019年12月31日活跃并在2020年1月1日关闭的账户所占的百分比,以及在2019年12月31日活跃的总账户数。每个账户只有一条每日记录,显示其在当天结束时的状态。

注意:将结果四舍五入到小数点后两位。

Input:

account_status table

ColumnType
account_idINTEGER
dateDATETIME
statusVARCHAR
account_iddatestatus
12020-01-01closed
12019-12-31open
22020-01-01closed

输出:

ColumnType
percentage_closedFLOAT

答案

解题思路

关键是要圈定两组ID:31号集体的激活账户,以及1号的休眠账户。
具体解题步骤如下:

  1. 首先,我们需要从账户状态表中筛选出在2019年12月31日活跃的账户。
  2. 然后,我们需要计算这些账户中有多少个在2020年1月1日关闭。
  3. 最后,我们将关闭的账户数量除以总的活跃账户数量,得到所需的百分比。
  4. 使用ROUND函数将结果四舍五入到两位小数。

答案代码

下面是题目的不同解法,主要的答题思路一致。

解法一

SELECT ROUND(
    (SELECT COUNT(*) FROM account_status WHERE date = '2020-01-01' AND status = 'closed')
    / (SELECT COUNT(*) FROM account_status WHERE date = '2019-12-31' AND status = 'open'),
    2
) AS percentage_closed

这种方法在处理大型数据集时可能会遇到性能问题,因为它执行了两次全表扫描。如果account_status表很大且没有适当的索引,这可能会导致查询速度较慢。然而,如果表很小或已经针对datestatus列建立了索引,这可能是一个简单而有效的解决方案。

解法二

SELECT 
	ROUND(
    SUM(CASE WHEN date = '2020-01-01' AND status = 'closed' THEN 1 ELSE 0 END) 
    / 
    COUNT(DISTINCT account_id) ,2)
    AS percentage_closed
FROM 
    account_status
WHERE 
    account_id IN (
        SELECT 
            account_id 
        FROM 
            account_status 
        WHERE 
            date = '2019-12-31' AND status = 'open'
    );

这种方法只需要一次全表扫描,并且利用了CASE语句来计算符合条件的行数。如果account_id有索引,那么子查询的性能会更好。这种方法通常比解法一更高效,特别是当处理大型数据集时。

解法三

WITH closed_accounts AS (
    SELECT *
    FROM account_status
    WHERE DATE(date) = "2020-01-01"
        AND status = "closed"
),
open_accounts AS (
    SELECT *
    FROM account_status
    WHERE DATE(date) = "2019-12-31"
        AND status = "open"
)
SELECT
    ROUND(COUNT(c.account_id) / COUNT(o.account_id),2) AS percentage_closed
FROM open_accounts AS o
LEFT JOIN closed_accounts AS c
ON o.account_id = c.account_id

这种方法使用了两个CTE来创建临时结果集,然后进行连接操作。这可能会导致额外的性能开销,特别是在没有适当索引的情况下。然而,如果数据库优化器能够有效地执行这些操作,这种方法也可以提供良好的性能。

其他业务思考……

在实际工作环境中,查询代码需要考虑多个因素。 比如数据库的大小、性能要求、数据分布和索引策略等。

  • 索引:确保account_status表上的datestatus列有索引,这将显著提高查询性能。
  • 数据量:如果数据量很大,倾向于选择那些减少全表扫描的方法。
  • 资源限制:考虑到服务器的资源限制,如CPU和内存,选择资源消耗较少的方法。
  • 维护性:选择易于理解和维护的代码,特别是在团队环境中。

基于上述考虑,解法二比其他两种答案更佳适用于真实工作场景,因为它通常在性能和维护性之间提供了一个好的平衡点。它避免了多次全表扫描,同时代码也相对简洁。

此外,还可以考虑以下改进:

  • 使用索引视图或物化视图来预计算某些值,以减少实时计算的负担。
  • 对于非常大的数据集,可以考虑使用并行查询或分布式计算来提高查询性能。
  • 如果业务逻辑允许,可以定期汇总数据到另一个表中,这样查询可以直接从这个汇总表中获取数据,而不是实时计算。像这种账户状态的指标,通常更建议这种方法,方便每日追踪监控。

最终,最佳的选择应该基于具体的业务需求、数据特性和系统环境进行测试和评估。

代码汇总

CREATE TABLE account_status (
    account_id INT,
    date DATE,
    status VARCHAR(10)
);

INSERT INTO account_status (account_id, date, status) VALUES
(1, '2019-12-31', 'open'),
(1, '2020-01-01', 'closed'),
(1, '2020-01-02', 'closed'),
(1, '2020-01-03', 'closed'),
(2, '2019-12-30', 'open'),
(2, '2019-12-31', 'open'),
(2, '2020-01-01', 'open'),
(2, '2020-01-02', 'closed'),
(2, '2020-01-03', 'closed'),
(3, '2019-12-30', 'open'),
(3, '2019-12-31', 'open'),
(3, '2020-01-01', 'closed'),
(3, '2020-01-02', 'closed'),
(3, '2020-01-03', 'closed'),
(4, '2020-12-31', 'closed'),
(4, '2021-01-01', 'closed'),
(4, '2021-01-02', 'closed'),
(4, '2021-01-03', 'closed'),
(5, '2019-12-31', 'open'),
(5,'2020-01-01','closed'),
(5,'2020-01-02','closed');

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1571990.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

在同一个局域网如何共享打印机和文件

1.在连接了打印机的主机上设置 1.1启用windows共享 打开网络与共享中心,点击“更改高级共享设置” 选择: “启用网络发现”“启用文件和打印机共享”“启用共享以便可以访问网络的用户可以读取和写入公用文件夹中的文件” 打开控制面板,选…

STM32-02基于HAL库(CubeMX+MDK+Proteus)GPIO输出案例(LED流水灯)

文章目录 一、功能需求分析二、Proteus绘制电路原理图三、STMCubeMX 配置引脚及模式,生成代码四、MDK打开生成项目,编写HAL库的GPIO输出代码五、运行仿真程序,调试代码 一、功能需求分析 在完成开发环境搭建之后,开始使用STM32GP…

python标准数据类型--列表常用方法

在Python中,列表(List)是一种非常常用的数据类型,用于存储一组有序的元素。Python提供了许多内置方法来操作列表,使得对列表的处理变得非常灵活和便捷。在本篇博客中,我们将介绍一些常用的列表方法&#xf…

Python | Leetcode Python题解之第8题字符串转换整数atoi

题目: 题解: INT_MAX 2 ** 31 - 1 INT_MIN -2 ** 31class Automaton:def __init__(self):self.state startself.sign 1self.ans 0self.table {start: [start, signed, in_number, end],signed: [end, end, in_number, end],in_number: [end, end,…

基于Java+SpringBoot+vue3点餐/外卖管理系统设计与实现

博主介绍:✌全网粉丝5W,全栈开发工程师,从事多年软件开发,在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战,博主也曾写过优秀论文,查重率极低,在这方面有丰富的经验…

linux 安装 pptp 协议

注意:目前iOS已不支持该协议 yum -y install ppp wget https://download-ib01.fedoraproject.org/pub/epel/7/x86_64/Packages/p/pptpd-1.4.0-2.el7.x86_64.rpm yum -y install pptpd-1.4.0-2.el7.x86_64.rpm vi /etc/pptpd.conf 去除 localip 和 remoteip的注释 …

Linux:进程等待究竟是什么?如何解决子进程僵尸所带来的内存泄漏问题?

Linux:进程等待究竟是什么?如何解决子进程僵尸所带来的内存泄漏问题? 一、进程等待的概念二、进程等待存在的意义三、如何进行进程等待3.1 wait()是实现进程等待1、wait()原型2. 验证wait()能回收僵尸子进程的空间 3.2 waitpid()实现进程等待…

阿里云2核2G服务器租用价格,真便宜

阿里云2核2G服务器配置优惠价格61元一年和99元一年,61元是轻量应用服务器2核2G3M带宽、50G高效云盘;99元服务器是ECS云服务器经济型e实例ecs.e-c1m1.large,2核2G、3M固定带宽、40G ESSD entry系统盘,阿里云活动链接 aliyunfuwuqi.…

真--开源个人收款系统方案--部署方案

继上文:真--个人收款系统方案,今天主要推出部署方案 1.下载源码 首先需要下载源码,源码地址:PayServer: 个人收款系统方案 - Gitee.com 并且pip下载依赖库: Flask2.5.1 Flask-Cors3.0.10 gevent23.6.0 websockets10.9 urllib31.26.1 2.修改配置 路径下有两个py文件&#xf…

【Frida】【Android】09_爬虫之Socket

🛫 系列文章导航 【Frida】【Android】01_手把手教你环境搭建 https://blog.csdn.net/kinghzking/article/details/136986950【Frida】【Android】02_JAVA层HOOK https://blog.csdn.net/kinghzking/article/details/137008446【Frida】【Android】03_RPC https://bl…

机器学习笔记 - 文字转语音技术路线简述以及相关工具不完全清单

一、TTS技术简述 今天的文本到语音转换技术(TTS)的目标已经不仅仅是让机器说话,而是让它们听起来像不同年龄和性别的人类。通常,TTS 系统合成器的质量是从不同方面进行评估的,包括合成语音的清晰度、自然度和偏好,以及人类感知因素,例如可理解性。 1、技术路线 (1)基…

【Java网络编程】HTTPS协议

HTTPS协议 由于HTTP协议是采用明文传输的方式,因此带来了很大的数据安全隐患,所以在最近几年的时间内,大部分平台都采用了HTTPS逐渐取代了HTTP,但HTTPS并不是一种全新的协议,而是建立在HTTP协议的基础之上&#xff0c…

单链表的排序

目录 题目来源: 题目描述: 初始代码: 思路: 具体做法: 我的代码: 优化代码: 对比: 复习:List 基本介绍 常用方法 遍历方式 题目来源: 单链表的排…

达梦使用disql登录数据库显示“未连接”

基础环境 操作系统:Red Hat Enterprise Linux Server release 7.9 (Maipo) 数据库版本:DM Database Server 64 V8 架构:单实例问题:达梦数据库在使用disql登录时,显示“未连接”。 指定了IP和端口号还是连接异常。 […

PTA天梯赛练习题 L1-029 是不是太胖了

PTA | 程序设计类实验辅助教学平台 思路简析 挺简单的一道输出题&#xff0c;但是有几个细节注意&#xff1a; 整数类型与浮点类型的混合运算控制小数位数 解法代码 #include<stdio.h> int main () {int H;scanf("%d", &H);float result;result 2 * (H …

Vulnhub:BOSSPLAYERSCTF: 1

目录 信息收集 arp nmap nikto whatweb WEB web信息收集 dirmap 命令执行漏洞 反弹shell 提权 系统信息收集 get root 信息收集 arp ┌──(root㉿ru)-[~/kali/vulnhub] └─# arp-scan -l Interface: eth0, type: EN10MB, MAC: 00:50:56:2f:dd:9…

基于java+SpringBoot+Vue的月度员工绩效考核管理系统设计与实现

基于javaSpringBootVue的月度员工绩效考核管理系统设计与实现 开发语言: Java 数据库: MySQL技术: SpringBoot VUE工具: IDEA/Eclipse、Navicat、Maven 系统展示 前台展示 绩效考核查询模块&#xff1a;员工可以查询自己的绩效考核结果和历史记录。 后台展示 部门管理模…

物联网实战--入门篇之(十)安卓QT--后端开发

目录 一、项目配置 二、MQTT连接 三、数据解析 四、数据更新 五、数据发送 六、指令下发 一、项目配置 按常规新建一个Quick空项目后&#xff0c;我们需要对项目内容稍微改造、规划下。 首先根据我们的需要在.pro文件内添加必要的模块&#xff0c;其中quick就是qml了&…

阿里云服务器资费:一年或1个月费用价格,2024年更新

阿里云服务器资费多少钱&#xff1f;一年或1个月费用价格&#xff1a;2核2G3M轻量服务器61元一年、ECS云服务器2核2G3M 99元一年&#xff0c;2核4G轻量165元一年&#xff0c;2核4G ECS 199元一年&#xff0c;阿里云服务器网aliyunfuwuqi.com整理如下&#xff1a; 1、ECS经济型e…

vue 实现的h5 页面,如何设置页面中的 title

修改页面中的title 公共修改方式在App.vue 中&#xff1a; created() {document.title "测试标题"; },单个页面修改&#xff0c;就在单个页面编写就ok