SQL查找给定类别的行之间的平均时间差

时间:2018-01-03 13:29:52

标签: sql sql-server datetime group-by

我浏览了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服务器),但是感谢任何帮助!

4 个答案:

答案 0 :(得分:1)

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

编辑: 添加了我没有注意到的最终字段,道歉。

答案 1 :(得分:0)

以下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

答案 2 :(得分:0)

您需要在每笔交易之间存在日期差异并对其进行平均。

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

答案 3 :(得分:0)

只是为了笑容,我添加了一个使用CTE的解决方案。如果第一个查询太大,您可能可以使用临时表。我在表中使用了@MatBailie创建脚本:

$('.widgetFontColor').ColorPicker({

     onBeforeShow: function (colpkr) {

        var ctx = document.createElement('canvas').getContext('2d');
        ctx.strokeStyle = $(this).css('backgroundColor');
        var hexColor = ctx.strokeStyle;
        $(this).ColorPickerSetColor(hexColor);

     },
     onChange:function(hsb,hex,rgb,ele){

     $(ele).parents('.forColor').find('.layoutColor').val('#' + hex);
     $(ele).parent().addClass("is-dirty"); 
     $(ele).css('backgroundColor', '#' + hex );

     console.log(ele);  
    },
    onSubmit: function(hsb, hex, rgb, el) {

        $(el).parents('.forColor').find('.layoutColor').val('#' + hex);
        $(el).ColorPickerHide();
    }
 });