将 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 join
的on
中使用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
子句,那么任何“生成的NULL
s”记录都会被该条件错误处理。因此,您可以将其添加到外部连接条件中
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 Server 复制 Oracle 的 RANGE BETWEEN 窗口子句语法