Oracle

查詢缺少一個日期;只發生在今天

  • May 28, 2017

我希望這應該是可以重現的。

我在 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;

這應該按降序返回今天日期前後 32 天。

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

出於某種原因,這不會返回 9 月 26 日。它從 25 日跳到 27 日。

我想不出一個押韻或原因。例如,此查詢確實在 25 日返回了 25 日(因此我沒有證據表明它只遺漏了 sysdate,因為它昨天有效)。

我到底做錯了什麼?

我看不出這個查詢是如何在當天返回的。 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;

你也可以不寫UNION

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

從性能的角度來看,使用一個、兩個或三個子查詢之間不太可能存在有意義的差異。如果您要一起處理UNION多個集合,因為您知道沒有重疊,您可能希望使用 aUNION ALL而不是 aUNION來避免不必要的排序並且DISTINCTUNION必須刪除重複項,UNION ALL而不是)。

我決定,因為它看起來不對,我會忽略我的使用者的評論,即它昨天有效,並在 sysdate 中聯合,以確保它總是出現。

以下是現在查詢的一部分,正在工作:

SELECT TRUNC(SYSDATE - ROWNUM) DATEITEM
FROM   DUAL
CONNECT BY ROWNUM <= 32

UNION
SELECT TRUNC(SYSDATE) DATEITEM
FROM DUAL

UNION
SELECT TRUNC(SYSDATE + ROWNUM) DATEITEM
FROM   DUAL
CONNECT BY ROWNUM <= 32

order by dateitem desc;

引用自:https://dba.stackexchange.com/questions/24997