Sql 查询以查找Oracle中缺少的月份日期
以下是Oracle 10g考勤表中“我的记录日期”列中的可用日期。您可以发现序列中缺少2016年6月4日2016年6月8日2016年6月16日2016年6月23日2016年6月29日Sql 查询以查找Oracle中缺少的月份日期,sql,oracle,Sql,Oracle,以下是Oracle 10g考勤表中“我的记录日期”列中的可用日期。您可以发现序列中缺少2016年6月4日2016年6月8日2016年6月16日2016年6月23日2016年6月29日 **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
**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将生成从开始日期开始添加的所有编号。日期包含表中开始日期和结束日期之间的所有日期。我们使用减号排除表中的日期。您需要生成所有日期,并且必须查找缺少的日期。下面是我用cte做的 使用CTE而不是inQuery: 根据datecolumn格式,首先将其更改为validformat以进入选择查询,然后使用此查询 您可以使用这个:
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);
请注意,所有内容都与不在相同-这只是我个人的偏好。我的方法:创建一个日历表并将其与上表连接,保留前者中的记录与后者中的记录不匹配。表中是否有标识列,以便我们可以相应地查询数据。如果没有,那么您应该有.Mybe可以帮助。@Tim日历表是虚拟表吗?@Suraz列是记录日期不为空的日期和行日期不为空的数字。例如,如果考勤表中缺少2016年6月1日,则此操作将失败,即将显示它。
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);