Query missing one date; only happened today

oracleoracle-11gquery

This should be pretty reproducible I hope.

I'm on Oracle 11g. This query, which I use as part of another query, is acting strangely:

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;

This should return 32 days before and after today's date, in descending order.

It has always worked, and always had, until today.

For some reason, this does not return September 26th. It skips right from 25 to 27th.

I cannot figure a rhyme or reason for this. This query did return the 25th on the 25th for example (and so I have no evidence that it leaves out only sysdate, as it worked yesterday).

What the heck have I done wrong here?

Best Answer

I don't see how this query could ever have returned the current day. ROWNUM starts with 1 so TRUNC(sysdate - rownum) will never return the current day and neither will TRUNC(sysdate + rownum). Both sides of your UNION return exactly 32 rows so the entire query should always return 64 rows. If you want 32 days before today, 32 days after today, and today in your result set, it would need to be 65 rows.

This query should return 65 rows and should include today.

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;

You can also write it without any UNION

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

From a performance standpoint, it is unlikely that there will be a meaningful difference between using one, two, or three subqueries. If you are going to UNION multiple sets together, since you know there are no overlaps, you would want to use a UNION ALL rather than a UNION to avoid an unnecessary sort and DISTINCT (UNION has to remove duplicates, UNION ALL does not).