Q:

Min date for a guest across all their accounts

So let me explain our setup first. We have two tables on SQL Server 2012 we are looking at:
PL_Guest and PL_MergedGuests

PL_Guest structure is as follows:
Create Table PL_Guest(
GuestID [int] IDENTITY(1,1) NOT NULL Primary Key,
CreatedDate [date] NOT NULL)

PL_MergedGuests structure is as follows:
Create Table PL_MergedGuests(
MergeID [int] IDENTITY(1,1) NOT NULL Primary Key,
VictimID [int] NOT NULL,
SurvivorID [int] NOT NULL)

So the situation is this:
The PL_Guest table keeps a record of every guest ever created and never has any records removed from it. The PL_MergedGuests table house a list of victimid and survivorid of when we merge two accounts together. We would do this if for instance a person got more than one Guestid assigned to them for some reason. Now when the merge is done the front line employee just picks which of the multiple accounts the person will be keeping this is usually done based on the card the guest has in hand so as to involve less changes for the guest. If a guest had GuestID 5 with CreatedDate 1/1/2013 and GuestID 10 with CreatedDate 10/1/2015; and the merge was done so that GuestID 5 was merged into GuestID 10 then GuestID 5 becomes the Victim and GuestID 10 becomes the survivor. When we run reports we only look at survivor accounts. However we are being asked to find the oldest Created Date for each guest. So for the above example they would want and entry that returns GuestID 10 Created date 1/1/2013 as the Guest that has GuestID 10 also had GuestID 5 which had the older created date of the 1/1/2013.
Now for the really hard part, there is no limit to the number of times a Guest could have been merged and these tables hold over 100 million records each. I was thinking that this would require some kind of looping(I think this might be referred to a recursive coding though I am unsure on that) but I am at a lost for how to write that code. I do have access to create new tables if that will help but can not modify the current tables.

A:

Due to lack of "real" examples I defined several examples myself and maintained several merges. I used a recursive cte in order to evaluate the desired "min creation date". I don't know how fast or slow this will work on your tables, but at least it should provide a usable starting point for further development:
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)

