Sql 如何选择在某个日期丢失的记录,然后在以后重新出现?

Sql 如何选择在某个日期丢失的记录,然后在以后重新出现?,sql,oracle,Sql,Oracle,我有一个记录表,每年都会得到验证。我想检查的是在2014年1月3日之前验证过的记录,但随后在2019年11月3日被删除并取回 例如,2019年3月1日之前的max date=2014年3月1日写入同一id。但是,返回的记录还必须包括2019年3月1日的地址 我的表格: ID |Date 1 |3/1/2011 1 |3/1/2012 1 |3/1/2013 1 |3/1/2014 2 |3/1/2011 2 |3/1/2012 2 |3/1/2013 2

我有一个记录表,每年都会得到验证。我想检查的是在2014年1月3日之前验证过的记录,但随后在2019年11月3日被删除并取回

例如,2019年3月1日之前的max date=2014年3月1日写入同一id。但是,返回的记录还必须包括2019年3月1日的地址

我的表格:

ID  |Date
1   |3/1/2011
1   |3/1/2012
1   |3/1/2013
1   |3/1/2014    
2   |3/1/2011
2   |3/1/2012
2   |3/1/2013
2   |3/1/2014
2   |3/1/2019
3   |3/1/2011
3   |3/1/2012
3   |3/1/2013
3   |3/1/2014
3   |3/1/2015
3   |3/1/2019
对于上面的示例,我希望ID2作为符合条件的唯一记录返回

结果

ID
2
ID 1不包括2019年3月1日,因此被排除在外


ID 3的最大日期为2019年3月1日之前的2015年3月1日,因此被排除在外。

我不确定您使用的语法,但在postgresql中,您可以这样编写代码,在mysql中,如果我没有弄错,您应该更改为apply等

SELECT distinct id from my_table a
left join lateral(select count(distinct date) b4 from my_table b where b.id=a.id and date<='3/01/2014') befor on true
left join lateral(select count(distinct date) aftr from my_table b where b.id=a.id and date>='3/11/2019') after on true
where b4>0 and aftr>0

基本上,我所做的是在上述日期之前和之后加入日期计数,然后只显示在这两个日期都有不同ID的人。

我认为您可以使用条件聚合来做您想做的事情:

select id
from t
group by id
having max(case when date < date '2019-11-03' then date end) < date '2014-03-01' and
       sum(case when date = date '2019-11-03' then 1 else 0 end) > 0;
另一种方法是:

select t.*
from (select t.*,
             lag(date) over (partition by id order by date) as prev_date
      from t
     ) t
where date = date '2019-11-03' and
      prev_date < date '2019-03-01';
考虑匹配。 有很多SQL方法可以做到这一点,已经给出了一些很好的方法。一旦您熟悉了语法,这里有一个可以说更具可读性

您正在数据中查找与模式匹配的行。具体而言,2014年3月1日或之前的一行,紧接着2019年3月1日的一行,中间没有任何内容

每当你寻找与模式匹配的行时,你可以考虑在你的选择中使用MatCHYRead子句。这是您的案例:

SELECT id from mytable
MATCH_RECOGNIZE (
  PARTITION BY id
  ONE ROW PER MATCH
  PATTERN ( OLDER RECENT )
  DEFINE
    RECENT AS RECENT.dte = TO_DATE('3/1/2019','MM/DD/YYYY'),
    OLDER AS OLDER.dte <= TO_DATE('3/1/2014','MM/DD/YYYY')
)
这很好,因为您可以更改它以获得更多信息,而不必对整个方法进行太多更改

例如,假设您还想知道,对于每个id,该系列的结束日期是什么。也就是说,这是2014年3月1日或之前有数据的最后一个日期。只需稍作改动即可实现:

SELECT id, dropoff_date from mytable
MATCH_RECOGNIZE (
  PARTITION BY id
  MEASURES OLDER.dte AS dropoff_date
  ONE ROW PER MATCH
  PATTERN ( OLDER RECENT )
  DEFINE
    RECENT AS RECENT.dte = TO_DATE('3/1/2019','MM/DD/YYYY'),
    OLDER AS OLDER.dte <= TO_DATE('3/1/2014','MM/DD/YYYY')
)

您正在搜索滞后/超前功能。
SELECT id, dropoff_date from mytable
MATCH_RECOGNIZE (
  PARTITION BY id
  MEASURES OLDER.dte AS dropoff_date
  ONE ROW PER MATCH
  PATTERN ( OLDER RECENT )
  DEFINE
    RECENT AS RECENT.dte = TO_DATE('3/1/2019','MM/DD/YYYY'),
    OLDER AS OLDER.dte <= TO_DATE('3/1/2014','MM/DD/YYYY')
)
+----+--------------+
| ID | DROPOFF_DATE |
+----+--------------+
|  2 | 01-MAR-14    |
+----+--------------+