用于确定两个整数范围是否重叠的T-SQL函数

时间:2014-08-18 13:58:48

标签: sql-server tsql range overlap

我有两个整数范围,需要确定它们是否重叠。一个或两个范围可以是开放式的。任何人都有一个T-SQL函数用于此目的吗?

3 个答案:

答案 0 :(得分:3)

更短,更黑的解决方案(将空值设置为最小值/最大值):

SET @p_start_range1 = ISNULL(@p_start_range1, -2147483648);
SET @p_end_range1 = ISNULL(@p_end_range1, 2147483647);
SET @p_start_range2 = ISNULL(@p_start_range2, -2147483648);
SET @p_end_range2 = ISNULL(@p_end_range2, 2147483647);

SELECT @Result = 
    CASE
        WHEN @p_start_range1 > @p_end_range2 OR @p_start_range2 > @p_end_range1
            THEN 0
        ELSE 1
    END;

答案 1 :(得分:1)

-- Takes in two different ranges and checks to see if they overlap (inclusive).
-- A null value for a parameter implies that the range is open-ended.
-- False is returned for a malformed range (end < start).

CREATE FUNCTION dbo.uf_IntRangesOverlap(
                    @p_start_range1 int,
                    @p_end_range1 int,
                    @p_start_range2 int,
                    @p_end_range2 int)
RETURNS bit
AS
BEGIN
    DECLARE
       @Result bit;

    IF @p_start_range1 > @p_end_range1
    OR @p_start_range2 > @p_end_range2
    BEGIN
        -- malformed range
        SELECT @Result = 0;
    END;
    ELSE
    BEGIN
        IF(@p_start_range1 IS NULL
       AND @p_end_range1 IS NULL)
       OR (@p_start_range2 IS NULL
       AND @p_end_range2 IS NULL)
        BEGIN
            SELECT @Result = 1;
        END;
        ELSE
        BEGIN
            IF @p_start_range1 IS NULL
            BEGIN
                SELECT @Result = CASE
                         WHEN(@p_start_range2 IS NULL
                           OR @p_start_range2 <= @p_end_range1)THEN 1
                         ELSE 0
                         END;
            END;
            ELSE
            BEGIN
                IF @p_end_range1 IS NULL
                BEGIN
                    SELECT @Result = CASE
                             WHEN(@p_end_range2 IS NULL
                               OR @p_end_range2 >= @p_start_range1)THEN 1
                             ELSE 0
                             END;
                END;
                ELSE
                BEGIN
                    IF @p_start_range2 IS NULL
                    BEGIN
                        SELECT @Result = CASE
                                 WHEN(@p_start_range1 IS NULL
                                   OR @p_start_range1 <= @p_end_range2)THEN 1
                                 ELSE 0
                                 END;
                    END;
                    ELSE
                    BEGIN
                        IF @p_end_range2 IS NULL
                        BEGIN
                            SELECT @Result = CASE
                                     WHEN(@p_end_range1 IS NULL
                                       OR @p_end_range1 >= @p_start_range2)THEN 1
                                     ELSE 0
                                     END;
                        END;
                        ELSE
                        BEGIN
                            SELECT @Result = CASE
                                     WHEN(@p_end_range1 >= @p_start_range2
                                      AND @p_start_range1 <= @p_end_range2)THEN 1
                                     ELSE 0
                                     END;
                        END;
                    END;
                END;
            END;
        END;
    END;
    RETURN @Result;
END;

答案 2 :(得分:1)

使用整数的最大/最小值:

DECLARE @p_start_range1 int
       ,@p_end_range1   int
       ,@p_start_range2 int
       ,@p_end_range2   int;

DECLARE @Result bit;
DECLARE @IntMin int = -2147483648;
DECLARE @IntMax int = 2147483647;

SELECT @Result = CASE 
                 WHEN (ISNULL(@p_start_range1,@IntMin) <= ISNULL(@p_end_range2,@IntMax)) 
                   AND(ISNULL(@p_start_range2,@IntMin) <= ISNULL(@p_end_range1,@IntMax)) 
                 THEN 1 
                 ELSE 0 END;
SELECT @Result;