计算流失模型

时间:2019-01-03 22:54:38

标签: sql sql-server

我正在尝试分析与我们在前一年(2017年)但今年(2018年)有业务往来的客户。我如何获得2018年激怒我们的客户的姓名。我正在使用SSMS 2016。

样本数据:

Client_ID    Client_Name     Order_Date           Revenue         
   214         ssms            2/4/2017             10000
   344         oracle          2/14/2017            9000
   754         postgresql      7/17/2017            15000
   154         toad            9/27/2017            14852
   854         teradata        12/14/2017           54111
   654         sybase          10/25/2017           85477
   214         ssms            3/25/2018            25000
   854         teradata        5/14/2018            35000
   654         sybase          10/24/2018           45000
  .........................................

select client_id, client_name
from my_table
where year(order_date) = 2017
and year(order_date) <> 2018

上面的查询返回了2017年的客户,但是并没有告诉您是否预先过滤了2018年的数字。

请求的结果:

Client_ID         Client_Name
  754             postgresql
  344             oracle
  154             toad

3 个答案:

答案 0 :(得分:2)

您可以使用存在作为

select client_id, client_name
from T tt
where year(order_date) = 2017
      and not exists(select 1 from t where client_id = tt.client_id and year(order_date) = 2018)

Demo

您也可以将IN()用作

SELECT *
FROM T
WHERE Order_Date >= '2017-01-01'
      AND
      Order_Date <= '2017-12-31'
      AND
      Client_ID NOT IN(
        SELECT Client_ID
        FROM T
        WHERE Order_Date >= '2018-01-01'
              AND
              Order_Date <= '2018-12-31'
      )

答案 1 :(得分:1)

您可以使用NOT EXISTS和相关的子查询。

SELECT t1.client_id,
       t1.client_name
       FROM my_table t1
       WHERE t1.order_date >= '2017-01-01'
             AND t1.order_date < '2018-01-01'
             AND NOT EXISTS (SELECT *
                                    FROM my_table t2
                                    WHERE t2.client_id = t1.client_id
                                          AND t2.order_date >= '2018-01-01'
                                          AND t2.order_date < '2019-01-01');

您可能还希望重写条件,以不再使用year()列上的order_date函数,而是与范围进行比较,以便可以将索引用于该列。

答案 2 :(得分:1)

我通常使用'having'子句来完成此任务,尽管如果您要处理大量数据,则可能需要更有效的方法。

select client_name, max(year(order_date)) as final_year from my_table group by client_name having max(year(order_date)) = 2018

以上内容将返回所有最后一次订购时间为2018年的客户。

包括其他“具有”条件,例如:

and min(year(order_date)) < 2018

将排除2018年首次交易的客户。

希望这足以满足您的目的。

不使用您的确切模式名称等道歉