A few months ago, I found myself working with a repetitive cursor that looped until the data had been manipulated enough times that it was finally correct.  The cursor was heavily dependent upon dates, every time requiring the earlier of two (or several) dates in one stored procedure, while requiring the later of two dates in another stored procedure.
In short what I needed was a function that would allow me to perform the following evaluation:
WHERE MAX(Date1, Date2) < @SomeDate
The problem is, the MAX() function in SQL Server does not perform this functionality. 
So, I set out to put these functions together.  They are titled: EarlierOf() and LaterOf().
    
        
            
            /**********************************************************
             
                                        EarlierOf.sql
             
            **********************************************************/
            /**********************************************************
             
            Return the later of two DATETIME variables.
             
            Parameter 1: DATETIME1
            Parameter 2: DATETIME2
             
            Works for a variety of DATETIME or NULL values. Even 
            though comparisons with NULL are actually indeterminate, we 
            know conceptually that NULL is not earlier 
            or later than any other date provided.
             
            SYNTAX:
            SELECT dbo.EarlierOf('1/1/2000','12/1/2009')
            SELECT dbo.EarlierOf('2009-12-01 00:00:00.000','2009-12-01 00:00:00.521')
            SELECT dbo.EarlierOf('11/15/2000',NULL)
            SELECT dbo.EarlierOf(NULL,'1/15/2004')
            SELECT dbo.EarlierOf(NULL,NULL)
             
            **********************************************************/
            USE AdventureWorks
            GO
             
            IF EXISTS
                  (SELECT *
                  FROM sysobjects
                  WHERE name = 'EarlierOf'
                  AND xtype = 'FN'
                  )
            BEGIN
                        DROP FUNCTION EarlierOf
            END
            GO
             
            CREATE FUNCTION EarlierOf (
                  @Date1                              DATETIME,
                  @Date2                              DATETIME
            )
             
            RETURNS DATETIME
             
            AS
            BEGIN
                  DECLARE @ReturnDate     DATETIME
             
                  IF (@Date1 IS NULL AND @Date2 IS NULL)
                  BEGIN
                        SET @ReturnDate = NULL
                        GOTO EndOfFunction
                  END
             
                  ELSE IF (@Date1 IS NULL AND @Date2 IS NOT NULL)
                  BEGIN
                        SET @ReturnDate = @Date2
                        GOTO EndOfFunction
                  END
             
                  ELSE IF (@Date1 IS NOT NULL AND @Date2 IS NULL)
                  BEGIN
                        SET @ReturnDate = @Date1
                        GOTO EndOfFunction
                  END
             
                  ELSE 
                  BEGIN
                        SET @ReturnDate = @Date1
                        IF @Date2 < @Date1
                              SET @ReturnDate = @Date2
                        GOTO EndOfFunction
                  END
             
                  EndOfFunction:
                  RETURN @ReturnDate
             
            END -- End Function
            GO
             
            ---- Set Permissions
            --GRANT SELECT ON EarlierOf TO UserRole1
            --GRANT SELECT ON EarlierOf TO UserRole2
            --GO
            
        
    
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
The inverse of this function is only slightly different.
    
        
            
            /**********************************************************
             
                                        LaterOf.sql
             
            **********************************************************/
            /**********************************************************
             
            Return the later of two DATETIME variables.
             
            Parameter 1: DATETIME1
            Parameter 2: DATETIME2
             
            Works for a variety of DATETIME or NULL values. Even 
            though comparisons with NULL are actually indeterminate, we 
            know conceptually that NULL is not earlier 
            or later than any other date provided.
             
            SYNTAX:
            SELECT dbo.LaterOf('1/1/2000','12/1/2009')
            SELECT dbo.LaterOf('2009-12-01 00:00:00.000','2009-12-01 00:00:00.521')
            SELECT dbo.LaterOf('11/15/2000',NULL)
            SELECT dbo.LaterOf(NULL,'1/15/2004')
            SELECT dbo.LaterOf(NULL,NULL)
             
            **********************************************************/
            USE AdventureWorks
            GO
             
            IF EXISTS
                  (SELECT *
                  FROM sysobjects
                  WHERE name = 'LaterOf'
                  AND xtype = 'FN'
                  )
            BEGIN
                        DROP FUNCTION LaterOf
            END
            GO
             
            CREATE FUNCTION LaterOf (
                  @Date1                              DATETIME,
                  @Date2                              DATETIME
            )
             
            RETURNS DATETIME
             
            AS
            BEGIN
                  DECLARE @ReturnDate     DATETIME
             
                  IF (@Date1 IS NULL AND @Date2 IS NULL)
                  BEGIN
                        SET @ReturnDate = NULL
                        GOTO EndOfFunction
                  END
             
                  ELSE IF (@Date1 IS NULL AND @Date2 IS NOT NULL)
                  BEGIN
                        SET @ReturnDate = @Date2
                        GOTO EndOfFunction
                  END
             
                  ELSE IF (@Date1 IS NOT NULL AND @Date2 IS NULL)
                  BEGIN
                        SET @ReturnDate = @Date1
                        GOTO EndOfFunction
                  END
             
                  ELSE 
                  BEGIN
                        SET @ReturnDate = @Date1
                        IF @Date2 > @Date1
                              SET @ReturnDate = @Date2
                        GOTO EndOfFunction
                  END
             
                  EndOfFunction:
                  RETURN @ReturnDate
             
            END -- End Function
            GO
             
            ---- Set Permissions
            --GRANT SELECT ON LaterOf TO UserRole1
            --GRANT SELECT ON LaterOf TO UserRole2
            --GO
            
        
    
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
The interesting thing about this function is its simplicity and the built-in NULL handling functionality.  Its interesting, because it seems like something should already exist in SQL Server that does this.  From a different vantage point, if you create this functionality and it is easy to use (ideally, intuitively self-explanatory), you have made a successful contribution.
Interesting is good.  Self-explanatory, or intuitive is FAR better.  Happy coding!
Graeme