【问题标题】:SQL get the last time number was set to 1SQL 获取最后一次数字设置为 1
【发布时间】:2020-01-09 17:31:00
【问题描述】:

我有一个类似于下面的 sql 表。我想知道它最后一次从 0 更改为 1 的时间以及最后一次更改回 0 的时间(在下面突出显示以获取示例 id)。

我试过的是:

select * from Table t1 join Table t2 on t1.id = t2.id join Table t3 on t1.id = t3.id 
where t1.flag = 1 and t2.flag = 0 and t3.flag 
group by t1.id
having min(t1.createdtime) between max(t2.createdtime) and min(t3.createdtime)

【问题讨论】:

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


    【解决方案1】:

    对于这个数据集,你可以使用lag()来引入上一行的标志,作为过滤条件,然后聚合:

    select 
        id,
        max(createdtime) createdtime,
        flag
    from (
        select 
            t.*,
            lag(flag) over(partition by id order by createdtime) lagflag
        from mytable t
    ) t
    where (flag = 0 and lagflag = 1) or (flag = 1 and lagflag = 0)
    group by id, flag
    

    【讨论】:

    • 我不能编辑,因为它是一个字母......“oder by”应该是“order by”
    【解决方案2】:

    您可以使用lag() 获取最近的标志。因此,您可以过滤更改,即当(当前)标志和最近标志根据需要相关时。要仅获取最新的更改,您可以按 row_number() 过滤。

    SELECT z.id,
           z.createdtime,
           z.flag
           FROM (SELECT y.id,
                        y.createdtime,
                        y.flag FROM (SELECT x.id,
                                            x.createdtime,
                                            x.flag,
                                            row_number() OVER (PARTITION BY x.id
                                                               ORDER BY x.createdtime DESC) rn
                                            FROM (SELECT t.id,
                                                         t.createdtime,
                                                         t.flag,
                                                         lag(t.flag) OVER (PARTITION BY t.id
                                                                           ORDER BY createdtime) recentflag
                                                         FROM elbat t) x
                                                         WHERE x.flag = 0
                                                               AND x.recentflag = 1) y
                        WHERE y.rn = 1
                 UNION ALL
                 SELECT y.id,
                        y.createdtime,
                        y.flag FROM (SELECT x.id,
                                            x.createdtime,
                                            x.flag,
                                            row_number() OVER (PARTITION BY x.id
                                                               ORDER BY x.createdtime DESC) rn
                                            FROM (SELECT t.id,
                                                         t.createdtime,
                                                         t.flag,
                                                         lag(t.flag) OVER (PARTITION BY t.id
                                                                           ORDER BY createdtime) recentflag
                                                         FROM elbat t) x
                                                         WHERE x.flag = 1
                                                               AND x.recentflag = 0) y
                        WHERE y.rn = 1) z
           ORDER BY z.createdtime DESC;
    

    【讨论】:

      【解决方案3】:

      CTE 中使用lag() 获取每行的前一个标志,然后使用NOT EXISTS

      with cte as(
          select *, lag(flag) over(partition by id order by createdtime) prevflag
          from tablename 
      ) 
      select c.id, c.createdtime, c.flag
      from cte c
      where c.flag <> c.prevflag 
      and not exists (
        select 1 from cte
        where id = c.id and flag = c.flag and prevflag = c.prevflag and createdtime > c.createdtime
      )
      order by c.createdtime
      

      或者:

      with cte as(
          select *, lag(flag) over(partition by id order by createdtime) prevflag
          from tablename 
      )
      select id, max(createdtime) createdtime, flag
      from cte
      where flag <> prevflag 
      group by id, flag
      order by createdtime
      

      请参阅demo
      结果:

      > id | createdtime         | flag
      > -: | :------------------ | ---:
      >  5 | 2019-11-02 14:30:00 |    1
      >  5 | 2020-08-01 14:30:00 |    0
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-07-30
        • 2017-12-12
        • 1970-01-01
        • 1970-01-01
        • 2020-01-14
        • 2013-11-20
        • 2013-06-13
        • 1970-01-01
        相关资源
        最近更新 更多