 (@ProgramID INTEGER = NULL)
RETURNS @outer TABLE
(ProgramID     INTEGER,
 ProgramName   VARCHAR(256),
 ProgramTypeID INTEGER,
 OccurID       INTEGER,
 AncestorID    INTEGER,
 AncestorName  VARCHAR(256)
)
AS
     BEGIN
         WITH cte
              AS (
              SELECT   p.ProgramID
                      ,pa.AliasName AS ProgramName
                      ,p.ProgramTypeID
                      ,p.OccurID
                      ,p.Ancestor
                      ,pa.AliasType
                      ,CASE WHEN ProgramTypeID IN (15, 16, 19) THEN 2
                             ELSE 1
                            END IsParentFlag
                      ,CASE WHEN ProgramTypeID IN (8, 15, 16) THEN 1
                            WHEN ProgramTypeID IN (13,19)      THEN 2
                             ELSE 3
                            END IsPairFlag
                      ,ROW_NUMBER() OVER(PARTITION BY pa.AliasType ,pa.AliasName ,CASE WHEN p.ProgramTypeID IN (8, 13) THEN 1 WHEN p.ProgramTypeID IN (15, 16, 19) THEN 2 ELSE 3 END ORDER BY p.ProgramTypeID) AS RN
                    FROM Programs p
                        LEFT OUTER JOIN ProgramAliases pa  ON pa.AliasType = 0 AND pa.ProgramID = p.programID
            )

            INSERT INTO @outer
            SELECT c1.ProgramID,
                   c1.ProgramName,
                   c1.ProgramTypeID,
                   c1.OccurID,
                   c2.ProgramID AS AncestorID,
                   ISNULL(c2.ProgramName, '') AS AncestorName
             FROM cte c1
                LEFT OUTER JOIN cte c2 ON c2.AliasType = 0 AND c2.IsParentFlag = 1 AND c2.RN = 1 AND c1.IsPairFlag = c2.IsPairFlag AND c2.ProgramName = c1.Ancestor
             WHERE @ProgramID IS NULL OR @ProgramID = c1.ProgramID;

             RETURN;
     END;