我有这张桌子:
COD(整数)(PK) ID(Varchar) 日期(日期)
我只是想从今天开始获取新ID,与昨天相比(今天的ID从昨天不存在)
这只需要一个查询,最高效率,因为该表将有4-5百万条记录
作为一名java开发人员,我能够通过2个查询来完成这项工作,但只有一个是我所不知道的,所以任何帮助都会非常感激
编辑:日期格式为dd / mm / yyyy,每天每个ID可能会有0或1次
答案 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 );