OVER(PARTITION BY ***)用法,力扣mysql算法题,每日一题

力扣mysql题

题目:585. 2016年的投资

Insurance 表:

Column NameType
pidint
tiv_2015float
tiv_2016float
latfloat
lonfloat

pid 是这张表的主键(具有唯一值的列)。
表中的每一行都包含一条保险信息,其中:
pid 是投保人的投保编号。
tiv_2015 是该投保人在 2015 年的总投保金额,tiv_2016 是该投保人在 2016 年的总投保金额。
lat 是投保人所在城市的纬度。题目数据确保 lat 不为空。
lon 是投保人所在城市的经度。题目数据确保 lon 不为空。

题目:编写解决方案报告 2016 年 (tiv_2016) 所有满足下述条件的投保人的投保金额之和:

他在 2015 年的投保额 (tiv_2015) 至少跟一个其他投保人在 2015 年的投保额相同。
他所在的城市必须与其他投保人都不同(也就是说 (lat, lon) 不能跟其他任何一个投保人完全相同)。
tiv_2016 四舍五入的 两位小数 。

查询结果格式如下例所示。

示例 1:

输入:
Insurance 表:

pidtiv_2015tiv_2016latlon
11051010
220202020
310302020
410404040

输出:

tiv_2016
45.00

解释:
表中的第一条记录和最后一条记录都满足两个条件。
tiv_2015 值为 10 与第三条和第四条记录相同,且其位置是唯一的。

第二条记录不符合任何一个条件。其 tiv_2015 与其他投保人不同,并且位置与第三条记录相同,这也导致了第三条记录不符合题目要求。
因此,结果是第一条记录和最后一条记录的 tiv_2016 之和,即 45 。

解题分析:
1.主要需要的字段:
tiv_2016:用于汇总数据
tiv_2015:有相同数据的条件
lat lon :用于区别投保人位置,且是唯一数据
2.由上可得:

SELECT tiv_2016,
COUNT(1) OVER(PARTITION BY tiv_2015 ) cnt_tiv_2015,
COUNT(1) OVER(PARTITION BY lat,lon ) cnt_lat
FROM Insurance

输出结果:

tiv_2016cnt_tiv_2015cnt_lat
531
3032
2012
4031

查询出我们需要的结果:cnt_tiv_2015 相同的不唯一的,cnt_lat唯一的
3.再根据条件最后查询:

SELECT round(sum(tiv_2016),2) tiv_2016
FROM 
(
SELECT tiv_2016,
COUNT(1) OVER(PARTITION BY tiv_2015 ) cnt_tiv_2015,
COUNT(1) OVER(PARTITION BY lat,lon ) cnt_lat
FROM Insurance 
) t
WHERE cnt_tiv_2015 > 1 AND cnt_lat = 1;

输入结果:

tiv_2016
45

最后所涉及到的函数及要点
1.round(x [,y]):返回离 x 最近的整数,可选参数 y 表示要四舍五入的小数位数,如果省略,则返回整数
SELECT ROUND(1.23456) --1
SELECT ROUND(345.156, 2) – 345.16
2.COUNT(1) OVER(PARTITION BY tiv_2015) cnt_tiv_2015:分析tiv_2015这个字段的数据在表中出现相同的次数
3.COUNT(1) OVER(PARTITION BY lat,lon ) cnt_lat:分析lat,lon这两个字段在表中出现相同的次数
4.sum():返回指定字段的总和
计算 OrderDetails 表中字段 Quantity 的总和:

SELECT SUM(Quantity) AS TotalItemsOrdered FROM OrderDetails;

详解2和3:

SELECT *,
COUNT(1) OVER(PARTITION BY tiv_2015 ) cnt_tiv_2015,
COUNT(1) OVER(PARTITION BY lat,lon ) cnt_lat
FROM Insurance 

结果:

pidtiv_2015tiv_2016latloncnt_tiv_2015cnt_lat
1105101031
31030202032
22020202012
41040404031

pid=1时,tiv_2015=10,tiv_2015字段在表中出现了 3次=10的情况,cnt_tiv_2015=3;
pid=2时,tiv_2015=10,tiv_2015字段在表中出现了 3次=10的情况;cnt_tiv_2015=3
pid=3时,tiv_2015=20,tiv_2015字段在表中出现了 1次=20的情况;cnt_tiv_2015=1
pid=4时,tiv_2015=10,tiv_2015字段在表中出现了 3次=10的情况;cnt_tiv_2015=3
同理可得:
pid=1时,lat=10,lon=10 表中出现了 1次的情况,cnt_lat=1;
pid=2时,lat=20,lon=20 表中出现了 2次的情况,cnt_lat=2;
pid=3时,lat=20,lon=20 表中出现了 2次的情况,cnt_lat=2;
pid=4时,lat=40,lon=40 表中出现了 1次的情况,cnt_lat=1;

### 回答1: MySQL 中的 OVER PARTITION BY 子句用于在对每个分区中的行进行聚合操作时对结果进行排序。其语法为: SELECT column_name, aggregate_function(column_name) OVER (PARTITION BY column_name_for_partition ORDER BY column_name_for_ordering) FROM table_name; 其中,aggregate_function 可以是 COUNT、SUM、AVG 等聚合函数,column_name_for_partition 是用于分区的列名,column_name_for_ordering 是用于排序的列名。 例如: SELECT id, name, salary, SUM(salary) OVER (PARTITION BY department ORDER BY salary DESC) as department_total_salary FROM employees; 该语句会对员工表中的每个部门的员工的工资求和,并按工资降序排序。 ### 回答2: MySQL中的over partition by语法是一种强大的分析函数,它可以让用户分析和计算分组数据的各种指标,例如排名、分组求和、分组平均等。在这里我们将主要讨论MySQL中over partition by语法的用法和实际应用。 首先,over partition by语法主要用于对分组数据进行分析和计算。一个最典型的应用场景是,我们需要根据某个列进行分组(例如按部门分组),然后对每个分组内的数据进行rank、sum、average、row_number等各种计算。这个时候,over partition by语法就可以大显神威了。例如,下面的语句用于计算每个部门的平均工资: ``` SELECT department, AVG(salary) OVER (PARTITION BY department) AS avg_salary FROM employee; ``` 在这个例子中,我们使用了over partition by语法,指定对每个部门进行分组,然后对分组内的salary求平均值,最后将结果作为一个新的列avg_salary返回。 除了平均值之外,我们还可以使用同样的方式计算每个部门内每个员工的排名或行号,例如: ``` SELECT department, name, salary, ROW_NUMBER() OVER (PARTITION BY department ORDER BY salary DESC) AS rank FROM employee; ``` 在这个例子中,我们使用了ROW_NUMBER()函数,对每个部门进行分组,然后按照工资从高到低排序,最后为每个分组内的每个员工计算一个排名。 除了ROW_NUMBER()之外,MySQL中还提供了很多其他有用的分析函数,例如SUM()、AVG()、MAX()、MIN()等,都可以配合partition by语法使用。需要注意的是,over子句必须放在所有其他子句(例如where、group by、order by等)的后面。 总体来说,over partition by语法是MySQL中一个非常有用的分析函数,它可以大大简化我们对数据分组的处理逻辑,并且提供了很多有用的函数和功能,让我们的数据分析工作更加便捷和高效。 ### 回答3: MySQL over partition by是一项高级窗口功能,它允许我们在MySQL查询中对结果集进行分区,并可以应用聚合函数和类似的分析函数来计算每个分区的值。 over partition by是针对窗口函数的一种用法。窗口函数是一种SQL语句中用于执行计算的高级函数,允许我们在结果集上执行聚合操作,并返回有关每个行分组的统计数据。 over partition by允许指定一个或多个列用于对结果集进行分区,这使得我们可以按照指定的列将结果集划分为多个子集。然后,我们可以在每个子集中计算聚合函数或其他分析函数,例如计算累积总和、计算当前行以前的行数等。 在使用over partition by之前,需要先定义一个窗口。窗口定义了查询中将使用分析和/或聚合函数的范围。窗口有两个主要部分:窗口规范和窗口框架。 窗口规范定义了要应用窗口函数的分区,可以使用partition by子句来指定。窗口框架定义了在分区内应用窗口函数的一系列行,可以使用rows或range子句来定义范围。如果没有定义窗口框架,则将对整个分区应用聚合函数。 下面是一个使用over partition by查询的例子,我们将对sales表进行分区,并计算每个分区中的行数、销售总额和平均销售额: SELECT date, region, product, sales, COUNT(*) OVER(PARTITION BY region, product) AS sales_count, SUM(sales) OVER(PARTITION BY region, product) AS sales_total, AVG(sales) OVER(PARTITION BY region, product) AS sales_avg FROM sales; 这个查询将返回按区域和产品分组的销售统计数据,包括每组的行数、销售总额和平均销售额。使用over partition by语法,我们可以更轻松地进行数据处理和分析,而无需编写复杂的嵌套子查询或联接语句。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

騒周

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值