查询缺少一个日期;只发生在今天

Sea*_*een 1 oracle query oracle-11g

我希望这应该是可重现的。

我在 Oracle 11g 上。我作为另一个查询的一部分使用的这个查询的行为很奇怪:

SELECT TRUNC(SYSDATE - ROWNUM) DATEITEM
                         FROM   DUAL
                         CONNECT BY ROWNUM <= 32
                         UNION
                         SELECT TRUNC(SYSDATE + ROWNUM) DATEITEM
                         FROM   DUAL
                         CONNECT BY ROWNUM <= 32
order by dateitem desc;
Run Code Online (Sandbox Code Playgroud)

这应该以降序返回今天日期前后 32 天。

它一直有效,一直有效,直到今天。

出于某种原因,这不会返回 9 月 26th。它从 25 号跳到 27 号。

我想不出这其中的韵律或原因。例如,这个查询确实在 25 日返回了 25 日(所以我没有证据表明它只遗漏了 sysdate,因为它昨天有效)。

我到底做错了什么?

Jus*_*ave 7

我不知道这个查询是如何返回当天的。 ROWNUM从 1 开始,所以TRUNC(sysdate - rownum)永远不会返回当天,也不会TRUNC(sysdate + rownum)。两边UNION正好返回 32 行,所以整个查询应该总是返回 64 行。如果您希望在今天之前 32 天、今天之后 32 天以及今天在您的结果集中,则需要 65 行。

此查询应返回 65 行,并应包括今天。

SELECT TRUNC(SYSDATE - ROWNUM) DATEITEM
FROM   DUAL
CONNECT BY ROWNUM <= 32
UNION
SELECT TRUNC(SYSDATE + ROWNUM - 1) DATEITEM
FROM   DUAL
CONNECT BY ROWNUM <= 33
order by dateitem desc;
Run Code Online (Sandbox Code Playgroud)

你也可以不写 UNION

SELECT TRUNC(SYSDATE - ROWNUM -33) DATEITEM
FROM   DUAL
CONNECT BY ROWNUM <= 65
order by dateitem desc;
Run Code Online (Sandbox Code Playgroud)

从性能的角度来看,使用一个、两个或三个子查询之间不太可能存在有意义的差异。如果您要将UNION多个集合放在一起,因为您知道没有重叠,您会希望使用 aUNION ALL而不是 aUNION来避免不必要的排序和DISTINCTUNION必须删除重复项,UNION ALL而不是)。