如何计算丢失的客户

时间:2018-07-01 13:13:23

标签: sql sql-server tsql

如何计算上一年缺少的客户记录。样本输入2008具有客户端ID( 1,2,3,4,5,6 ),但2009仅具有客户端ID( 2和3 ),因此缺少客户端ID总数( 1、4、5、6 )的期望输出包含 2009 中的总数 4 。 2007年和2008年的方法相同。需要查询所需的输出。

表结构为

CREATE TABLE [dbo].[tblProductClient](
    [Year] [nchar](10) NULL,
    [Product] [nchar](10) NULL,
    [Client] [nchar](10) NULL,
    [TotalMissingClient] [int] NULL
) ON [PRIMARY]

表格样本数据

Year    Product Client  TotalMissingClient
2008        A    1          NULL
2008        A    2          NULL
2008        A    3          NULL
2007        B    3          NULL
2007        B    2          NULL
2008        B    1          NULL
2007        A    2          NULL
2009        A    2          NULL
2009        A    3          NULL
2008        A    4          NULL
2008        A    5          NULL
2008        A    6          NULL

所需的输出是

Year    Product Client  TotalMissingClient
2008        A      1            0
2008        A      2            0
2008        A      3            0
2007        B      3            NULL
2007        B      2            NULL
2008        B      1            NULL
2007        A      2            NULL
2009        A      2            4
2009        A      3            4
2008        A      4            0
2008        A      5            0
2008        A      6            0

2 个答案:

答案 0 :(得分:0)

我认为这可以满足您的要求:

select t.*,
       (count(distinct client) over () -
        count(distinct clinet) over (partition by year)
       ) as TotalMissingClient
from t;

A,SQL Server不支持带有窗口功能的count(distinct)。因此,一种方法是使用嵌套窗口函数:

select t.*,
       (max(rank_c) over () -
        max(rank_yc) over (partition by year)
       ) as TotalMissingClient
from (select t.*,
             dense_rank() over (order by client) as rank_c,
             dense_rank() over (partition by year order by client) as rank_yc
      from t
     ) t;

编辑:

我认为我误解了这个问题。以上解决了多年来所有 all 客户的问题。您只希望与前一年相比:

select t.*, tprev.TotalMissingClient
from t left join
     (select tprev.year, count(distinct tt.client) as TotalMissingClient
      from t tprev left join
           t tt
           on tprev.year = tt.year - 1
              tprev.client = tt.client
      where tt.client is null
      group by tprev.year
     ) tprev
     on tprev.year = t.year - 1;

答案 1 :(得分:0)

您所需的输出仅包含基表中包含的Year / Product组合,这意味着,如果缺少上一年的所有客户,则不会看到。示例:产品B在2008年有1个客户,但在2009年没有客户。 另外,产品B在2007年有2个客户,在2008年有1个(其他的,所以是新的)客户。在这种情况下,您想要的结果显示为NULL,但是它不应该显示2个缺少的客户(和1个新客户)吗? 该数字似乎仅取决于年份和产品。我认为查看上一年度和当前年度之间的整个增量(即客户数量,缺少的客户和新客户)会更有用。当然,这只有在没有丢失年份的情况下才有效。为了隐藏上一个记录的年份和下一个年份之间的差异,我使用了RANK函数:

#define UNTAG(x) ((tagged int *)(char (*)[2])(&(x)[-*(x)]))