让我先解释一下我们的设置。我们在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亿条记录。我当时认为这需要某种循环(我认为这可能会被称为递归编码,虽然我不确定)但我对于如何编写代码感到很遗憾。我有权创建新表,如果这将有所帮助,但无法修改当前表。
答案 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)