2011-09-29 45 views
1

我想执行一次检查“是否有表中最后100天中的每一天都有一个条目”,其中该表具有类似引用日期列的内容,并且正在考虑加入子查询返回SYSDATE - 0,SYSDATE - 1,... SYSDATE - 100检查最近n天的行是否存在

更新(澄清):

  • 我需要知道哪些日期是在过去的n天失踪
  • 我想避免额外的表(也是临时表)

这是一个好方法吗?

回答

4

假设你的Oracle表看起来像这样...

CREATE TABLE DATE_TABLE (
    D DATE, 
    -- And other fields, PK etc... 
) 

...假设d包含“圆”的日期(即没有时间的日),下面的查询会给你:min_date:min_date + :day_count之间的所有失踪日期:

SELECT * 
FROM (
    SELECT (TO_DATE(:min_date) + LEVEL - 1) GENERATED_DATE 
    FROM DUAL 
    CONNECT BY LEVEL <= :day_count 
) 
WHERE 
    GENERATED_DATE NOT IN (SELECT D FROM DATE_TABLE) 

用简单的英语:

  1. 生成给定时间间隔(子查询)中的所有日期。
  2. 检查表中是否存在任何一个(超级查询)。
+0

最好的解决方案,我的答案:短,优雅,和规模很好到任意的时间间隔(尽管我实际上从不需要超过100天) – michael667

1

如果有AREN’吨任何间隙(如周末),则可以使用一个小技巧是

SELECT COUNT(DISTINCT somedate)=100 FROM sometable -- evaluates to boolean 
WHERE somedate>=sysdate-100; 

根据您的RDBMS,一个GROUP BY可能比COUNT DISTINCT工作得更快。

[发布澄清评论]

正如你现在已经解释过,我想你想的密集日期列表和你的表,然后COUNTGROUP BY之间的LEFT JOIN。如果你使用的是MySQL,在子查询中生成日期列表的方式已经被早期的stackoverflow所覆盖(我不知道MySQL几乎已经足以想到接受的答案)。在大多数其他数据库系统中更容易。

在永久日历表的链接中提到的解决方案也不是那么糟糕。

+0

我也想知道我没有行的日期 – michael667

1

在MySQL:

SELECT * FROM `table_name` WHERE `date_column` > DATE_SUB(CURDATE(), INTERVAL 99 DAY) 

MySQL Date Arithmetic

+0

如何从此查询中获取“缺失”日期? – michael667

+0

啊,我刚刚看过你的最新问题。获取不同的日期是很容易的,但如果不使用临时表,在MySQL中执行操作会更加困难。你能够使用程序吗? – megaflop

+0

没有程序允许 – michael667

2

这可能会帮助你:

create table your_table (a_date date not null); 

insert into your_table values (date(now()-interval 0 day)); 
insert into your_table values (date(now()-interval 1 day)); 
insert into your_table values (date(now()-interval 2 day)); 
insert into your_table values (date(now()-interval 3 day)); 
insert into your_table values (date(now()-interval 5 day)); 
insert into your_table values (date(now()-interval 6 day)); 
insert into your_table values (date(now()-interval 9 day)); 
insert into your_table values (date(now()-interval 10 day)); 
insert into your_table values (date(now()-interval 50 day)); 
insert into your_table values (date(now()-interval 60 day)); 
insert into your_table values (date(now()-interval 70 day)); 
insert into your_table values (date(now()-interval 80 day)); 
insert into your_table values (date(now()-interval 90 day)); 

select a_date,ifnull(datediff(next_date ,a_date)-1,0) as number_of_days_missing_after_date 
from 
(
select dt.a_date, 
(select min(a_date) from your_table dtp where dtp.a_date > dt.a_date and dtp.a_date >= date(now()-interval 100 day)) as next_date 
from 
(select a_date 
from your_table 
union select date(now()-interval 100 day)) dt 
where dt.a_date >= date(now()-interval 100 day) 
) a; 

应该给你的指示,以缺少哪些日期。

我已经创建了表your_table来代替您计划检查缺失日期的表格(以便我可以更清楚地向您说明我的示例)。

也许这个解决方案的唯一问题是,它不会给你一个缺失日期的列表 - 虽然它们可以通过查看(在示例中)a_date列和在a_date之后缺少的天数。

希望它有帮助&祝你好运!

+0

我正在寻找一个解决方案,无需额外的表 – michael667

+0

啊。我没有解释得很清楚。我创建的表格代表您希望查询缺失日期的表格。我已经更新了我的答案,试图让它更清晰。 –

3

这是你在找什么:

Select seqnum.date, count(issues.id) 
from 
(
SELECT 
    Curdate() - interval (TENS.SeqValue + ONES.SeqValue) day Date 
FROM 
    (
    SELECT 0 SeqValue 
    UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 
    UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 
    ) ONES 
CROSS JOIN 
    (
    SELECT 0 SeqValue 
    UNION SELECT 10 UNION SELECT 20 UNION SELECT 30 UNION SELECT 40 UNION SELECT 50 
    UNION SELECT 60 UNION SELECT 70 UNION SELECT 80 UNION SELECT 90 
    ) TENS 
) seqnum 
left join issues on (cast(issues.created_on as date) = seqnum.date) 
group by seqnum.date 

我跑这对一个管理平台的实例,看看有多少问题,在过去的100天创建,一天一天,包括天凡没有创建问题。相应地调整您的数据结构。享受:)

+0

+1,迄今为止最好的解决方案,但它不能很好地扩展,我希望有更优雅的东西;-) – michael667

+1

您可以在查询中包含数百个,然后在加入 –

+1

@ michael667之前过滤seqs:检查这些答案约翰和马丁史密斯:http://stackoverflow.com/questions/7513996/how-to-select-a-single-row-a-100-million-x –