在多个分区上获取潜在客户价值

时间:2018-11-14 10:49:05

标签: sql sql-server tsql sql-server-2017 data-partitioning

我有一个问题,我感觉可以使用滞后/前导+分区来解决,但我无法解决这个问题。

每两年(大约)邀请客户参加研究项目。 为每个项目选择了许多客户。 一些客户被选择用于多个研究项目。 那些被发送了邀请。在某些情况下,不会发送邀请。如果客户不响应邀请,则发送第二个邀请(提醒)。第三,第四也是可能的。

我需要确定客户是否曾受邀参加先前的研究项目。 (以及可选的邀请)。

数据集如下:

clientID | projectID | invitationID
  14     |    267    |     489
  14     |    267    |     325
  16     |    385    |     475
  17     |    546    |     NULL
  17     |    547    |     885
  17     |    548    |     901
  18     |    721    |     905
  18     |    834    |     906
  18     |    834    |     907
  19     |    856    |     908
  19     |    856    |     929
  19     |    857    |     931
  19     |    857    |     945
  19     |    858    |     NULL


Client 14 has had 2 invitations for the same research-project
Client 16 has had 1 invitation for 1 research-project
Client 17 has been selected for 3 research-projects but opted out for project 546, receiving 1 invitation each for the following projects. 
Client 18 has been selected for 2 research-projects. For the second project he got a 2 invitations.
Client 19 has been selected for three research-projects. For the first two a reminder was set. Client 19 was selected for project 858 but opted out thus no invitation.

现在,我需要为每个客户确定是否有以前的研究项目的邀请。 (以及可选的邀请)。我只需要第一个邀请(如果有多个邀请)。 因此,我得到的数据集应如下所示(括号之间的内容是可选的):

clientID | projectID | invitationID | InvitedForPreviousProject
  14     |    267    |     489      |      0
  14     |    267    |     325      |      0
  16     |    385    |     475      |      0
  17     |    546    |     NULL     |      0
  17     |    547    |     885      |      0
  17     |    548    |     901      |      1 (885)
  18     |    721    |     905      |      0
  18     |    834    |     906      |      1 (905)
  18     |    834    |     907      |      1 (905)
  19     |    856    |     908      |      0
  19     |    856    |     929      |      0
  19     |    857    |     931      |      1 (908)
  19     |    857    |     945      |      1 (908)
  19     |    858    |     NULL     |      1 (931)

这可以使用LEAD,Rank,Dense-Rank完成吗?包含以下数据的创建语句

declare @table table (
    [clientID] [int] NULL,
    [projectID] [int] NULL,
    [invitationID] [int] NULL
)
INSERT @table ([clientID], [projectID], [invitationID]) VALUES
(14, 267, 489),
(14, 267, 325),
(16, 385, 475),
(17, 546, NULL),
(17, 547, 885),
(17, 548, 901),
(18, 721, 905),
(18, 834, 906),
(18, 834, 907),
(19, 856, 908),
(19, 856, 929),
(19, 857, 931),
(19, 857, 945),
(19, 858, NULL)

2 个答案:

答案 0 :(得分:2)

可以提供帮助吗?

declare @table table (
    [clientID] [int] NULL,
    [projectID] [int] NULL,
    [invitationID] [int] NULL
)
INSERT @table ([clientID], [projectID], [invitationID]) VALUES
(14, 267, 489),
(14, 267, 325),
(16, 385, 475),
(17, 546, NULL),
(17, 547, 885),
(17, 548, 901),
(18, 721, 905),
(18, 834, 906),
(18, 834, 907),
(19, 856, 908),
(19, 856, 929),
(19, 857, 931),
(19, 857, 945),
(19, 858, NULL);

-查询使用DENSE_RANK()和相关子查询

WITH ranked AS
(
    SELECT t.* 
         ,DENSE_RANK() OVER(PARTITION BY t.clientID ORDER BY t.projectID) AS InvRank
    FROM @table t
)
SELECT r.*
      ,earlierProject.invitationID
FROM ranked r
OUTER APPLY(SELECT TOP 1 *
            FROM ranked r2 
            WHERE r2.clientID=r.clientID
             AND  r2.projectID<r.projectID 
             AND  r2.InvRank=r.InvRank-1   
            ORDER BY invitationID ASC
            ) earlierProject
ORDER BY r.clientID,r.projectID,r.invitationID;

如果表中的“ 0”,则邀请ID为NULL;如果找到项目,则将其设置为所需的值。

提示

实际上不需要APPLY。如果仅需要invitationID,则可以将子查询直接放置为一列(速度稍快)。但这更好阅读,您也可以在其他专栏上阅读……

答案 1 :(得分:1)

您需要一列来指定顺序。让我假设有一个邀请日期以及其他各栏。

通过此信息,您可以通过比较两个值来轻松计算您的标志:

  • 客户的最低邀请日期
  • 客户/项目ID的最低邀请日期

如果相同,这是第一个带有邀请的项目。

所以:

 buttons: [
   {
     addClass: 'btn btn-primary', text: 'Prev', onClick: function($noty) {
        // Do your magic
     }
   },
   {
     addClass: 'btn btn-primary', text: 'Next', onClick: function($noty) {
        // Do your magic
     }
   }
 ]