我有一个包含大量事件的事务表,其中包含许多事件类型。我想对两个相关的事件类型做一些分析:transit-send和transit-receive。该表的示例如下所示:
ItemID | EventType | TransactionDate
--------|-----------|-----------------
11111 | send | 2013-07-02
22222 | receive | 2013-07-02
33333 | receive | 2013-07-03
22222 | send | 2013-07-03
11111 | receive | 2013-07-04
55555 | send | 2013-07-05
22222 | receive | 2013-07-06
44444 | send | 2013-07-07
22222 | send | 2013-07-07
44444 | receive | 2013-07-08
55555 | receive | 2013-07-09
22222 | receive | 2013-07-10
33333 | send | 2013-07-11
我需要做的是找到每个发送 - 接收配对,其中接收是发送后的第一个:11111在7/2发送并在7/4接收。 22222在7/3发送,然后在7/6收到。但是,在7/2和7/10也收到了22222。
我最初尝试使用连接来获得一些快速结果:
SELECT a.ItemID, a.EventType, a.TransactionDate, b.EventType, b.TransactionDate, b.TransactionDate - a.TransactionDate AS "Days"
FROM Transactions a, Transactions b
WHERE a.ItemID = b.ItemID
AND a.EventType = 'send'
AND b.EventType = 'receive'
AND a.TransactionDate < b.TransactionDate
我知道这不会得到我想要的实际结果,但这是一个快速而肮脏的近似。问题是,对于之后的每个接收,它将为同一发送返回多行(请注意第一个22222发送事务的重复):
a.ItemID | a.EventType | a.TransactionDate | b.EventType | b.TransactionDate | Days
----------|-------------|-------------------|-------------|-------------------|------
11111 | send | 2013-07-02 | receive | 2013-07-04 | 2
22222 | send | 2013-07-03 | receive | 2013-07-06 | 3
22222 | send | 2013-07-03 | receive | 2013-07-10 | 7
22222 | send | 2013-07-07 | receive | 2013-07-10 | 3
44444 | send | 2013-07-07 | receive | 2013-07-08 | 1
55555 | send | 2013-07-05 | receive | 2013-07-09 | 4
Google建议我可以使用LEAD分析功能。这看起来很有希望,但鉴于我对它不熟悉,我不确定如何(或者如果)我可以使它适合我的模型,其中链接线没有直接配对(找到11111的下一个交易,无论类型)。我挂断了试图限制第一个交易发送,第二个交易接收。我怎样才能做到这一点?
答案 0 :(得分:2)
也许这会有所帮助:
select t.*,
lead(EventType) over (partition by ItemId order by TransactionDate) as NextEventType,
lead(TransactionDate) over (partition by ItemId order by TransactionDate) as NextEventType,
from Transactions t
然后您可以计算天数,但需要使用子查询:
select t.*,
(case when NextEventType = 'receive' then NextEventDate - EventDate end) as days
from (select t.*,
lead(EventType) over (partition by ItemId order by TransactionDate) as NextEventType,
lead(TransactionDate) over (partition by ItemId order by TransactionDate) as NextEventDate
from Transactions t
) t
where t.EventType = 'send'
有两个挑战。如果连续两个发送同一个项目但没有接收,则会发生一种情况。这将检测到这种情况并将接收分配给第二次发送。
另一个是时机。如果您在同一天有一个事件的发送和接收,则没有足够的信息可以知道哪个事先发生。这可能会造成问题。您的数据没有任何此类示例。如果出现这种情况,解决方案是包括时间戳。