【问题标题】:How to find two consecutive rows sorted by date, containing a specific value?如何找到按日期排序的两个连续行,包含特定值?
【发布时间】:2020-09-23 05:14:04
【问题描述】:

我有一个表,其中包含以下结构和数据:

| ID    | Date          | Result    |
|----   |------------   |--------   |
| 1     | 30/04/2020    | +         |
| 1     | 01/05/2020    | -         |
| 1     | 05/05/2020    | -         |
| 2     | 03/05/2020    | -         |
| 2     | 04/05/2020    | +         |
| 2     | 05/05/2020    | -         |
| 2     | 06/05/2020    | -         |
| 3     | 01/05/2020    | -         |
| 3     | 02/05/2020    | -         |
| 3     | 03/05/2020    | -         |
| 3     | 04/05/2020    | -         |

我正在尝试编写一个 SQL 查询(我正在使用 SQL Server),它返回给定 ID 的前两个连续否定结果的日期。 例如,对于 ID 号。 1,前两个连续的负面结果是在 01/05 和 05/05。 ID 号 2 的前两个连续结果分别在 05/05 和 06/05。 ID 3 的前两个连续阴性结果分别在 01/05 和 02/05 出现。

所以查询应该产生以下结果:

| ID    | FirstNegativeDate     |
|----   |-------------------    |
| 1     | 01/05                 |
| 2     | 05/05                 |
| 3     | 01/05                 |

请注意,日期不一定相隔一天。有时,两个连续的阴性测试可能相隔几天。但它们仍应被视为“连续阴性测试”。换句话说,两个阴性测试只有在它们之间有阳性测试结果时才“连续”。

这如何在 SQL 中完成?我已经阅读了一些内容,看起来可能需要 PARTITION BY 语句,但我不确定它是如何工作的。

【问题讨论】:

    标签: sql sql-server date window-functions gaps-and-islands


    【解决方案1】:

    这是一个间隙和孤岛问题,您希望'-'s 的第一个孤岛的开始至少包含两行。

    我会推荐lead() 和聚合:

    select id, min(date) first_negative_date
    from (
        select t.*, lead(result) over(partition by id order by date) lead_result
        from mytable t
    ) t
    where result = '-' and lead_result = '-'
    group by id
    

    【讨论】:

    • 谢谢!我会试试这个。同时,为了帮助其他人偶然发现这一点,lead() 函数接受一个偏移量参数。如果未提供,则偏移量默认为 1,这就是为什么在这种情况下,lead() 可以找到 两个 连续值的原因。 (techonthenet.com/sql_server/functions/lead.php)
    • 您能解释一下 where 子句 ) t where result = '-' and lead_result = '-' 之前的 t 的用途吗?它有什么作用?没有它查询将无法运行,但也将其更改为其他内容似乎对输出没有影响。
    • 这是子查询的表别名。这在 SQL 中是非常重要的事情(每个派生表都必须有一个别名)。
    • 明白 :) 内部查询和外部查询都使用't'让我有点困惑,我想。
    【解决方案2】:

    在按日期列排序的 ID 分区上使用 LEAD 或 LAG 函数。 然后简单检查 LEAD/LAG 列等于 Result 的位置。 您还需要过滤排名靠前的。

    The image attached just shows what LEAD/LAG would return

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-18
      • 1970-01-01
      • 1970-01-01
      • 2015-06-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-26
      相关资源
      最近更新 更多