如何查询范围在 SQL 中的基于 SQL 的集合

How to query number based SQL Sets with Ranges in SQL

我正在寻找的是在 MSSQL 中创建包含一组值的复杂 IN 或 LIKE 子句的方法,其中一些值将是范围。

有点像这样,有一些单一的数字,也有一些数字范围。

EX: SELECT * FROM table WHERE 字段 LIKE/IN '1-10, 13, 24, 51-60'

我需要找到一种方法来执行此操作,而不必分别指定范围内的每个数字,也不必说“字段类似废话或字段介于废话和废话之间或字段类似废话。 这只是一个简单的示例,但真正的查询将包含许多组和大范围,因此所有 OR 都不起作用。

一个相当简单的方法是用你的 values/ranges:

加载临时文件 table
CREATE TABLE #Ranges (ValA int, ValB int)

INSERT INTO #Ranges
VALUES
 (1, 10)
,(13, NULL)
,(24, NULL)
,(51,60)

SELECT *
FROM Table t
JOIN #Ranges R
ON (t.Field = R.ValA AND R.ValB IS NULL)
   OR (t.Field BETWEEN R.ValA and R.ValB AND R.ValB IS NOT NULL)

不过,BETWEEN 不会很好地扩展,因此您可能需要考虑扩展它以包括所有值并消除范围。

你可以用 CTE 做到这一点。

首先,创建一个 numbers/tally table 如果您还没有一个(如果您要经常使用它,最好让它永久而不是临时的):

;WITH Numbers AS
(
    SELECT
        1 as Value
    UNION ALL
    SELECT
        Numbers.Value + 1
    FROM
        Numbers
)
SELECT TOP 1000
    Value
INTO ##Numbers
FROM
    Numbers
OPTION (MAXRECURSION 1000)

然后您可以使用 CTE 来解析逗号分隔的字符串并将范围与数字 table 连接起来以获得包含您要查找的整个数字列表的 "NewValue" 列:

DECLARE @TestData varchar(50) = '1-10,13,24,51-60'

;WITH CTE AS 
(
    SELECT
        1 AS RowCounter,
        1 AS StartPosition,
        CHARINDEX(',',@TestData) AS EndPosition

    UNION ALL
    SELECT
        CTE.RowCounter + 1,
        EndPosition + 1,
        CHARINDEX(',',@TestData, CTE.EndPosition+1)
    FROM CTE
    WHERE
        CTE.EndPosition > 0
)

SELECT
    u.Value,
    u.StartValue,
    u.EndValue,
    n.Value as NewValue
FROM
    (
    SELECT
        Value,
        SUBSTRING(Value,1,CASE WHEN CHARINDEX('-',Value) > 0 THEN CHARINDEX('-',Value)-1 ELSE LEN(Value) END) AS StartValue,
        SUBSTRING(Value,CASE WHEN CHARINDEX('-',Value) > 0 THEN CHARINDEX('-',Value)+1 ELSE 1 END,LEN(Value)- CHARINDEX('-',Value))  AS EndValue
    FROM
        (
        SELECT
            SUBSTRING(@TestData, StartPosition, CASE WHEN EndPosition > 0 THEN EndPosition-StartPosition ELSE LEN(@TestData)-StartPosition+1 END) AS Value
        FROM 
            CTE
        )t
    )u INNER JOIN ##Numbers n ON n.Value BETWEEN u.StartValue AND u.EndValue

你需要做的就是使用 IN 语句查询结果,比如

SELECT * FROM MyTable WHERE Value IN (SELECT NewValue FROM (/*subquery from above*/)t)