• I added start and end dates to table GroupMembers and added StartDate to the primary key. This is to track when an individual or groups enters/exits a group. I embedded the group derivation logic in a function which accepts two parameters:@GroupCode and @GroupDate. I added some additional test cases. Everything is working as expected. I just wanted to post a follow up in case anyone saw any issues with the code or thought it could be useful to them.  Thanks again Drew.

    --Drop tables if they exist
        IF OBJECT_ID('[dbo].[GroupMembers]') IS NOT NULL DROP TABLE dbo.GroupMembers
        IF OBJECT_ID('[dbo].[Groups]') IS NOT NULL DROP TABLE dbo.Groups
    GO
    --Create tables
        CREATE TABLE dbo.Groups
        (
            GroupCode INT NOT NULL,
            GroupDescription VARCHAR(40) NULL
            CONSTRAINT PK_Groups PRIMARY KEY CLUSTERED (GroupCode ASC)
        )

        CREATE TABLE dbo.GroupMembers(
            GroupCode INT NOT NULL,
            Member INT NOT NULL,
            MemberType VARCHAR(12) NOT NULL,
            StartDate DATE NOT NULL,
            EndDate DATE NULL,
            CONSTRAINT PK_GroupMembers PRIMARY KEY CLUSTERED
            (
            GroupCode ASC,
            Member ASC,
            MemberType ASC,
            StartDate
            )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
        )
    GO

        ALTER TABLE dbo.GroupMembers WITH CHECK ADD CONSTRAINT FK_GroupMembers_Groups FOREIGN KEY(GroupCode)
        REFERENCES dbo.Groups (GroupCode)
    GO
    --Drop function if exists
        IF OBJECT_ID('GetGroupMembers') IS NOT NULL DROP FUNCTION GetGroupMembers
    GO
        --Create function
        CREATE FUNCTION dbo.GetGroupMembers
                (
                    @GroupCode INT,
                    @GroupDate DATE
                )
        RETURNS TABLE AS
        RETURN

            WITH Members AS
            (
                --Anchor
                SELECT
                    GroupCode,
                    Member
                FROM GroupMembers
                WHERE
                    @GroupDate BETWEEN StartDate AND COALESCE(EndDate,GETDATE()) AND
                    MemberType = 'Individual'

                UNION ALL

                --Recursive call
                SELECT
                    h.GroupCode,
                    m.Member
                FROM GroupMembers h
                INNER JOIN Members m
                    ON h.Member = m.GroupCode
                WHERE
                    @GroupDate BETWEEN StartDate AND COALESCE(EndDate,GETDATE()) AND
                    h.MemberType = 'Group'
            )

            SELECT
                Member
            FROM Members m
            WHERE
                @GroupCode = GroupCode

    GO
    INSERT INTO Groups (GroupCode,GroupDescription) VALUES (1,'Simple group')
    INSERT INTO Groups (GroupCode,GroupDescription) VALUES (2,'Simple group')
    INSERT INTO Groups (GroupCode,GroupDescription) VALUES (3,'Group of Groups')
    INSERT INTO Groups (GroupCode,GroupDescription) VALUES (4,'Mixed')
    INSERT INTO Groups (GroupCode,GroupDescription) VALUES (5,'Complicated')
    INSERT INTO Groups (GroupCode,GroupDescription) VALUES (6,'Different Start Dates')
    INSERT INTO Groups (GroupCode,GroupDescription) VALUES (7,'Different Start Dates and an End Date')
    INSERT INTO Groups (GroupCode,GroupDescription) VALUES (8,'additional test group')
    INSERT INTO Groups (GroupCode,GroupDescription) VALUES (9,'additional test group')
    INSERT INTO Groups (GroupCode,GroupDescription) VALUES (10,'additional test group')
    INSERT INTO Groups (GroupCode,GroupDescription) VALUES (11,'additional test group')
    INSERT INTO Groups (GroupCode,GroupDescription) VALUES (12,'additional test group')
    INSERT INTO Groups (GroupCode,GroupDescription) VALUES (13,'additional test group')
    INSERT INTO Groups (GroupCode,GroupDescription) VALUES (14,'additional test group')
    INSERT INTO Groups (GroupCode,GroupDescription) VALUES (15,'additional test group')
    INSERT INTO Groups (GroupCode,GroupDescription) VALUES (16,'additional test group')

    --Group 1 has two individual members; no nested groups
    INSERT INTO GroupMembers (GroupCode,Member,MemberType,StartDate,EndDate) VALUES (1,1,'Individual','2018-02-01',NULL)
    INSERT INTO GroupMembers (GroupCode,Member,MemberType,StartDate,EndDate) VALUES (1,2,'Individual','2018-02-01',NULL)
    --Group 2 has two individual members; no nested groups
    INSERT INTO GroupMembers (GroupCode,Member,MemberType,StartDate,EndDate) VALUES (2,3,'Individual','2018-02-01',NULL)
    INSERT INTO GroupMembers (GroupCode,Member,MemberType,StartDate,EndDate) VALUES (2,4,'Individual','2018-02-01',NULL)
    --Group 3 has two members both of which are groups
    INSERT INTO GroupMembers (GroupCode,Member,MemberType,StartDate,EndDate) VALUES (3,1,'Group','2018-02-01',NULL)
    INSERT INTO GroupMembers (GroupCode,Member,MemberType,StartDate,EndDate) VALUES (3,2,'Group','2018-02-01',NULL)
    --Group 4 has an individual and a group
    INSERT INTO GroupMembers (GroupCode,Member,MemberType,StartDate,EndDate) VALUES (4,1,'Group','2018-02-01',NULL)
    INSERT INTO GroupMembers (GroupCode,Member,MemberType,StartDate,EndDate) VALUES (4,4,'Individual','2018-02-01',NULL)
    --Group 5 has an individual and a group; The group is a nested group
    INSERT INTO GroupMembers (GroupCode,Member,MemberType,StartDate,EndDate) VALUES (5,3,'Group','2018-02-01',NULL)
    INSERT INTO GroupMembers (GroupCode,Member,MemberType,StartDate,EndDate) VALUES (5,5,'Individual','2018-02-01',NULL)

    DECLARE
        @GroupCode INT,
        @GroupDate DATE

        --GroupCode = 1; GroupDate = '2018-02-15'
            SET @GroupCode = 1
            SET @GroupDate = '2018-02-15'
            SELECT
                'GroupCode = 1; GroupDate = 2018-02-15' AS Test,
                Member,
                'Expected results: Members 1 and 2' AS ExpectedResults
            FROM dbo.GetGroupMembers(@GroupCode,@GroupDate)

        --GroupCode = 2; GroupDate = '2018-02-15'
            SET @GroupCode = 2
            SET @GroupDate = '2018-02-15'
            SELECT
                'GroupCode = 2; GroupDate = 2018-02-15' AS Test,
                Member,
                'Expected results: Members 3,4' AS ExpectedResults
            FROM dbo.GetGroupMembers(@GroupCode,@GroupDate)

        --GroupCode = 3; GroupDate = '2018-02-15'
            SET @GroupCode = 3
            SET @GroupDate = '2018-02-15'
            SELECT
                'GroupCode = 3; GroupDate = 2018-02-15' AS Test,
                Member,
                'Expected results: 1,2,3,4' AS ExpectedResults
            FROM dbo.GetGroupMembers(@GroupCode,@GroupDate)

        --GroupCode = 4; ; GroupDate = '2018-02-15'
            SET @GroupCode = 4
            SET @GroupDate = '2018-02-15'
            SELECT
                'GroupCode = 4; ; GroupDate = 2018-02-15' AS Test,
                Member,
                'Expected results: 1,2,4' AS ExpectedResults
            FROM dbo.GetGroupMembers(@GroupCode,@GroupDate)

        --GroupCode = 5; GroupDate = current date
            SET @GroupCode = 5
            SET @GroupDate = GETDATE()
            SELECT
                'GroupCode = 5; GroupDate = current date' AS Test,
                Member,
                'Expected results: 1,2,3,4,5' AS ExpectedResults
            FROM dbo.GetGroupMembers(@GroupCode,@GroupDate)

    --Start testing the start and end date logic

    --Create new groups
    --Group 6 has two members both of which are groups; Group 1 joined on 2018-02-01 and Group 2 joined on 2018-02-02
    INSERT INTO GroupMembers (GroupCode,Member,MemberType,StartDate,EndDate) VALUES (6,1,'Group','2018-02-01',NULL)
    INSERT INTO GroupMembers (GroupCode,Member,MemberType,StartDate,EndDate) VALUES (6,2,'Group','2018-02-02',NULL)

        --GroupCode = 6; GroupDate = '2018-02-15';     
            SET @GroupCode = 6
            SET @GroupDate = '2018-02-15'
            SELECT
                'GroupCode = 6; GroupDate = 2018-02-15' AS Test,
                Member,
                'Expected results: The individual members of both groups 1 and 2: 1,2,3,4. All existed in the group on 2018-02-15' AS ExpectedResults
            FROM dbo.GetGroupMembers(@GroupCode,@GroupDate)

        --GroupCode = 6; GroupDate = '2018-02-15';     
            SET @GroupCode = 6
            SET @GroupDate = '2018-02-15'
            SELECT
                'GroupCode = 6; GroupDate = 2018-02-15' AS Test,
                Member,
                'Expected results: The individual members of both groups 1 and 2; 1,2,3,4 All existed in the group on 2018-02-02' AS ExpectedResults
            FROM dbo.GetGroupMembers(@GroupCode,@GroupDate)

        --GroupCode = 6; GroupDate = '2018-02-01';
            SET @GroupCode = 6
            SET @GroupDate = '2018-02-01'
            SELECT
                'GroupCode = 6; GroupDate = 2018-02-01' AS Test,
                Member,
                'Expected results: The individual members of group 1 ; Members 1,2; Only group 1 existed in the group on 2018-02-01' AS ExpectedResults
            FROM dbo.GetGroupMembers(@GroupCode,@GroupDate)
        
        --GroupCode = 6; GroupDate = '2017-02-01';
            SET @GroupCode = 6
            SET @GroupDate = '2017-02-01'
            SELECT
                'GroupCode = 6; GroupDate = 2017-02-01' AS Test,
                Member,
                'Expected results: None; No groups existed on 2017-02-01' AS ExpectedResults
            FROM dbo.GetGroupMembers(@GroupCode,@GroupDate)

    --Group 7; Sames as group 6 but group 1 exited the group on 2018-02-05
    INSERT INTO GroupMembers (GroupCode,Member,MemberType,StartDate,EndDate) VALUES (7,1,'Group','2018-02-01','2018-02-05')
    INSERT INTO GroupMembers (GroupCode,Member,MemberType,StartDate,EndDate) VALUES (7,2,'Group','2018-02-02',NULL)

        --GroupCode = 7; GroupDate = '2018-02-05';
            SET @GroupCode = 7
            SET @GroupDate = '2018-02-05'
            SELECT
                'GroupCode = 7; GroupDate = 2018-02-05' AS Test,
                Member,
                'Expected results: The individual members of both groups 1 and 2; 1,2,3,4 All existed in the group on 2018-02-05' AS ExpectedResults
            FROM dbo.GetGroupMembers(@GroupCode,@GroupDate)
        
        --GroupCode = 7; GroupDate = '2018-02-06';
            SET @GroupCode = 7
            SET @GroupDate = '2018-02-06'
            SELECT
                'GroupCode = 7; GroupDate = 2018-02-06' AS Test,
                Member,
                'Expected results: 3 and 4; Group 1 exited group 7 on 2018-02-05' AS ExpectedResults
            FROM dbo.GetGroupMembers(@GroupCode,@GroupDate)

        --GroupCode = 7; GroupDate = '2018-02-01'
            SET @GroupCode = 7
            SET @GroupDate = '2018-02-01'
            SELECT
                'GroupCode = 7; GroupDate = 2018-02-01' AS Test,
                Member,
                'Expected results: The individual members of group 1; Group 2 joined group 7 the next day' AS ExpectedResults
            FROM dbo.GetGroupMembers(@GroupCode,@GroupDate)

    --Nest deeper
    INSERT INTO GroupMembers (GroupCode,Member,MemberType,StartDate,EndDate) VALUES (8,9,'Group','2018-02-01',NULL)
    INSERT INTO GroupMembers (GroupCode,Member,MemberType,StartDate,EndDate) VALUES (9,10,'Group','2018-02-01',NULL)
    INSERT INTO GroupMembers (GroupCode,Member,MemberType,StartDate,EndDate) VALUES (10,11,'Group','2018-02-01',NULL)
    INSERT INTO GroupMembers (GroupCode,Member,MemberType,StartDate,EndDate) VALUES (11,1,'Individual','2018-02-01',NULL)

        --GroupCode = 8; GroupDate = '2018-02-01';
            SET @GroupCode = 8
            SET @GroupDate = '2018-02-01'
            SELECT
                'GroupCode = 8; GroupDate = 2018-02-01' AS Test,
                Member,
                'Expected results: Member 1; Group 8 contains group 9 which contains group 10 which contains group 11; Group 11 contains the individual member 1' AS ExpectedResults
            FROM dbo.GetGroupMembers(@GroupCode,@GroupDate)
            
        --Testing group 9, 10 and 11 will get the same result
            SET @GroupCode = 11
            SET @GroupDate = '2018-02-01'
            SELECT
                'GroupCode = 11; GroupDate = 2018-02-01' AS Test,
                Member,
                'Expected results: Member 1' AS ExpectedResults
            FROM dbo.GetGroupMembers(@GroupCode,@GroupDate)

    --Test when an intermediate nested group has an individual member
    INSERT INTO GroupMembers (GroupCode,Member,MemberType,StartDate,EndDate) VALUES (12,13,'Group','2018-02-01',NULL)
    INSERT INTO GroupMembers (GroupCode,Member,MemberType,StartDate,EndDate) VALUES (13,14,'Group','2018-02-01',NULL)
    INSERT INTO GroupMembers (GroupCode,Member,MemberType,StartDate,EndDate) VALUES (13,8,'Individual','2018-02-01',NULL)
    INSERT INTO GroupMembers (GroupCode,Member,MemberType,StartDate,EndDate) VALUES (14,15,'Group','2018-02-01',NULL)
    INSERT INTO GroupMembers (GroupCode,Member,MemberType,StartDate,EndDate) VALUES (15,1,'Individual','2018-02-01',NULL)

        --GroupCode = 12; GroupDate = '2018-02-01';
            SET @GroupCode = 12
            SET @GroupDate = '2018-02-01'
            SELECT
                'GroupCode = 12; GroupDate = 2018-02-01' AS Test,
                Member,
                'Expected results: 1 and 8; Group 12 contains group 13 which contains group 14 (and individual 8) which contains group 15; Group 15 contains the member 1' AS ExpectedResults
            FROM dbo.GetGroupMembers(@GroupCode,@GroupDate)

    --A group exits and re-enters a group; Has an individual from the start
    INSERT INTO GroupMembers (GroupCode,Member,MemberType,StartDate,EndDate) VALUES (16,19,'Individual','2018-02-01',NULL)
    INSERT INTO GroupMembers (GroupCode,Member,MemberType,StartDate,EndDate) VALUES (16,1,'Group','2018-02-01','2018-02-05')
    INSERT INTO GroupMembers (GroupCode,Member,MemberType,StartDate,EndDate) VALUES (16,1,'Group','2018-02-10','2018-02-15')

        --GroupCode = 16; GroupDate = '2018-02-05';
            SET @GroupCode = 16
            SET @GroupDate = '2018-02-05'
            SELECT
                'GroupCode = 16; GroupDate = 2018-02-05' AS Test,
                Member,
                'Expected results: Members 1, 2 and 19; Group 1 which contains members 1 and 2 was in group 16 on 2018-02-05' AS ExpectedResults
            FROM dbo.GetGroupMembers(@GroupCode,@GroupDate)

        --GroupCode = 16; GroupDate = '2018-02-09';
                SET @GroupCode = 16
            SET @GroupDate = '2018-02-09'
            SELECT
                'GroupCode = 16; GroupDate = 2018-02-09' AS Test,
                Member,
                'Expected results: Just 19; Group 1 which contains members 1 and 2 was not in group 16 on 2018-02-09' AS ExpectedResults
            FROM dbo.GetGroupMembers(@GroupCode,@GroupDate)

    --View the group and group members
    --SELECT * FROM dbo.Groups
    --SELECT * FROM dbo.GroupMembers