SQL如何计算一个时间段内发生的事件数?

时间:2018-11-13 02:52:26

标签: sql sqlite sum window-functions datediff

我需要知道电话如何影响我们的客户

因此,我给客户打了电话之后,我需要查看他们是否在通话后1天内,7天之内或14天之内登录了他们的帐户。

在这种情况下,我该如何使用datediff?

enter image description here

2 个答案:

答案 0 :(得分:0)

您可以在SQL聚合方法中使用条件求和

SELECT SUM(CASE WHEN time > 1 AND time <= 7 THEN 1 ELSE 0 END)   AS LoggedInAfter1day,
       SUM(CASE WHEN time > 7 AND time <= 14 THEN 1 ELSE 0 END ) AS LoggedInAfter7day,
       SUM(CASE WHEN time > 14 THEN 1 ELSE 0 END )               AS LoggedInAfter14day
FROM ( SELECT (logged_in_time - call_time) As time FROM customers ) AS c

答案 1 :(得分:0)

假设;  -该表名为 logininfo ,  -根据 YYYY-MM-DD HH:MM (或Date And Time Functions支持的一种格式)存储call_time和logging_in_time

然后,我相信以下内容将满足您的要求:-

WITH 
        CTE1 AS (
            SELECT customer_id, strftime('%Y%m%d',logged_in_time) - strftime('%Y%m%d',call_time) AS daysafter  
            FROM logininfo 
            WHERE (strftime('%Y%m%d',logged_in_time) - strftime('%Y%m%d',call_time)) > 0 -- ignore login the same day
                AND customer_id = 1 -- must be for this customer
                AND date(call_time) = date('2018-01-01') -- must be in relation to this call (if wanted)
        )

SELECT (SELECT customer_id FROM CTE1 ORDER BY customer_id),
    (SELECT count() FROM CTE1 WHERE daysafter > 0 AND daysafter <= 1) AS 'logged in 1 day after',
    (SELECT count() FROM CTE1 WHERE daysafter > 0 AND daysafter <= 7) AS 'logged in 7 days after',
    (SELECT count() FROM CTE1 WHERE daysafter > 0 AND daysafter <= 14) AS 'logged in 14 days after'
;
  • 您将适当的customer_id和call_time应用于where子句。
  • 您的预期结果似乎不符合,因此,我给客户打了电话后,我需要查看他们是否在1天内,7天内或14天内登录了他们的帐户(例如通话后7天内)将包括通话后1天内的通话次数,依此类推。如果不是这种情况,只需要适当地更改最后3个WHERE子句即可。

假设一个表填充为:-

enter image description here

以上将导致:-

enter image description here

以下是使用的完整测试脚本:-

DROP TABLE IF EXISTS logininfo;
CREATE TABLE IF NOT EXISTS logininfo (customer_id INTEGER, call_time TEXT, logged_in_time TEXT);
INSERT INTO logininfo VALUES
    (1,'2018-01-01 11:30','2018-01-02 10:00'), 
    (1,'2018-01-01 11:30','2018-01-03 10:00'),
    (1,'2018-01-01 11:30','2018-01-04 10:00'),
    (1,'2018-01-01 11:30','2018-01-05 10:00'),
    (1,'2018-01-01 11:30','2018-01-06 10:00'),
    (1,'2018-01-01 11:30','2018-01-07 10:00'),
    (1,'2018-01-01 11:30','2018-01-08 10:00'),
    (1,'2018-01-01 11:30','2018-01-15 10:00'),
    (1,'2018-01-01 11:30','2018-01-16 10:00'),
    (1,'2018-01-01 11:30','2018-01-17 10:00'),

    (1,'2018-02-01 11:30','2018-02-14 10:00'),
    (1,'2018-02-01 11:30','2018-02-15 10:00'),
    (1,'2018-02-01 11:30','2018-02-16 10:00'),
    (1,'2018-02-01 11:30','2018-02-17 10:00'),
    (1,'2018-02-01 11:30','2018-02-18 10:00'),
    (1,'2018-02-01 11:30','2018-02-19 10:00'),

    (2,'2018-01-01 11:30','2018-01-02 10:00'),
    (2,'2018-01-01 11:30','2018-01-03 10:00'),
    (2,'2018-01-01 11:30','2018-01-04 10:00'),
    (2,'2018-01-01 11:30','2018-01-05 10:00'),
    (2,'2018-01-01 11:30','2018-01-15 10:00'),
    (2,'2018-01-01 11:30','2018-01-16 10:00'),
    (2,'2018-01-01 11:30','2018-01-17 10:00')
    ;

SELECT * FROM logininfo;

WITH 
        CTE1 AS (
            SELECT customer_id, strftime('%Y%m%d',logged_in_time) - strftime('%Y%m%d',call_time) AS daysafter  
            FROM logininfo 
            WHERE (strftime('%Y%m%d',logged_in_time) - strftime('%Y%m%d',call_time)) > 0 -- ignore login the same day
                AND customer_id = 1 -- must be for this customer
                AND date(call_time) = date('2018-01-01') -- must be in relation to this call (if wanted)
        )

SELECT (SELECT customer_id FROM CTE1 ORDER BY customer_id),
    (SELECT count() FROM CTE1 WHERE daysafter > 0 AND daysafter <= 1) AS 'logged in 1 day after',
    (SELECT count() FROM CTE1 WHERE daysafter > 0 AND daysafter <= 7) AS 'logged in 7 days after',
    (SELECT count() FROM CTE1 WHERE daysafter > 0 AND daysafter <= 14) AS 'logged in 14 days after'
;

注意,它不使用datediff,而是在查询中确定日期差。