如何从逗号分隔列中查找值

时间:2016-04-06 04:08:59

标签: sql-server-2008

我想知道如何为SQL Server 2008编写一个SQL语句,用于选择列中包含逗号分隔值的条目(通常 - 只能有一个条目(并且没有前导逗号)),例如:

Column1
---------------------------
10-15,20-30,31-97,104-187

列中的值表示逗号分隔的范围。 在这种情况下,我想找到25

1 个答案:

答案 0 :(得分:1)

请考虑规范化您的数据库。您通过使用单个列来保留多个范围数据,从而增加了对伤害的侮辱。规范化数据库将具有另一个范围表,包含起始值和结束值,以及原始表的外键。
像这样:

CREATE TABLE tblRange
(
    Range_itemId int, --(fk to the original table)
    Range_From int,
    Range_To int
)

如果你这样做,你的查询就是:

SELECT i.*
FROM tblItems
INNER JOIN tblRange ON(Item_Id = Range_ItemId)
WHERE Range_From <= 25
AND Range_To >= 25

但是,如果您无法规范化数据库,那么您必须使用split string函数从逗号分隔列创建行,然后解析每行的文本以查找是什么每行的范围。
这是一个例子:

创建演示表

CREATE TABLE ZZZItems
(
    ItemId int identity(1,1),
    ItemRanges varchar(500)
)

填充演示表

INSERT INTO ZZZItems VALUES
('10 - 20, 20 - 30, 30 - 40'),
('40 - 50, 50 - 60, 60 - 70'),
('70 - 80, 80 - 90, 90 - 100'),
('10 - 20, 20 - 30, 30 - 40')

使用CROSS APPLY分割功能表并从分割数据中提取范围

    ;WITH CTE AS
    (
        SELECT  ItemId, 
                CAST(LEFT(Data, CHARINDEX('-', Data) - 1) As Int) As RangeFrom, 
                CAST(RIGHT(Data, LEN(Data) - CHARINDEX('-', Data)) As Int) As RangeTo
        FROM ZZZItems 
        CROSS APPLY dbo.Split(ItemRanges, ',')
    )

    -- select the item ids where the requested number fits in the range.
    SELECT ItemId
    FROM CTE 
    WHERE RangeFrom < 25 
    AND RangeTo > 25

清理

DROP TABLE ZZZItems 

结果:

ItemId
-----------
1
4

我没有添加拆分功能,您应该从我链接的文章中选择您自己的功能。