oracle 不符合SQL语法[已关闭]

zbwhf8kr  于 2023-11-17  发布在  Oracle
关注(0)|答案(2)|浏览(121)

已关闭。此问题需要更多focused。目前不接受回答。
**要改进此问题吗?**更新此问题,使其仅针对editing this post的一个问题。

9小时前关闭
Improve this question
我正在使用供应商软件,使我能够从他们的现代Oracle数据库(18c)中的数据创建报告。其中一个报告在返回大量数据时遇到麻烦。供应商告诉我,我的SQL是“不符合”。他们说,SQL这样的...

select a.Name
, a.Descr

from tblA a
  inner join tblB b on b.aID = b.aID
  inner join tblC c on c.bID = b.bID

where sysdate between c.StartDate and c.EndDate
  and c.Name in ('X', 'Y', 'Z')

字符串
是错的而这...

select a.Name
, a.Descr

from tblA a
, tblB b

where b.aID = b.aID
  and b.bID in (
    select c.bID
    from tblC c
    where sysdate between c.StartDate and c.EndDate
      and c.Name in ('X', 'Y', 'Z')
  )


是正确的
这是一个戏剧性的简化例子。最初的查询是巨大的,但这基本上是我被告知的差异造成的问题。
我很困惑,因为我没有看到任何有意义的区别。
1.这些查询会产生不同的结果吗?

  1. INNER JOIN是否会导致“in(subquery)”语法避免的重复?
    1.如何使用子查询增加任何价值?它可以更快吗?
    1.“逗号”样式的连接不是在20年前就被弃用了吗?
ep6jt1vc

ep6jt1vc1#

首先,我假设b.aID = b.aID是一个错别字,应该是b.aID = a.aID
然后,奇怪的是,他们希望你使用逗号连接(from tblA a, tblB b),就像在20世纪80年代所做的那样。这是一个过时的语法,现在不应该使用。
但是,是的,原始查询可能会导致重复的结果行。如果你只想从tblA中选择数据,那么只从tblA中选择并将条件放在WHERE子句中。我想这就是他们试图通过将tblC放入IN子句来做的事情。一个好主意,应该看起来像这样:

SELECT a.name, a.descr
FROM tbla a
WHERE a.aid IN 
(
  SELECT b.aid
  FROM tblb b 
  INNER JOIN tblc c ON c.bid = b.bid
  WHERE SYSDATE BETWEEN c.startdate AND c.enddate
  AND c.name IN ('X', 'Y', 'Z')
);

字符串
回答您的问题:
1.这些查询会产生不同的结果吗?是的。

  1. INNER JOIN是否会导致“in(subquery)”语法避免的重复?
    1.如何使用子查询增加任何价值?它可以更快吗?是的,更快,不产生重复。
    1.“逗号”风格的连接不是在20年前就被弃用了吗?实际上,甚至在30年前就被弃用了,但Oracle晚了10年才采用这种语法。所以,是的。
    线
WHERE SYSDATE BETWEEN c.startdate AND c.enddate


startdate和enddate可能是日期,而SYSDATE也包含时间。因此,我们希望SYSDATE位于日期范围内,但取决于enddate是包含性的还是排除性的,这应该是

WHERE c.startdate <= SYSDATE AND c.enddate > SYSDATE


WHERE c.startdate <= SYSDATE AND c.enddate > SYSDATE - INTERVAL '1' DAY


为了不把接下来的午夜也算进去

polhcujo

polhcujo2#

我认为供应商可能并没有试图使Oracle原生与ANSI连接语法成为问题。我认为他们建议的重写表明,您对tblC的连接不适当地增加了行数(如果c.bid在给定日期的tblC中不是唯一的),并建议使用子查询,这样它就不会使行相乘。还有其他方法可以做到这一点,但是他们的建议是可以的,也就是说,对于你的问题,
INNER JOIN是否会导致“in(subquery)”语法避免的重复?
是的。这可能就是关键所在。或者可能是他们试图优化你的查询,并提供他们认为会更快的东西。这可能是也可能不是,但同样,子查询才是关键,而不是连接语法。
说到原生的Oracle join语法,与这个论坛上的大多数其他人一直说的相反,它没有任何问题。它从未被弃用过,并且仍然有大量的语法在使用。这在很大程度上是风格和个人用法的问题。这可能是供应商最熟悉的,可能不是他们说你应该改变的。选择你喜欢的语法,然后跟着它走。

相关问题