1、简介

Lead() 函数式一个窗口函数,允许您向前看多行并从当前行访问行的数据。

语法:

  1. LEAD(<expression>[,offset[, default_value]]) OVER (
  2. PARTITION BY (expr)
  3. ORDER BY (expr)
  4. )

expression
lead() 函数返回值expression从offset-th有序分区排
offset
offset是从当前行向前行的行数,以获取值。
offset必须是一个非负整数,如果offset为零,则lead()函数计算expression当前行的值。
如果省略offset,则Lead() 函数默认使用一个。
default_value
如果没有后续行,则Lead()函数返回default_value。例如,如果offset是1,则最后一行的返回值为default_value
如果您未指定default_value,则函数返回Null。
PARTITION BY子句
**
PARTITION BY子句将结果集中的行划分Lead()为应用函数的分区。
如果PARTITION BY未指定子句,则结果集中的所有行都将被视为单个分区

ORDER BY子句
order by 子句确定LEAD()应用函数之前分区中行的顺序

示例
我们将使用示例数据库中的orderscustomers表进行演示:
以下语句查找每个客户的订单日期和下一个订单日期:

  1. SELECT
  2. customerName,
  3. orderDate,
  4. LEAD(orderDate,1) OVER (
  5. PARTITION BY customerNumber
  6. ORDER BY orderDate ) nextOrderDate
  7. FROM
  8. orders
  9. INNER JOIN customers USING (customerNumber);

image.png
在此示例中,我们首先将客户编号的结果集划分为多个分区。然后,我们按订单日期对每个分区进行排序。最后,LEAD()函数应用于每个分区以获取下一个订单日期。
一旦后续行穿过分区边界,nextOrderDate每个分区的最后一行中的值就是NULL
在本教程中,您学习了如何使用MySQL LEAD()函数访问当前行中后续行的数据。

2、案例

image.png```sql select temp.user_id, max(datediff(nextDate,temp.visit_date)) biggest_window from ( select user_id , visit_date , lead(visit_date ,1,’2021-1-1’) over (PARTITION BY user_id ORDER BY visit_date ) nextDate from UserVisits ) temp group by temp.user_id

  1. <a name="L8cNq"></a>
  2. # 案例2
  3. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/1428377/1637119108085-d6e2a77c-9654-448d-b63e-fd75afb1b8c7.png#align=left&display=inline&height=499&margin=%5Bobject%20Object%5D&name=image.png&originHeight=997&originWidth=1170&size=85187&status=done&style=none&width=585)<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/1428377/1637119144611-05102c62-e257-4330-91fd-902c7651cbc3.png#align=left&display=inline&height=817&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1634&originWidth=1742&size=210375&status=done&style=none&width=871)
  4. 解决方式1: 自连接
  5. ```sql
  6. select u2.name,u2.mail
  7. from users u2
  8. where user_id in (
  9. select gold_medal
  10. from contests
  11. group by gold_medal
  12. having count(*)>=3
  13. union
  14. select distinct u.user_id
  15. from users u,contests c1,contests c2,contests c3
  16. where (u.user_id=c1.gold_medal or u.user_id=c1.silver_medal or u.user_id=c1.bronze_medal)
  17. and (u.user_id=c2.gold_medal or u.user_id=c2.silver_medal or u.user_id=c2.bronze_medal)
  18. and (u.user_id=c3.gold_medal or u.user_id=c3.silver_medal or u.user_id=c3.bronze_medal)
  19. and c1.contest_id=c2.contest_id+1 and c2.contest_id=c3.contest_id+1
  20. )

解决方式2 : 临时表、窗口函数

  1. with tmp1 as (
  2. select contest_id,gold_medal m from contests
  3. union all
  4. select contest_id,silver_medal from contests
  5. union all
  6. select contest_id,bronze_medal from contests
  7. )
  8. select name,mail
  9. from users
  10. where user_id in (
  11. select gold_medal m
  12. from contests
  13. group by gold_medal
  14. having (count(1)>=3)
  15. union
  16. select t1.m
  17. from (
  18. select *,lead(contest_id,2) over(partition by m order by contest_id) lead2
  19. from tmp1
  20. ) t1
  21. where contest_id+2=lead2
  22. )