如何从逗号分隔值字段中选择数据行

时间:2016-12-05 10:56:30

标签: sql-server sql-server-2008 ssms

我的问题与这个问题并不完全相似

How to SELECT parts from a comma-separated field with a LIKE statement

但我没有看到任何答案。所以我再次发布我的问题。

我有下表

╔════════════╦═════════════╗
║ VacancyId  ║  Media      ║
╠════════════╬═════════════╣
║     1      ║ 32,26,30    ║
║     2      ║ 31, 25,20   ║
║     3      ║ 21,32,23    ║
╚════════════╩═════════════╝

我想选择媒体ID = 30或媒体= 21或媒体= 40

的数据

因此,在这种情况下,输出将返回第1行和第3行。

我该怎么做?

我尝试了像'30'这样的媒体,但这并没有带来任何价值。另外,我只是不需要在该字段中搜索一个字符串。

我的数据库是SQL Server

谢谢

5 个答案:

答案 0 :(得分:3)

如果可行的话,使用逗号分隔值来存储在数据库中是不行的,尝试制作单独的表来存储它们,因为这很可能是1:n关系。

如果这不可行,那么有以下几种方法可以做到这一点, 如果您要匹配的值的数量保持不变,那么您可能希望根据您的要求执行一系列Like语句和OR/AND

前 -

WHERE
    Media LIKE '%21%'
    OR Media LIKE '%30%'
    OR Media LIKE '%40%' 

但是,上述查询可能会捕获包含21的所有值,因此即使返回值为1210210的列也是如此。为了克服这个问题,您可以执行以下技巧,这会妨碍性能,因为它使用where子句中的函数,这违反了进行Seargable查询。 但就是这样,

--Declare valueSearch variable first to value to match for you can do this for multiple values using multiple variables.

Declare @valueSearch = '21'

-- Then do the matching in where clause
WHERE 
    (',' + RTRIM(Media) + ',') LIKE '%,' + @valueSearch + ',%'

如果要匹配的值的数量会发生变化,那么您可能需要查看FullText Index并且您应该考虑相同的问题。 如果您决定在Fulltext Index之后继续使用此功能,您可以按照以下步骤进行操作,以获得所需内容,

实施例.-

WHERE 
     CONTAINS(Media, '"21" OR "30" OR "40"')

答案 1 :(得分:2)

我可以建议的最好的方法是首先使用This link对表格进行逗号分隔值,最后你会得到如下表格。

enter image description here

SELECT * FROM Table
WHERE Media in('30','28')

一定会有效。

答案 2 :(得分:1)

如果您确定包含字符串Media的任何30值都是您希望返回的值,则只需在LIKE语句中包含通配符:

SELECT *
FROM Table
WHERE Media LIKE '%30%'

请记住,这也会返回媒体值为298,300,302的记录,因此,如果这对您有问题,您需要考虑更复杂的方法,例如:

SELECT *
FROM Table
WHERE Media LIKE '%,30,%'
OR Media LIKE '30,%'
OR Media LIKE '%,30'
OR Media = '30'

如果字符串中可能有空格(根据您的问题),您还要删除它们:

SELECT *
FROM Table
WHERE REPLACE(Media,' ','') LIKE '%,30,%'
OR REPLACE(Media,' ','') LIKE '30,%'
OR REPLACE(Media,' ','') LIKE '%,30'
OR REPLACE(Media,' ','') = '30'

修改:我实际上更喜欢Coder of Code的解决方案:

SELECT *
FROM Table
WHERE ',' + LTRIM(RTRIM(REPLACE(Media,' ',''))) + ',' LIKE '%,30,%'

您提到希望在此字段中搜索多个字符串,这也是可能的:

SELECT *
FROM Table
WHERE Media LIKE '%30%'
   OR Media LIKE '%28%'

SELECT *
FROM Table
WHERE Media LIKE '%30%'
  AND Media LIKE '%28%'

答案 3 :(得分:1)

你可以使用它,但性能不可避免地很差。正如其他人所说,你应该将这种结构规范化。

WHERE
       ',' + media + ',' LIKE '%,21,%'
    OR ',' + media + ',' LIKE '%,30,%'
    Etc, etc...

答案 4 :(得分:1)

此解决方案使用RECURSIVE CTE识别字符串中每个逗号的位置,然后使用SUBSTRING返回逗号之间的所有字符串。

我已经留下了一些不必要的代码,以帮助您了解它所做的事情。您可以将其剥离以提供您所需的确切内容。

DROP TABLE #TMP
CREATE TABLE #TMP(ID INT, Vals CHAR(100))

INSERT INTO  #TMP(ID,VALS)
VALUES
(1,'32,26,30')
,(2,'31, 25,20')
,(3,'21,32,23')

;WITH cte
    AS
    (
    SELECT
        ID
        ,VALS
        ,0 POS
        ,CHARINDEX(',',VALS,0) REM
    FROM
        #TMP
    UNION ALL
        SELECT ID,VALS,REM,CHARINDEX(',',VALS,REM+1)
        FROM
        cte c 
        WHERE CHARINDEX(',',VALS,REM+1) > 0
    UNION ALL
        SELECT ID,VALS,REM,LEN(VALS)
        FROM
        cte c 
        WHERE POS+1 < LEN(VALS) AND CHARINDEX(',',VALS,REM+1) = 0
    )
,cte_Clean
    AS
    (
    SELECT ID,CAST(REPLACE(LTRIM(RTRIM(SUBSTRING(VALS,POS+1,REM-POS))),',','') AS INT) AS VAL FROM cte
    WHERE POS <> REM
    )
SELECT
    ID
FROM
    cte_Clean
WHERE
    VAL = 32
ORDER BY ID