所有帐户中的访客的最短日期

时间:2017-08-31 12:15:05

标签: loops recursion sql-server-2012 recursive-query

让我先解释一下我们的设置。我们在SQL Server 2012上有两个表:

cmd.CommandText="INSERT INTO person(birthdate)VALUES('"+dateTimePicker.Value.Date+"')";

PL_Guest结构如下:

PL_Guest and PL_MergedGuests

PL_MergedGuests结构如下:

Create Table PL_Guest(
GuestID [int] IDENTITY(1,1) NOT NULL Primary Key,
CreatedDate [date] NOT NULL)

情况就是这样:

PL_Guest表记录了每个创建过的guest虚拟机,并且从未删除过任何记录。当我们将两个帐户合并在一起时,PL_MergedGuests表列出了victimid和survivorid的列表。如果一个人出于某种原因分配了多个Guestid,我们会这样做。现在,当合并完成时,前线员工只选择该人将保留的多个账户中的哪一个,这通常基于客人手中的卡来完成,以便对客人进行较少的更改。如果访客的CreIDDate 1/1/2013为GuestID 5,CreatedDate为10/1/2015,则为GuestID 10;并且完成合并以便将GuestID 5合并到GuestID 10中,然后GuestID 5成为受害者并且GuestID 10成为幸存者。当我们运行报告时,我们只查看幸存者帐户。但是,我们被要求为每位客人找到最早的创建日期。因此,对于上面的示例,他们希望和条目返回GuestID 10 Created date 1/1/2013,因为具有GuestID 10的Guest也具有GuestID 5,其具有较早创建的日期为2013年1月1日。

现在对于非常困难的部分,Guest可以合并的次数没有限制,这些表每个都有超过1亿条记录。我当时认为这需要某种循环(我认为这可能会被称为递归编码,虽然我不确定)但我对于如何编写代码感到很遗憾。我有权创建新表,如果这将有所帮助,但无法修改当前表。

1 个答案:

答案 0 :(得分:1)

由于缺乏"真实"示例我自己定义了几个示例并维护了几个合并。我使用递归cte来评估所需的" min创建日期"。我不知道这对你的牌桌有多快或多慢,但至少它应该为进一步发展提供一个可用的起点:

DECLARE @PL_Guest TABLE(
  GuestID INT NOT NULL,
  CreatedDate [date] NOT NULL
)

DECLARE @PL_MergedGuests TABLE(
  MergeID  INT NOT NULL,
  VictimID [int] NOT NULL,
  SurvivorID [int] NOT NULL
)


INSERT INTO @PL_Guest
  VALUES (1, '2016-11-01'), (2, '2016-12-01'), (3, '2016-11-01'), (4, '2016-12-01'), (5, '2017-01-01'), (6, '2017-01-01'), (7, '2017-02-01'), (8, '2017-02-01'), (9, '2017-03-01'), (10, '2017-04-01');

INSERT INTO @PL_MergedGuests
  VALUES (1, 3, 4), (2, 4, 6), (3, 9, 6), (4, 10, 2), (5, 8, 5); 

WITH cteRecursice AS(
  SELECT mg1.SurvivorID, mg1.VictimID, 1 AS lvl, mg1.SurvivorID AS LastSurvivor, pg1.CreatedDate AS LastSurvivorCreatedDate
    FROM @PL_MergedGuests mg1
    JOIN @PL_Guest pg1 ON pg1.GuestID = mg1.SurvivorID
  UNION ALL
  SELECT mg2.SurvivorID, mg2.VictimID, c.lvl + 1 AS lvl, c.LastSurvivor, c.LastSurvivorCreatedDate
    FROM @PL_MergedGuests mg2
    JOIN cteRecursice c ON mg2.SurvivorID = c.VictimID
),
cteGrouped AS(
  SELECT LastSurvivor, LastSurvivorCreatedDate, MIN(CreatedDate) AS MinCreatedDate
    FROM cteRecursice
    JOIN @PL_Guest AS pg ON pg.GuestID = VictimID
    WHERE LastSurvivor NOT IN (SELECT VictimID FROM @PL_MergedGuests AS pmg)
    GROUP BY LastSurvivor, LastSurvivorCreatedDate
  UNION ALL
  SELECT GuestID, CreatedDate, CreatedDate
    FROM @PL_Guest pg
    WHERE GuestID NOT IN (SELECT VictimID FROM @PL_MergedGuests UNION ALL SELECT SurvivorID FROM @PL_MergedGuests)
)
SELECT LastSurvivor, IIF(MinCreatedDate < LastSurvivorCreatedDate, MinCreatedDate, LastSurvivorCreatedDate) AS MinCreatedDate
  FROM cteGrouped cg
  ORDER BY LastSurvivor
  OPTION (MAXRECURSION 0)