我浏览了SO但是找不到确切的答案,或者可能是针对不同的语言。
假设我有一张表,其中每一行都是一笔交易记录:
trade_id customer trade_date
1 A 2013-05-01 00:00:00
2 B 2013-05-01 10:00:00
3 A 2013-05-02 00:00:00
4 A 2013-05-05 00:00:00
5 B 2013-05-06 12:00:00
我希望每个客户的交易时间,天数或天数之间的平均时间,以及自上次交易以来的天数。因此,例如对于客户A,交易1和3之间的时间是1天,交易3和4之间的时间是3天,平均为2.所以结束表看起来像这样(假设今天它是2013-05 -10):
customer avg_time_btw_trades time_since_last_trade
A 2.0 5.0
B 5.08 3.5
如果一个客户只有1个交易,我认为NULL可以作为输出。
甚至不确定SQL是最好的方法(我正在使用SQL服务器),但任何帮助表示赞赏!
SELECT
customer,
DATEDIFF(second, MIN(trade_date), MAX(trade_date)) / (NULLIF(COUNT(*), 1) - 1) / 86400.0,
DATEDIFF(second, MAX(trade_date), GETDATE() ) / 86400.0
FROM
yourTable
GROUP BY
customer
http://sqlfiddle.com/#!6/eb46e/7
编辑:添加了我没有注意到的最终字段,道歉。
以下SQL脚本使用您的数据并提供预期结果。
DECLARE @temp TABLE
( trade_id INT,
customer CHAR(1),
trade_date DATETIME );
INSERT INTO @temp VALUES (1, 'A', '20130501');
INSERT INTO @temp VALUES (2, 'B', '20130501 10:00');
INSERT INTO @temp VALUES (3, 'A', '20130502');
INSERT INTO @temp VALUES (4, 'A', '20130505');
INSERT INTO @temp VALUES (5, 'B', '20130506 12:00');
DECLARE @getdate DATETIME
-- SET @getdate = getdate();
SET @getdate = '20130510';
SELECT s.customer
, AVG(s.days_btw_trades) AS avg_time_between_trades
, CAST(DATEDIFF(hour, MAX(s.trade_date), @getdate) AS float)
/ 24.0 AS time_since_last_trade
FROM (
SELECT CAST(DATEDIFF(HOUR, t2.trade_date, t.trade_date) AS float)
/ 24.0 AS days_btw_trades
, t.customer
, t.trade_date
FROM @temp t
LEFT JOIN @temp t2 ON t2.customer = t.customer
AND t2.trade_date = ( SELECT MAX(t3.trade_date)
FROM @temp t3
WHERE t3.customer = t.customer
AND t3.trade_date < t.trade_date)
) s
GROUP BY s.customer
您需要在每笔交易之间存在日期差异并对其进行平均。
select
a.customer
,avg(datediff(a.trade_date, b.trade_date))
,datediff(now(),max(a.trade_date))
from yourTable a, yourTable b
where a.customer = b.customer
and b.trade_date = (
select max(trade_date)
from yourTable c
where c.customer = a.customer
and a.trade_date > c.trade_date)
#gets the one earlier date for every trade
group by a.customer
只是为了笑容,我添加了一个使用CTE的解决方案。如果第一个查询太大,您可能可以使用临时表。我在表中使用了@MatBailie创建脚本:
CREATE TABLE customer_trades (
id INT IDENTITY(1,1),
customer_id INT,
trade_date DATETIME,
PRIMARY KEY (id),
INDEX ix_user_trades (customer_id, trade_date)
)
INSERT INTO
customer_trades (
customer_id,
trade_date
)
VALUES
(1, '2013-05-01 00:00:00'),
(2, '2013-05-01 10:00:00'),
(1, '2013-05-02 00:00:00'),
(1, '2013-05-05 00:00:00'),
(2, '2013-05-06 12:00:00')
;
;WITH CTE as(
select customer_id, trade_date, datediff(hour,trade_date,ISNULL(LEAD(trade_date,1) over (partition by customer_id order by trade_date),GETDATE())) Trade_diff
from customer_trades
)
, CTE2 as
(SELECT customer_id, trade_diff, LAST_VALUE(trade_diff) OVER(Partition by customer_id order by trade_date) Curr_Trade from CTE)
SELECT Customer_id, AVG(trade_diff) AV, Max(Curr_Trade) Curr_Trade
FROM CTE2
GROUP BY customer_id