sql查询获取今天与昨天

时间:2017-06-26 21:50:25

标签: sql oracle

我有这张桌子:

COD(整数)(PK) ID(Varchar) 日期(日期)

我只是想从今天开始获取新ID,与昨天相比(今天的ID从昨天不存在)

这只需要一个查询,最高效率,因为该表将有4-5百万条记录

作为一名java开发人员,我能够通过2个查询来完成这项工作,但只有一个是我所不知道的,所以任何帮助都会非常感激

编辑:日期格式为dd / mm / yyyy,每天每个ID可能会有0或1次

3 个答案:

答案 0 :(得分:2)

这是一个仅基于一次基础数据的解决方案。它选择id和日期是昨天或今天(或两者)的日期。然后它是GROUPS BY id - 每个组将有一行或两行。然后按照组中的MIN日期为“今天”的条件进行过滤。这些是今天存在的,但昨天不存在。

DATE是Oracle关键字,最好不要用作列名。我改为DT。我还假设你的“dt”字段是一个纯粹的日期(在Oracle中可以是纯粹的,意思是:时间总是存在的时间是00:00:00)。

select   id
from     your_table
where    dt in (trunc(sysdate), trunc(sysdate) - 1)
group by id
having   min(dt) = trunc(sysdate)
;

编辑:戈登提出了一个很好的观点:也许在同一天,每个ID可能会有多个这样的行?在这种情况下,时间也可能与00:00:00不同。

如果是这样,可以调整解决方案:

select   id
from     your_table
where    dt >= trunc(sysdate) - 1 and dt < trunc(sysdate) + 1
group by id
having   min(dt) >= trunc(sysdate)
;

无论哪种方式:(1)基表只读一次; (2)列DT没有包含在任何函数中,因此如果该列上有索引,则可以使用它来访问所需的行。

答案 1 :(得分:1)

典型的方法是使用not exists

select t.*
from t
where t.date >= trunc(sysdate) and t.date < trunc(sysdate + 1) and
      not exists (select 1
                  from t t2
                  where t2.id = t.id and
                        t2.date >= trunc(sysdate - 1) and t2.date < trunc(sysdate)
                 );

这是一般解决方案。如果您知道每天最多只有一条记录,那么有更好的解决方案,例如使用lag()

答案 2 :(得分:1)

使用MINUS。我想你的日期列有一个时间部分,所以你需要截断它。

select id from mytable where trunc(date) = trunc(sysdate)
minus
select id from mytable where trunc(date) = trunc(sysdate) - 1;

我建议使用以下函数索引。没有它,查询将必须完全扫描表,这可能会非常慢。

create idx on mytable( trunc(sysdate) , id );