繁体   English   中英

SQL如何在值更改时检索第一行?

[英]SQL How to retrieve first row when value changed?

我有一个带有 ID、日期和标志的表。 我想检索标志已从 0 显式更改为 1 的某一年内的第一条记录。

ID    DATE        FLAG
1    2019-01-31     0
1    2019-02-28     1
1    2019-03-31     1

2    2019-01-31     1
2    2019-02-28     1
2    2019-03-31     1
2    2019-04-30     0
2    2019-05-31     1

3    2019-01-31     0
3    2019-02-28     1
3    2019-03-31     0
3    2019-04-30     1

所以,我预期的结果将是1这将是2019年1月31日,2将被排除在外,而3将是2019年2月28日。

到目前为止,我有这个查询在大多数情况下都有效,但是当我进行 QA 时,似乎该查询不排除那些从 1 开始,切换到 0,然后返回到 1 的查询。

询问

SELECT t.ID,
    Date, 
    Flag
 FROM table t
WHERE Flag = '1' 
  AND t.Date > (SELECT MAX(t2.Date) FROM table t2 WHERE t2.ID = t.ID AND t2.Flag = '0' AND t2.Date BETWEEN '2019-01-01' AND '2019-12-31') 
AND t.Date BETWEEN '2019-01-01' AND '2019-12-31'
ORDER BY ROW_NUMBER() OVER (PARTITION BY ID ORDER BY Date);

任何帮助都会很棒,谢谢!

编辑:我添加了SQLFiddle

使用lag()获取前一个标志,然后聚合:

select id, min(date)
from (select *,
             lag(flag) over (partition by id, year(date) order by date) as prev_flag
      from temp
     ) t
where flag = 1 and prev_flag = 0
group by id, year(date);

SQL小提琴

这将返回每年的结果。 当然,如果您愿意,您可以在子查询中按年份进行过滤。

我知道您想要第一个1 - 对于仅以0开头的系列。

如果您运行的是 MySQL 8.0,则可以为此使用窗口函数:

select id, min_date
from (
    select 
        id,
        flag,
        row_number() over(partition by id order by date) rn,
        min(case when flag = 1 then date end) over(partition by id) min_date
    from mytable
) t
where rn = 1 and flag = 0

子查询按date具有相同id的记录进行排名,并计算组中第一个1标志的日期; 每个组的第一条记录上的外部查询过滤器,确保它有一个0标志,并显示计算的日期。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM