【问题标题】:Delete rows by date in ANSI SQL在 ANSI SQL 中按日期删除行
【发布时间】:2014-09-17 14:28:24
【问题描述】:

我想从最后一天删除行,我有一个日期列,我该如何在 ansi 中执行此操作?

delete from mytable where mydate < current_date;

此查询同时删除昨天和今天的记录,我想保留今天的记录(“今天”是从上午 12 点开始)

【问题讨论】:

  • 这应该可以工作(在 Postgres 中可以)。但是,即使您特别提到了 ANSI SQL,也可能存在行为不同的 DBMS。我猜你正在使用 Oracle 来解释这种行为
  • 您使用的是哪个数据库?
  • @a_horse_with_no_name 是的,我正在使用 oracle,但我需要在 ansi 中进行此操作
  • @AnkitBajpai 现在是 oracle,但我需要在 ansi 中执行此操作
  • @AnkitBajpai:Oracle确实了解current_date

标签: sql ansi-sql


【解决方案1】:

您的语句是有效的 ANSI SQL,并且可以在任何符合关于DATE 处理的 ANSI SQL 规范的 DBMS 上运行。

Oracle 的情况有所不同:DATE 列/值也总是包含时间。所以current_date(或sysdate,在本次讨论中相同)不会返回2014-09-17,但例如2014-09-17 16:54:12.

现在,如果您的表中有一行包含2014-09-17 08:54:12,则条件mydate &lt; current_date 将为真,因为08:54:12 小于16:54:12,因此该行将被删除。

您需要将您的语句重写为:

delete from mytable 
where trunc(mydate) < trunc(current_date);

trunc()DATE 的时间部分设置为00:00:00,因此比较的行为就像不涉及时间部分一样(因为两个比较值相同)。

如果您真的非常需要在 ANSI SQL 中编写此条件并考虑到 Oracle 的非标准 DATE 处理,您需要执行以下操作:

select * 
from mytable
  where (extract(year from mydate) < extract(year from current_date))
     or (extract(year from mydate) = extract(year from current_date) and extract(month from mydate) < extract(month from current_date))
     or (extract(year from mydate) = extract(year from current_date) and extract(month from mydate) = extract(month from current_date) and extract(day from mydate) < extract(day from current_date));

如图所示的extract() 函数是ANSI SQL。

【讨论】:

  • 无论如何trunc(current_date) 但肯定trunc(mydate) 是不必要的?毕竟,如果 '2014-09-17 00:00:00' &lt; x 之后的同一日期,例如'2014-09-17 15:25:00' &lt; x 也是如此。不必要地截断 mydate 的最大问题是它使查询不可 SARGable。
猜你喜欢
  • 1970-01-01
  • 2021-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-24
相关资源
最近更新 更多