将 sql BETWEEN 子句从 ANSI 89 转换为 ANSI 92

Posted

技术标签:

【中文标题】将 sql BETWEEN 子句从 ANSI 89 转换为 ANSI 92【英文标题】:convert sql BETWEEN clause from ANSI 89 into ANSI 92 【发布时间】:2018-04-18 21:57:39 【问题描述】:

我正在尝试将 sql 语句从 ANSI 89 转换为 ANSI 92(意味着将“(+)”转换为“OUTHER JOIN”)

代码如下:

select a.*, p.price
from article a, prices p
where a.product_id = p.product_id(+)
and trunc(sysdate) + 1 between a.date_from and date_to
and trunc(sysdate) + 1 between p.date_from(+) and p.date_to(+);

我知道 (+) 指的是 LEFT 或 RIGHT JOIN,具体取决于放置它的位置,但我不知道如何转换最后一行 ( and trunc(sysdate) + 1 between p.date_from(+) and p.date_to(+) )

到目前为止,我做了以下工作:

select a.*, p.price
from article a
left join prices p
on a.product_id = p.product_id
where trunc(sysdate) + 1 between a.date_from and date_to

但我不知道如何转换最后一个条件。

有人可以帮忙吗?

谢谢,

【问题讨论】:

如果您使用left join,则不再需要(+)。关于不同的 ansi92 连接,here's an interesting older post 你可以阅读。此外,可以在left joinon 中使用between 标准(尽管很少这样做) and trunc(sysdate) + 1 between p.date_from and p.date_to;? @LukStorms:我的错误,我在尝试中忘记了“(+)”。无论如何,这篇文章很好,但已经知道 LEFT/RIGHT/INNER/FULL 连接之间的区别。我只想在 ANSI 92 中转换 p.date_from(+) 和 p.date_to(+) 之间的 and trunc(sysdate) + 1 @a_horse_with_no_name:它不工作。它限制了其余的条件并且不返回任何内容。 您需要将其放入 JOIN 条件中,不是 where 条件中。 【参考方案1】:

我假设每个表都有一个date_from 和一个date_to,并且您的意思是与这两个范围进行比较。在这种情况下,您在示例查询中留下了a.,所以我添加了它。当然,如果这不是您的意思,请随意调整...

所以明显的困难是,如果你添加

and trunc(sysdate) + 1 between p.date_from and p.date_to

where 子句,那么任何“生成的NULLs”记录都会被该条件错误处理。因此,您可以将其添加到外部连接条件中

select a.*, p.price
  from           article a
       left join prices p
    on a.product_id = p.product_id
   and trunc(sysdate) + 1 between p.date_from and p.date_to
 where trunc(sysdate) + 1 between a.date_from and a.date_to

从语义上讲,这有点小题大做,因为p 上的日期范围检查可能不是真正的连接条件;但这将“外部”语义应用于条件。另一个更明确的选择是

select a.*, p.price
  from           article a
       left join prices p
    on a.product_id = p.product_id
 where trunc(sysdate) + 1 between a.date_from and a.date_to
   and (trunc(sysdate) + 1 between p.date_from and p.date_to
        or p.product_id is null)

(您可能可以删除or 并只说between coalesce(p.date_from, trunc(sysdate)) and coalesce(p.date_to, trunc(sysdate)+2)) 或类似的东西,但这假设只有生成的-NULL 记录对于这些值会有NULL - 即没有@987654334 @record 实际上在这些列中有一个NULL。)

【讨论】:

以上是关于将 sql BETWEEN 子句从 ANSI 89 转换为 ANSI 92的主要内容,如果未能解决你的问题,请参考以下文章

如何在同一SQL查询中合并子句LIKE和BETWEEN?

使用 SQL Server 复制 Oracle 的 RANGE BETWEEN 窗口子句语法

SQL Server 索引如何帮助将 BETWEEN 用于给定查询

在 NodeJS 中使用 BETWEEN 子句

Oracle Between(范围)子句

Oracle Between(范围)子句