SQL.LeetCode(1321)餐馆营业额变化增长

embedded/2024/11/15 6:06:58/

表: Customer

+---------------+---------+
| Column Name   | Type    |
+---------------+---------+
| customer_id   | int     |
| name          | varchar |
| visited_on    | date    |
| amount        | int     |
+---------------+---------+
在 SQL 中,(customer_id, visited_on) 是该表的主键。
该表包含一家餐馆的顾客交易数据。
visited_on 表示 (customer_id) 的顾客在 visited_on 那天访问了餐馆。
amount 是一个顾客某一天的消费总额。

你是餐馆的老板,现在你想分析一下可能的营业额变化增长(每天至少有一位顾客)。

计算以 7 天(某日期 + 该日期前的 6 天)为一个时间段的顾客消费平均值。average_amount 要 保留两位小数。

结果按 visited_on 升序排序

返回结果格式的例子如下。

示例 1:

输入:
Customer 表:
+-------------+--------------+--------------+-------------+
| customer_id | name         | visited_on   | amount      |
+-------------+--------------+--------------+-------------+
| 1           | Jhon         | 2019-01-01   | 100         |
| 2           | Daniel       | 2019-01-02   | 110         |
| 3           | Jade         | 2019-01-03   | 120         |
| 4           | Khaled       | 2019-01-04   | 130         |
| 5           | Winston      | 2019-01-05   | 110         | 
| 6           | Elvis        | 2019-01-06   | 140         | 
| 7           | Anna         | 2019-01-07   | 150         |
| 8           | Maria        | 2019-01-08   | 80          |
| 9           | Jaze         | 2019-01-09   | 110         | 
| 1           | Jhon         | 2019-01-10   | 130         | 
| 3           | Jade         | 2019-01-10   | 150         | 
+-------------+--------------+--------------+-------------+
输出:
+--------------+--------------+----------------+
| visited_on   | amount       | average_amount |
+--------------+--------------+----------------+
| 2019-01-07   | 860          | 122.86         |
| 2019-01-08   | 840          | 120            |
| 2019-01-09   | 840          | 120            |
| 2019-01-10   | 1000         | 142.86         |
+--------------+--------------+----------------+
解释:
第一个七天消费平均值从 2019-01-01 到 2019-01-07 是restaurant-growth/restaurant-growth/ (100 + 110 + 120 + 130 + 110 + 140 + 150)/7 = 122.86
第二个七天消费平均值从 2019-01-02 到 2019-01-08 是 (110 + 120 + 130 + 110 + 140 + 150 + 80)/7 = 120
第三个七天消费平均值从 2019-01-03 到 2019-01-09 是 (120 + 130 + 110 + 140 + 150 + 80 + 110)/7 = 120
第四个七天消费平均值从 2019-01-04 到 2019-01-10 是 (130 + 110 + 140 + 150 + 80 + 110 + 130 + 150)/7 = 142.86

这道题的难点在于我们如何基于当天拿到前6天的数据,以来求取这七天的平均数。

而且拿到了这样的数据我们还得想怎么去除不满足前面有6天的数据,例如示例的2019-01-01,它前面都没有六天的数据,所以就没有必要展示。

我们知道一定的是基于七天的一个度量去进行计算,所以我们可以联想到一个窗口,窗口的大小固定为7,基于当天我们这个窗口包含住前6天的数据进行计算来得到结果。

我们知道MySQL是有窗口函数的,但是其实窗口函数是有定长的窗口的功能。

语法为:

sql"><window_function> OVER ([PARTITION BY partition_column][ORDER BY order_column][ROWS or RANGE BETWEEN <frame_start> AND <frame_end>]
)

后面的ROWS与RANGE就是用来制定窗口的大小的。

详情可以查看我上一篇定长窗口的SQL

https://blog.csdn.net/m0_65013257/article/details/142170042?spm=1001.2014.3001.5501

 现在我们已经有了计算固定窗口大小的函数,但我们还得需要一个细节。每一天是有多条记录的,也就是会有多个顾客购买,我们应该是基于当天的总额来进行窗口的计算。所以我们首先得算出每一天的总额

sql">select visited_on,sum(amount) amount
from customer
group by visited_on

现在我们可以基于这样一个基础表进行计算。需要运用两次窗口函数。

一次窗口计算七天内的总和。一次窗口计算七天内的平均数。

写出对应的SQL

sql">select visited_on,
sum(amount) over (order by visited_on rows 6 preceding) amount,
avg(t1.amount) over (order by visited_on rows 6 preceding) as average_amount
from (select visited_on,sum(amount) amountfrom customergroup by visited_on
) t1

这里还有一点瑕疵,平均数题目的示例中需要保留两位小数。所以我们还要使用Round函数

sql">select visited_on,
sum(amount) over (order by visited_on rows 6 preceding) amount,
round(avg(t1.amount) over (order by visited_on rows 6 preceding),2) as average_amount
from (select visited_on,sum(amount) amountfrom customergroup by visited_on
) t1

现在我们就算出每一天的七天内的平均额度与总额度了。但是我们还得需要去除未能有前面6天数据的数据。那这样我们应该有两种想法。一种应该是跳过,还有一种应该是基于一种判定,我们只需要判定后的数据。

我这里先阐述跳过的方法。我们可以跳过前六天的数据,然后获取后面所有的数据即可,但是遇到一个麻烦的事,MySQL当中没有这样的语法说获取到后面所有的数据。但我们可以拟一个较大的数,这样就可以满足我们的需求。

完整的SQL如下

sql">select visited_on,
sum(amount) over (order by visited_on rows 6 preceding) amount,
round(avg(t1.amount) over (order by visited_on rows 6 preceding),2) as average_amount
from (select visited_on,sum(amount) amountfrom customergroup by visited_on
) t1
limit 100000000000000 offset 6

那我们如何基于第二种想法解题呢,或者说还有其他方法吗?

实际上我们可以减少一次窗口函数的使用,因为有了七天的总额度,我们可以直接除以7就可以得倒平均数。而除去前六天的数据可以已时间的差值来进行判定,拿到所有时间中的最小值,然后当天的时间剪去最小值的时间如果大于等于6就行。

我们基础表不变,还是需要每一天的总额。

sql">select visited_on,sum(amount) amountfrom customergroup by visited_on) t1

然后运用一次窗口计算总额

sql">select visited_on,sum(amount) over (order by visited_on rows 6 preceding) amountfrom (select visited_on,sum(amount) amountfrom customergroup by visited_on) t1

然后筛选时间的SQL语句为

sql">where datediff(visited_on,(select min(visited_on) from customer)) >= 6

然后算出平均数即可。总SQL为

sql">select visited_on,
amount,
round(amount / 7,2) as average_amount
from
(select visited_on,sum(amount) over (order by visited_on rows 6 preceding) amountfrom (select visited_on,sum(amount) amountfrom customergroup by visited_on) t1
) t2
where datediff(visited_on,(select min(visited_on) from customer)) >= 6


http://www.ppmy.cn/embedded/113876.html

相关文章

cross-plateform 跨平台应用程序-09-phonegap/Apache Cordova 介绍

跨平台系列 cross-plateform 跨平台应用程序-01-概览 cross-plateform 跨平台应用程序-02-有哪些主流技术栈&#xff1f; cross-plateform 跨平台应用程序-03-如果只选择一个框架&#xff0c;应该选择哪一个? cross-plateform 跨平台应用程序-04-React Native 介绍 cross…

docker 数据管理

1. 数据管理 1.1 什么是数据管理 docker的镜像是只读的。容器可以进行操作&#xff0c;但数据不能保存到容器中。数据保存需要使用数据卷和数据卷容器。 1.2 容器、数据卷、数据卷容器关系图 1.2.1 什么是数据卷 宿主机的某个目录映射到容器中&#xff0c;作为数据存储的目…

网络运维面试题

1. 请解释OSI模型和TCP/IP模型的主要区别。 OSI模型和TCP/IP模型是两种不同的网络通信参考模型&#xff0c;它们在层数、功能及服务等方面存在显著差异。以下是具体区别&#xff1a; 层数 OSI模型&#xff1a;OSI模型共有七层&#xff0c;分别是物理层、数据链路层、网络层、…

VirtualBox7.1.0 安装 Ubuntu22.04.5 虚拟机

环境 &#xff08;1&#xff09;宿主机系统&#xff1a;Windows10 &#xff08;2&#xff09;虚拟机软件&#xff1a;VirtualBox7.1.0 &#xff08;3&#xff09;虚拟机系统&#xff1a;Ubuntu 22.04.5 LTS (Jammy Jellyfish) 安装虚拟机 &#xff08;1&#xff09;第一步…

2024.9.18

1.已知网址www.hqyj.com截取出网址的每一个部分 菜单栏中 ----> 虚拟机 -----> 设置 -----> 网络适配器 选择桥接模式 菜单栏中 ----> 编辑 -----> 虚拟网络编辑器 更改设置 将桥接改成自动 如果桥接连不上网 尝试还原默认设置后&#xff0c;在重新连接桥接…

75年来最强台风中,开门见“光明”!百年乳企守护城市“奶瓶子”,传递温度

​9月16日&#xff0c;今年第13号台风“贝碧嘉”登陆&#xff0c;台风预警已拉响。光明乳业全产业链严阵以待&#xff0c;密切关注台风发展趋势&#xff0c;细化落实防汛防台风各项应对措施&#xff0c;凝心聚力守护市民“奶瓶子”不断供。 光明随心订风雨无阻不断供 台风“贝…

软件测试 | APP测试 —— Appium 的环境搭建及工具安装教程

大家应该都有同一种感觉&#xff0c;学习appium最大的难处之一在于环境的安装&#xff0c;安装流程比较繁琐&#xff0c;安装的工具和步骤也较多&#xff0c;以下是基于Windows系统下的Android手机端的安装流程。就像我们在用Selenium进行web自动化测试的时候一样&#xff0c;我…

2024年9月HarmonyOS鸿蒙应用开发者高级认证全新题库(覆盖99%考题)

一个小时通过鸿蒙高级认证 1、在开发 Harmony0S 应用工程时&#xff0c; 随着业务的发展&#xff0c;现在需要创建一个模块&#xff0c; 关于在 DevEco Studio 中创建 Module &#xff0c; 下列选项哪种方式是错误的? 必对 在 hvigor 目录下&#xff0c;单击鼠标右键&#xf…