Sql 有多少客户从产品A升级到产品B?

Sql 有多少客户从产品A升级到产品B?,sql,ssrs-2012,Sql,Ssrs 2012,我有一个每日更改表,记录客户何时升级或降级其会员级别。在表中,假设字段1是客户ID,字段2是会员类型,字段3是变更日期。客户123和ABC在表中各有两行。字段1 ID中的值相同,但字段2 TYPE和3 DATE中的值不同。我想编写一个SQL查询,告诉我在任何给定的时间范围内,有多少客户从成员资格类型1升级到成员资格类型2,有多少客户从成员资格类型2降级到成员资格类型1 该表还显示了其他类型的更改。为了识别成员资格类型字段中发生更改的记录,我创建了以下代码: SELECT * FROM membe

我有一个每日更改表,记录客户何时升级或降级其会员级别。在表中,假设字段1是客户ID,字段2是会员类型,字段3是变更日期。客户123和ABC在表中各有两行。字段1 ID中的值相同,但字段2 TYPE和3 DATE中的值不同。我想编写一个SQL查询,告诉我在任何给定的时间范围内,有多少客户从成员资格类型1升级到成员资格类型2,有多少客户从成员资格类型2降级到成员资格类型1

该表还显示了其他类型的更改。为了识别成员资格类型字段中发生更改的记录,我创建了以下代码:

SELECT *
FROM member_detail_daily_changes_new
WHERE customer IN (
    SELECT customer
    FROM member_detail_daily_changes_new
    GROUP BY customer
    HAVING COUNT(distinct member_type_cd) > 1)
我想看一份结束报告,它告诉我:

2018财年, 十、 XXX客户从会员类型1转移到会员类型2,并且
十、 XXX客户从会员类型2转移到会员类型1听起来是使用LEAD分析功能预测给定客户的会员类型的好时机;将其与当前记录进行比较,然后评估这是否为升级/降级,然后对结果求和。

我不确定rex tester上的SQL express是否不支持分析本身的总和,这就是我必须添加CTE的原因,或者这是否也是非SQL express版本中的规则

其他一些注意事项:

我让系统在where子句中隐式地强制转换日期 我假设member_Type_代码本身告诉我这是升级还是降级,长期来看可能是不对的。假设我们添加成员类型3,它介于1和2之间。。。现在怎么办。。。所以,也许我们需要一个成员类型代码之外的十进制数,这样我们就可以处理未来的成员身份,如果是升级/降级或横向。。。 我假设所有的升级/降级都会被计算在内,并且如果成员身份在所需的时间段内经常发生变化,那么一个用户可以被计算多次。 我假设升级/降级不能在同一日期/时间发生。否则,lead的排序可能无法正常工作。但是如果它是一个时间戳字段,我们就不会有问题 那么这是如何工作的呢

我们使用一个公共表表达式CTE生成每个客户所需的降级/升级评估。这可以在派生表中完成,也可以在线完成,但我发现CTE更容易阅读;然后我们总结一下

LeadMember_Type_代码按客户订单按日期划分asc执行以下操作

它按客户组织数据,然后按日期升序排序

因此,我们最终会在按日期排序的后续行中获得所有相同的客户记录。然后,Leadfield从记录1开始,展望同一客户的记录2,并返回记录1中记录2的成员类型代码。然后,我们可以比较这些类型代码并确定是否发生了升级或降级。然后,我们可以对比较结果进行汇总,并提供所需的总数

现在我们对一个非常小的查询有一个冗长的解释:p

您想使用滞后来实现这个查询,但是您需要注意日期过滤。所以,我想你想要:

SELECT prev_membership_type, membership_type,
       COUNT(*) as num_changes,
       COUNT(DISTINCT member) as num_members
FROM (SELECT mddc.*,
             LAG(mddc.membership_type) OVER (PARTITION BY mddc.customer_id ORDER BY mddc.date) as prev_membership_type
      FROM member_detail_daily_changes_new mddc
     ) mddc
WHERE prev_membership_type <> membership_type AND
      date >= '2018-01-01' AND
      date < '2019-01-01'
GROUP BY membership_type, prev_membership_type;
注:

日期过滤需要在计算滞后后进行。 这考虑到成员可能在2017年拥有某种类型,然后在2018年更换为新类型。 日期筛选与索引兼容。 计算了两个值。一是变化的总体数量。另一个对每种类型的更改只对每个成员计数一次。
自联接表后使用条件聚合:

select 
  2018 fiscal, 
  sum(case when m.member_type_cd > t.member_type_cd then 1 else 0 end) upgrades, 
  sum(case when m.member_type_cd < t.member_type_cd then 1 else 0 end) downgrades 
from member_detail_daily_changes_new m inner join member_detail_daily_changes_new t
on 
  t.customer = m.customer 
  and 
  t.changedate = (
    select max(changedate) from member_detail_daily_changes_new
    where customer = m.customer and changedate < m.changedate
  )
where year(m.changedate) = 2018 

即使存在两种以上的Membership级别,这也会起作用。

如果客户在同一年从类型1更改为类型2,然后再次更改为类型1,会发生什么情况?这是可能的。我确实看到一些行,其中一个客户在表中有三行或更多行。我想在这些情况下,我需要使用日期字段来计算从第一行到第二行的变化以及从第二行到第三行的变化,以指示变化的顺序。因此,相同的客户将被计算在两个类别中?好问题。我想我应该为同一个客户捕获这两个操作。所以,是的,他将被视为一次升级,一次降级。如果其他人想要的话,请随意使用创建的模拟答案!无需根据测试数据重新设计车轮!将测试/试用并报告。谢谢。我在测试的时候不得不做一些修正。更新以反映这些变化,并提供了一个使用rextesterI的示例演示,还添加了许多注释,以帮助解释正在发生的事情以及关于它的假设和想法。
SELECT prev_membership_type, membership_type,
       COUNT(*) as num_changes,
       COUNT(DISTINCT member) as num_members
FROM (SELECT mddc.*,
             LAG(mddc.membership_type) OVER (PARTITION BY mddc.customer_id ORDER BY mddc.date) as prev_membership_type
      FROM member_detail_daily_changes_new mddc
     ) mddc
WHERE prev_membership_type <> membership_type AND
      date >= '2018-01-01' AND
      date < '2019-01-01'
GROUP BY membership_type, prev_membership_type;
select 
  2018 fiscal, 
  sum(case when m.member_type_cd > t.member_type_cd then 1 else 0 end) upgrades, 
  sum(case when m.member_type_cd < t.member_type_cd then 1 else 0 end) downgrades 
from member_detail_daily_changes_new m inner join member_detail_daily_changes_new t
on 
  t.customer = m.customer 
  and 
  t.changedate = (
    select max(changedate) from member_detail_daily_changes_new
    where customer = m.customer and changedate < m.changedate
  )
where year(m.changedate) = 2018