SQL 获取最后一次数字设置为 1

Posted

技术标签:

【中文标题】SQL 获取最后一次数字设置为 1【英文标题】:SQL get the last time number was set to 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)

【问题讨论】:

【参考方案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

【讨论】:

以上是关于SQL 获取最后一次数字设置为 1的主要内容,如果未能解决你的问题,请参考以下文章

SQL - 如何让sql自动设置下一个id

数组中只出现一次的数字

js怎么控制文本框只能输入数字

js怎么控制文本框只能输入数字

页面控件未设置为中间

获取 ArrayList 值并将其设置为按钮单击时的 TextView 不工作 - RecyclerView