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

发布于 2025-01-02 14:48:45 字数 2284 浏览 1 评论 0原文

目的与目的到目前为止我所得到的

我正在尝试创建一个视图来检查丢失的劳动力交易。该视图将被输入到水晶报表中。

在这种情况下,视图应获取 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
; 

Purpose & What I've Got So Far

I am attempting to create a view which checks for missing labor transactions. The view will be fed to a Crystal report.

In this case, the view should take all dates between sysdate+30 and sysdate -30, and then should left outer join all labor records by active employees for each of those dates. It then gives a count of the number of labor transactions for each employee for each date.

This gets passed to the Crystal Report, which will filter based on a specific date range (within the +/- 30 range by the view). From there, the count of all days will summed up per employee in Crystal, and employees will show up which have zero transactions.

The Problem

Without spitting out a list of every date, initially, I'm using labor transaction for each date, but some have no counts for any date. These folks show null transaction dates with zero hours. This indicates they have no charges for the entire period, which makes sense.

However, when Crystal does a filter on that data and selects a range, I believe it leaves out these null values, thus not allowing me to show the full range of folks who don't have time submitted.

The Question

Is there a way to do the equivalent of "select every date between (sysdate+30) and (sysdate-30)" in a view, so that I can use it to compare all the time against?

The SQL (for reference)

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
; 

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

留蓝 2025-01-09 14:48:45
select trunc(sysdate)+31-level from dual connect by level <=61

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

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

This is a good method for generating any arbitrary list of values.

大海や 2025-01-09 14:48:45

或者另一种方法:选择一个有很多行的表

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

Or another method: pick a table with a lot of rows

select sysdate+30 - rownum from user_objects where rownum<61
时光病人 2025-01-09 14:48:45

为了满足我对 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; 

我使用 这个答案来自这个SO问题并扩展了这个想法,使用union 来加入不同方向的查询。

In order to meet my requirements of being sysdate -30 and sysdate + 30 in a range, this seems be the most elegant way of doing things for now:

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; 

I used this answer from this SO Question and expanded upon that thinking, using a union to join the queries that went in separate directions.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文