如何在上次记录后x天预计的记录迟到时选择统计数据?

时间:2015-12-07 14:20:41

标签: sql oracle11g

我在一个表中有配置信息的实体。如果'供应商'在“提醒日期”内没有做任何事情'这样做的最后一次,它就变得过期了。

    CREATE TABLE t_vendors
    (
      vendor_id NUMBER,
      vendor_name VARCHAR2 (250),
      reminder_days NUMBER
    );

    Insert into T_VENDORS (vendor_id, vendor_name, reminder_days)
    Values (12, 'sanity-test', 7);

并且应用程序会记录他们在使用此类数据进行此表时所执行的操作:

    CREATE TABLE t_vendor_events
    (
        vendor_event_id,
        vendor_id NUMBER (19,0),
        description VARCHAR2 (250),
        event_date DATE
    );

    Insert into t_vendor_events (vendor_event_id, vendor_id, description, event_date)
    Values (10015, 12, TO_DATE('11/9/2015 21:22:55', 'MM/DD/YYYY HH24:MI:SS'), 'one');
    Insert into t_vendor_events (vendor_event_id, vendor_id, description, event_date)
    Values (10016, 12, TO_DATE('11/16/2015 21:23:55', 'MM/DD/YYYY HH24:MI:SS'), 'two');
    Insert into t_vendor_events (vendor_event_id, vendor_id, description, event_date)
    Values (10017, 12, TO_DATE('11/30/2015 21:24:55', 'MM/DD/YYYY HH24:MI:SS'), 'three');
    Insert into t_vendor_events (vendor_event_id, vendor_id, description, event_date)
    Values (10018, 12, TO_DATE('12/01/2015 21:25:55', 'MM/DD/YYYY HH24:MI:SS'), 'four');

一旦我获得了比较值,我需要汇总数据以量化迟到:

  • 发生了多少事件
  • 他们过期的频率
  • 预期的内容(提醒天数值)
  • 他们平均迟到多少
  • 他们在最坏的时候迟到多少(最多)

我需要查看结果中的所有供应商,包括那些未能产生事件的供应商。

我能想到的所有解决方案都涉及创建额外的列并存储某种“迟到”。每个事件的数据。这虽然让我觉得是一种冗余,因为我知道所需的间隔(reminder_days),但我不知道什么样的嵌套选择会产生我需要的东西。

我更愿意坚持使用标准SQL,而且我不使用PL-SQL,但我可以在必要时使用特定于Oracle的语法。

结果看起来像这样(预期天数是提醒天数'列):

Vendor    Event     Overdue   Expected   Avg       Max
          Count     Count     Days       Elapsed   Elapsed
Mega1     5         2         10         12        20
Ole!      6         0         10         9         10
GoPunk    0         0         0          0         0
X-Dan     0         0         0          0         0 
RetroB    1         1         30         60        60

1 个答案:

答案 0 :(得分:0)

您可以使用lag获取上一个event_date并计算与当前event_date的差异。然后选择差异大于的行>供应商提醒_days。只需汇总最终结果,了解供应商迟到的频率。

with prev as 
(select lag(event_date) over(partition by vendor_id order by event_date) prevdt
 , t.* from t_vendor_events)
select v.vendor_id, v.vendor_name, event_date - nvl(prevdt, event_date) diff 
from prev p
join t_vendors v on p.vendor_id = v.vendor_id
where event_date - nvl(prevdt, event_date) > v.reminder_days