数据库 OVER(PARITITON BY)函数和MySQL排序常用的方法

OVER(PARTITION BY)开窗函数

X 市建了一个新的体育馆,每日人流量信息被记录在这三列信息中:序号 (id)、日期 (visit_date)、 人流量 (people)。
请编写一个查询语句,找出人流量的高峰期。高峰期时,至少连续三行记录中的人流量不少于100。
例如,表 stadium:

+------+------------+-----------+
| id   | visit_date | people    |
+------+------------+-----------+
| 1    | 2017-01-01 | 10        |
| 2    | 2017-01-02 | 109       |
| 3    | 2017-01-03 | 150       |
| 4    | 2017-01-04 | 99        |
| 5    | 2017-01-05 | 145       |
| 6    | 2017-01-06 | 1455      |
| 7    | 2017-01-07 | 199       |
| 8    | 2017-01-08 | 188       |
+------+------------+-----------+

对于上面的示例数据,输出为:

+------+------------+-----------+
| id   | visit_date | people    |
+------+------------+-----------+
| 5    | 2017-01-05 | 145       |
| 6    | 2017-01-06 | 1455      |
| 7    | 2017-01-07 | 199       |
| 8    | 2017-01-08 | 188       |
+------+------------+-----------+

解题:

select id,visit_date,people from (
    select id,visit_date,people,count(b)over(partition by b) b2 from (
    	 select *,(id-row_number()over(order by id)) as b 
    	 from stadium where people >= 100
    	 ) t1 
) t2
where b2>=3;

over(partition by)和group by 作用相同,但是group by 是聚合函数,会影响输出结果,而over(partition by)是开窗函数,会在每一行后面加上分析的结果

比如count(Id)over(partiton by),那么就会在每一行后面加一列数据,就是统计Id的数量值

------------------------------------------分割线--------------------------------------------------

排序

现有这么一个表,根据不同部门对薪水进行排序:

+----+-------+--------+--------------+
| Id | Name  | Salary | DepartmentId |
+----+-------+--------+--------------+
| 1  | Joe   | 70000  | 1            |
| 2  | Jim   | 90000  | 1            |
| 3  | Henry | 80000  | 2            |
| 4  | Sam   | 60000  | 2            |
| 5  | Max   | 90000  | 1            |
+----+-------+--------+--------------+

现在需要对各部门每个人的工资进行排序
方法1-row_number()
select *,row_number()over(partition by DepartmentId order by Salary desc)as `Rank` from test;

+----+--------+--------+--------------+------+
| id | Name   | Salary | DepartmentId | Rank |
+----+--------+--------+--------------+------+
|  2 | Jim    |  90000 |            1 |    1 |
|  5 | Max    |  90000 |            1 |    2 |
|  1 | Joe    |  70000 |            1 |    3 |
|  3 | Henery |  80000 |            2 |    1 |
|  4 | Sam    |  60000 |            2 |    2 |
+----+--------+--------+--------------+------+
直接取排序后的行数,排名不重复

方法2-rank()
select *,rank()over(partition by DepartmentId order by Salary desc)as `Rank` from test;

+----+--------+--------+--------------+------+
| id | Name   | Salary | DepartmentId | Rank |
+----+--------+--------+--------------+------+
|  2 | Jim    |  90000 |            1 |    1 |
|  5 | Max    |  90000 |            1 |    1 |
|  1 | Joe    |  70000 |            1 |    3 |
|  3 | Henery |  80000 |            2 |    1 |
|  4 | Sam    |  60000 |            2 |    2 |
+----+--------+--------+--------------+------+
相同薪水相同部门排名一样,且会空出名次

方法3-dense_rank()
select *,dense_rank()over(partition by DepartmentId order by Salary desc)as `Rank` from test;

+----+--------+--------+--------------+------+
| id | Name   | Salary | DepartmentId | Rank |
+----+--------+--------+--------------+------+
|  2 | Jim    |  90000 |            1 |    1 |
|  5 | Max    |  90000 |            1 |    1 |
|  1 | Joe    |  70000 |            1 |    2 |
|  3 | Henery |  80000 |            2 |    1 |
|  4 | Sam    |  60000 |            2 |    2 |
+----+--------+--------+--------------+------+
相同薪水相同名次,不会空出名次

以上这三种方法,基本可以满足工作中所有的排序需求了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值