一道SQL Server窗口函数的面试题

news/2024/11/23 5:51:25/

概要

本文介绍一道和SQL Server窗口函数相关的面试题,主要涉及窗口函数的原理和Framing参数的设置。

设计和实现

题目介绍

输入数据如下:

主要包括账户编号(account_no),交易日期(tran_date),交易类型(tran_tyrp),交易金额(tran_amount)
在这里插入图片描述
要求统计账户交易总额大于等于1000的账户,已经统计每个账户总交易金额第一次达到1000的日期。

按照交易类型,如果是信用卡交易(credit),则加入总数;如果是储蓄卡交易(debit),则需要从总数中减去。

最后的输出结果是:

在这里插入图片描述

实现思路

我们以acc_1 账户进行分析,按照日期排序如下

在这里插入图片描述

  1. 因为交易类型都是信用卡交易,所以交易金额都是正值
  2. 统计每个日期和之前的日期的交易总额,每个日期对应的累计交易额是 100,600,900,1100
  3. 统计整个acc_1账户的全部交易额,已查看总交易额是否达到1000,每个日期对应的总交易额是1100

基于上述思路,我们需要逐条记录进行交易额的累计,以找到第一次交易总额超过1000的交易日期,还需要统计每个账户的总交易额,以检查其是否达到1000。

按照上述思路,使用窗口函数是最佳解决途径。

代码实现

查询过程中涉及大量的子查询,我们使用CTE代替嵌套子查询。

第一步, 我们根据交易类型,增加一列tran_actual_amount,用于标识实际的交易金额,如果是credit,则交易金额为负,以方便后面进行统计。

WITH add_tran_actual_amount AS (SELECT account_no, tran_date, tran_type, tran_amount, CASE WHEN tran_type = 'credit' THEN tran_amountELSE tran_amount * -1END AS tran_actual_amountFROM transactions),

第二步,我们使用窗口函数统计每个账户的累计交易额和总交易额。

add_sum AS (SELECT *, sum(tran_actual_amount) OVER (PARTITION BY account_no ORDER BY tran_date) AS sum_before_all, sum(tran_actual_amount) OVER (PARTITION BY account_no ORDER BY tran_date ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS sum_allFROM add_tran_actual_amount)

累计交易额sum_before_all,采用默认的Framing参数 即 ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW,该值可省略。

总交易金额表示统计每个账号的所有记录sum_all,所以Framing参数不能使用默认值,需要手工指定,即ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING

第三步,我们需要过滤掉交易总额不到1000的账户,并且找到每个账户第一次到1000的日期。

SELECT account_no, min(tran_date) AS first_reach_1000_date
FROM add_sum
WHERE sum_all >= 1000AND sum_before_all >= 1000
GROUP BY account_no

通过聚合函数min,找到最早到达1000的的日期。

附录

建表和数据填充代码如下:

if OBJECT_ID('transactions', 'U') is not null
drop table transactions;
create table transactions (id int primary key identity(1,1),account_no char(5) not null,tran_date date not null,tran_type nvarchar(10) not null,tran_amount int not null
)insert into transactions (account_no, tran_date, tran_type, tran_amount) values('acc_1', '2022-01-20', 'credit', 100),
('acc_1', '2022-01-21', 'credit', 500),
('acc_1', '2022-01-22', 'credit', 300),
('acc_1', '2022-01-23', 'credit', 200),('acc_2', '2022-01-20', 'credit', 500),
('acc_2', '2022-01-21', 'credit', 1100),
('acc_2', '2022-01-22', 'debit', 1000),('acc_3', '2022-01-20', 'credit', 1000),('acc_4', '2022-01-20', 'credit', 1500),
('acc_4', '2022-01-21', 'debit', 500),('acc_5', '2022-01-20', 'credit', 900)

http://www.ppmy.cn/news/481937.html

相关文章

四种网课框架模型,帮你轻松组织讲课内容

哈喽,大家好,我是海哥,知识付费变现创业教练,教育公司培训总监,从事知识付费变现咨询10年,已助力3000人实现知识付费变现。 当我们刚开始着手制作网课的时候,首先会遇到的问题就是不知道怎么填充…

强化学习从基础到进阶-案例与实践[2]:马尔科夫决策、贝尔曼方程、动态规划、策略价值迭代

【强化学习原理项目专栏】必看系列:单智能体、多智能体算法原理项目实战、相关技巧(调参、画图等、趣味项目实现、学术应用项目实现 专栏详细介绍:【强化学习原理项目专栏】必看系列:单智能体、多智能体算法原理项目实战、相关技巧…

dnf软件管理命令

dnf: ropolist##列出仓库信息 clean all##清除系统中已经加载的仓库储存信息 /var/cache/dnf list all##列出所有软件 list available##列出未安装软件 list installed##列出已安装软件 install##安装 remove##卸载 reinstall##重新安装 search##搜索…

CentOS 8 的 DNF 命令使用

DNF 是新一代的PMR软件包管理器,是 Yum包管理器的升级版。 DNF 使用 RPM, libsolv 和 hawkey 库进行包管理操作。 Yum是使用RPM软件包管理器的Linux操作系统的免费开放源代码命令行软件包管理应用程序。 Yum是rpm的前端工具,可自动解决软件包的依赖性。…

鸿蒙dnf为什么一直连接服务器,DNF组队崩溃内存占用高怎么办 附带详细解决办法...

DNF很多小伙伴都会遇到组队崩溃的情况,这样的事情一般是因为内存占用度太高产生的,很多玩家还不清楚怎么解决组队崩溃的情况,下面就来为大家详细的介绍一下攻略。 1.启动游戏就不要用wegame了,直接打开DNF的start文件,…

无盘服务器搬砖会封号吗,DNF工作室多开搬砖起号二天,16个帐号全被封,对于95版本严厉打击工作室你如果评价?...

“DNF这款游戏属于做了饿不死,不做又可惜的肉” 在90版本时,游戏工作室可谓一路横行,每个地图前都是好多重叠在一起的角色,都是工作室在起小号,而随着95版本的更新,TX势必打击了一批工作室,凡是…

dnf计算机配置检测,如何用DNF的方式来测试(卡爆)''你的电脑''

原标题:如何用DNF的方式来测试(卡爆)你的电脑 如何用DNF的方式来测试你的电脑配置,废话不多说我们直接进入正题,电脑不好的玩家就别皮辣 既然是测试,肯定要把配置拉满 基础设置拉满后 步骤一: 测试对象首选为&#xff…

最新版CleanMyMacX4.13.6发布了,它值得买吗?

Clean My Mac X是Mac上一款美观易用的系统优化清理工具,也是小编刚开始用Mac时的装机必备。垃圾需要时时清,电脑才能常年新。Windows的垃圾清理工具选择有很多,但是Mac的清理工具可选择的就很少。 最新版CleanMyMacX4.13.6发布此版本有哪些亮…