繁体   English   中英

查询以查找Oracle中一个月的丢失日期

[英]Query to find the missing dates of a month in Oracle

这是Oracle 10g的出勤表中我的Record_Date (Date)列中的可用日期。您可以找到日期04/06/2016 08/06/2016 16/06/2016 23/06/2016 29/06/2016 are序列中缺少。

   **Record_Date**  

    01/06/2016
    02/06/2016
    03/06/2016
    05/06/2016
    06/06/2016
    07/06/2016
    09/06/2016
    10/06/2016
    12/06/2016
    13/06/2016
    14/06/2016
    15/06/2016
    17/06/2016
    18/06/2016
    19/06/2016
    20/06/2016
    21/06/2016
    22/06/2016
    24/06/2016
    25/06/2016
    26/06/2016
    27/06/2016
    28/06/2016
    30/06/2016
    01/07/2016

我只需要查询以查找特定月份(以及以后的年份)中缺少的日期。

请告诉我一种方法

with 
nums(num )
as
(select 0 from dual
union all
select num + 1 from nums
  where num < (select max(col) from qtable)- (select min(col) from qtable)
),

date_btwn(dat) 
as(select num + (select min(col) from qtable) from nums)

select  dat from date_btwn
minus
select col from qtable;

内联视图 nums将从开始日期开始生成所有要添加的数字。 date_btwn包含表中开始日期结束日期之间的所有日期。 我们使用减号排除表中的日期。

您可以使用以下一种:

WITH all_days AS 
    (SELECT DATE '2016-06-01' + LEVEL-1 AS the_day
    FROM dual
    CONNECT BY DATE '2016-06-01' + LEVEL-1 <= DATE '2016-06-30')
SELECT the_day
FROM all_days
WHERE the_day <>ALL (SELECT Record_Date FROM Attendance);

或者,如果您希望更动态地使用它:

WITH all_days AS 
    (SELECT START_DATE + LEVEL AS the_day
    FROM dual
        CROSS JOIN 
            (SELECT 
                TRUNC(MIN(Record_Date), 'MM') -1 AS START_DATE, 
                TRUNC(LAST_DAY(MAX(Record_Date))) AS END_DATE 
            FROM Attendance)
    CONNECT BY START_DATE + LEVEL <= END_DATE)
SELECT the_day
FROM all_days
WHERE the_day <>ALL (SELECT Record_Date FROM Attendance);

请注意, <>ALLNOT IN相同-这只是我个人的喜好。

您需要生成所有日期,并且必须找到丢失的日期。 下面与CTE我已经做到了

使用CTE not in Query中:

            with calendar as (
                    select rownum - 1 as daynum,
                    to_date('1-jun-2016') + (rownum - 1) as monthdate
                    from dual )
            select monthdate  as monthdate
            from calendar              
            where monthdate  not in (
            SELECT 
            Record_Date
            FROM Attendance      )  
             and monthdate   >=  to_date('1-jun-2016')  /* CHANGE as per need */
             and monthdate   <  to_date('1-jul-2016')  /* CHANGE as per need */

或使用CTEleft join查询:

            with calendar as (
                    select rownum - 1 as daynum,
                    to_date('1-jun-2016') + (rownum - 1) as monthdate
                    from dual )
            select monthdate  as monthdate
            from calendar C left join Attendance A on A.Record_Date=c.monthdate
            where A.Record_Date is  null
             and monthdate   >=  to_date('1-jun-2016')  /* CHANGE as per need */
             and monthdate   <  to_date('1-jul-2016')  /* CHANGE as per need */

按照日期列格式,先将其更改为有效格式,再进入选择查询,然后再使用此查询。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM