如何生成sysdate-30和sysdate + 30之间所有日期的列表?

时间:2012-02-06 20:33:25

标签: sql oracle gaps-and-islands

目的&我到目前为止

我正在尝试创建一个检查缺少人工交易的视图。该视图将被提供给Crystal报告。

在这种情况下,视图应该采用sysdate + 30和sysdate -30之间的所有日期,然后应该为每个日期的活动员工留下外部联接所有人工记录。然后,它计算每个员工每个日期的人工交易数量。

这将传递给Crystal Report,后者将根据特定日期范围(视图在+/- 30范围内)进行过滤。从那里开始,Crystal中每位员工的总计数将会计算,员工将显示零交易。

问题

在没有吐出每个日期的列表的情况下,最初,我正在为每个日期使用人工交易,但有些日期没有任何计数。这些人显示空交易日期为零小时。这表明他们在整个期间都没有收费,这是有道理的。

但是,当Crystal对该数据进行过滤并选择范围时,我相信它会遗漏这些空值,因此不允许我显示没有时间提交的所有人。

问题

有没有办法在视图中执行“选择(sysdate + 30)和(sysdate-30)之间的每个日期”,以便我可以用它来比较所有时间?

SQL(供参考)

SELECT QUERY.LABORRECLABORCODE
       , QUERY.LABORRECEMPLOYEENUM
       , QUERY.PERSONRECDISPLAYNAME
       , QUERY.TRANSSTARTDATE
       , COUNT(TRANSROWSTAMP) AS ROWCOUNT
FROM   (SELECT *
        FROM  (SELECT LABOR.LABORCODE      AS LABORRECLABORCODE
                      , LABOR.LA20         AS LABORRECEMPLOYEENUM
                      , PERSON.DISPLAYNAME AS PERSONRECDISPLAYNAME
               FROM   LABOR
                      LEFT OUTER JOIN PERSON
                        ON ( LABOR.LABORCODE = PERSON.PERSONID )
               WHERE  LABOR.STATUS = 'ACTIVE'
                  AND LABOR.LA20 IS NOT NULL
                  AND PERSON.DISPLAYNAME IS NOT NULL
                  AND LOWER(PERSON.DISPLAYNAME) NOT LIKE '%kimball%'
                  AND LOWER(PERSON.DISPLAYNAME) NOT LIKE '%electrico%'
                  AND LOWER(PERSON.DISPLAYNAME) NOT LIKE '%misc labor cost adj%'
                  AND LOWER(PERSON.DISPLAYNAME) NOT LIKE '%brossoit%'
                  AND LOWER(PERSON.DISPLAYNAME) NOT LIKE '%brossiot%')PERSONINFO
              LEFT OUTER JOIN (SELECT STARTDATE   AS TRANSSTARTDATE
                                      , LABORCODE AS TRANSLABORCODE
                                      , ROWSTAMP  AS TRANSROWSTAMP
                               FROM   LABTRANS
                               WHERE  STARTDATE BETWEEN ( SYSDATE - 30 ) AND ( SYSDATE + 30 ))LABTRANSLIMITED
                ON ( PERSONINFO.LABORRECLABORCODE = LABTRANSLIMITED.TRANSLABORCODE ))QUERY
GROUP  BY LABORRECLABORCODE
          , TRANSSTARTDATE
          , LABORRECEMPLOYEENUM
          , PERSONRECDISPLAYNAME
ORDER  BY LABORRECLABORCODE
          , TRANSSTARTDATE
; 

3 个答案:

答案 0 :(得分:16)

select trunc(sysdate)+31-level from dual connect by level <=61

这是生成任意值列表的好方法。

答案 1 :(得分:0)

或另一种方法:选择一个包含大量行的表

select sysdate+30 - rownum from user_objects where rownum<61

答案 2 :(得分:0)

为了满足我在某个范围内成为sysdate -30和sysdate + 30的要求,这似乎是目前最优雅的做事方式:

SELECT *
FROM   (SELECT TRUNC(SYSDATE - ROWNUM) DT
        FROM   DUAL
        CONNECT BY ROWNUM < 31
        UNION
        SELECT TRUNC(SYSDATE + ROWNUM) DT
        FROM   DUAL
        CONNECT BY ROWNUM < 31)DATERANGE; 

我使用了来自this answerthis SO Question并扩展了这种想法,使用联合来加入分开指向的查询。