mysql> select * from user;+‐‐‐‐+‐‐‐‐‐‐+‐‐‐‐‐‐‐‐‐+‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐+| id | name | address | createtime |+‐‐‐‐+‐‐‐‐‐‐+‐‐‐‐‐‐‐‐‐+‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐+|1| aa | cun | 2020‐06‐01 00:00:00 || 2 | bb | cun |2020‐06‐0100:00:00||3| bb | shi | 2020‐06‐01 01:00:00 || 4 | bb | shi |2020‐06‐0101:00:00||5| cc | cun | 2020‐06‐01 01:00:00 || 6 | tt | cun |2020‐06‐0301:00:00||7| eee | cun | 2020‐06‐04 01:00:00 || 8 | eee | cun |2020‐06‐0401:00:00||9| xx | shen | 2020‐06‐02 01:00:00 |+‐‐‐‐+‐‐‐‐‐‐+‐‐‐‐‐‐‐‐‐+‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐+9 rows in set (0.00 sec)
2)窗口函数的使用
SELECT createtime,row_number() over(order by createtime) AS crFROM user ;+‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐+‐‐‐‐+| createtime | ll |+‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐+‐‐‐‐+|2020‐06‐0100:00:00| 1 || 2020‐06‐01 00:00:00 |2||2020‐06‐0101:00:00| 3 || 2020‐06‐01 01:00:00 |4||2020‐06‐0101:00:00| 5 || 2020‐06‐02 01:00:00 |6||2020‐06‐0301:00:00| 7 || 2020‐06‐04 01:00:00 |8||2020‐06‐0401:00:00| 9 |+‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐+‐‐‐‐+9 rows in set (0.00 sec)
row_number() over(order by createtime) as cr 这部分为窗口函数。over(order by createtime)为窗口规范,函数 row_number() 即对窗口的数据进行编号。所以上述 sql 的意思为:先对 createtime 进行排序,然后对每行数据进行编号。
通过子查询 a 对用户进行分组计算出每个用户的总交易金额(everymoney),再通过子查询 aa 使用 sum()+over 子句计算出所有用户总的交易金额(totalmoney),最后将每个用户总交易金额比上所有用户总交易金额(a.everymoney/(sum(a.everymoney) over())。
3.3 场景二
在拥有用户表和交易表的前提下,可以计算出每天交易金额位于第一的用户。
sql 如下:
SELECT a.name,a.paydate,row_number()OVER w AS numFROM(SELECT u.name,paydate,sum(amount) AS totalFROM user uJOIN transaction tON u.id=t.useridGROUP BY u.name,paydate) a window w AS (partition by paydateORDER BY a.total desc); +‐‐‐‐‐‐‐‐+‐‐‐‐‐‐‐‐‐‐‐‐+‐‐‐‐‐+| name | paydate | num |+‐‐‐‐‐‐‐‐+‐‐‐‐‐‐‐‐‐‐‐‐+‐‐‐‐‐+| 王五 |2020‐07‐01| 1 || 老三 |2020‐07‐01| 2 || 张三 |2020‐07‐01| 3 || 李四 |2020‐07‐01| 4 || 王五 |2020‐07‐03| 1 || 张三 |2020‐07‐03| 2 || 老三 |2020‐07‐03| 3 || 王五 |2020‐07‐10| 1 || 张三 |2020‐07‐14| 1 || 赵六 |2020‐07‐14| 2 || 张三 |2020‐07‐30| 1 |+‐‐‐‐‐‐‐‐+‐‐‐‐‐‐‐‐‐‐‐‐+‐‐‐‐‐+11 rows in set (0.00 sec)
上述 sql 通过子查询 a 对用户和 paydate 进行分组,计算出每个用户每天的交易金额
(total),再通过窗口函数 row_number() over w as num…window w as (partition by paydate order by a.total) 对数据按 paydate 分组,并按 total 降序排序进行编号。