在列中匹配逗号分隔值

时间:2012-02-23 22:07:19

标签: sql sql-server comma csv

如果我在“逗号分隔”行中有一个名为“类别”的列,并显示science,maths,english,如何将所有行与包含maths的类别进行匹配?

我尝试过一个简单的LIKE,但不太准确,因为搜索'%science%'时可能存在'poo_science'会与之匹配。

我看过StackOverflow并且有很多类似的问题但是所有人似乎都希望以逗号分隔的列表或其他方式返回数据 - 这不是我想要的。

我不想使用存储过程,也不能使用全文搜索。我有一个我使用的存储过程,在每个值周围添加了另一个字符('$'),然后搜索'$value$'...这是不是很讨厌?我正在采用一种更简单的方法。

6 个答案:

答案 0 :(得分:9)

免责声明:评论员是对的......单个字段中的CSV是一个可怕的设计,应该重新完成。

话虽如此,以下是解决问题的方法:

使用前导Categories填充,,这样您就可以将它们包含在通配符搜索中:

WHERE (',' + Categories + ',') LIKE '%,science,%'

答案 1 :(得分:6)

使用FIND_IN_SET(,)

SQL:

SELECT name FROM orders,company
WHERE orderID = 1 
AND 
FIND_IN_SET(companyID, attachedCompanyIDs)

或 可以查看此链接FIND_IN_SET() vs IN()

答案 2 :(得分:3)

此问题在谷歌上可见并且有很多观点,所以我想分享我对这个问题的处理方法。我不得不处理如此糟糕的设计,因为逗号分隔的值也存储为字符串。我在调整负责标签的CMS插件时遇到了这个问题。

是的,与网站文章相关的标签存储方式如下:" tag1,tag2,...,tagN "。因此,获得完全匹配并不像最初可能出现的那样微不足道:使用简单的LIKE,文章标记为" ball "我也有标记的"脚"和" 房间"。不重要,但很烦人。

FIND_IN_SET 函数起初看起来很棒,但事实证明它并没有使用索引,如果第一个参数包含逗号字符,它就无法正常工作。

我不想改变插件本身或更深层次的CMS核心功能,该插件已经构建在其上。

还值得注意的是,所需的tag(substring)可以是字符串中的第一个,最后一个元素,也可以位于中间的某个位置,因此这段代码WHERE (',' + Categories + ',') LIKE '%,science,%'并不能涵盖所有三个案例。

最后,我最终得到了非常简单的解决方案。它对我有用:

... WHERE tags LIKE 'ball,%' OR tags LIKE '%,ball,%' OR tags LIKE '%,ball'

涵盖所有案件;用作分隔符的逗号。希望它可以帮助其他遇到类似陷阱的人。

PS。我根本不是MySQL / DB专家,我很想读到这种方法的潜在缺点,尤其是在真正庞大的桌子上(这不是我的情况,顺便说一下)。我只是分享了我的小型研究成果,以及我用最少的努力解决这个问题所做的工作。

答案 3 :(得分:2)

我对您的数据布局做了一些假设。试试这个 - 使用SQL Server 2K8 +这应该可行:

DECLARE @SearchString NVarChar(100) = 'maths';

SELECT 1 SomeId, 'science,maths,english' Categories
INTO #TestTable;

WITH R AS (
  SELECT
    X.SomeId,
    C.value('@value', 'NVarChar(100)') SomeTagValue
  FROM (SELECT SomeId,
          CONVERT(XML, '<tag value = "' + REPLACE(Categories, ',', '" /><tag value = "') + '" />') XMLValue
        FROM #TestTable) X CROSS APPLY X.XMLValue.nodes('//tag') T(C)
)
SELECT *
FROM R
WHERE SomeTagValue = @SearchString;

DROP TABLE #TestTable;

它绝对不会超级高效或可扩展性很高,但是反对非规范化数据的工作往往会产生这些问题。

答案 4 :(得分:1)

使用FIND_IN_SET()mysql函数

语法

SELECT * FROM as WHERE FIND_IN_SET(要在字符串中搜索的值,以逗号分隔的字符串);

实施例

SELECT * FROM as WHERE FIND_IN_SET(5,“1,2,3,4,5,6”);

更多信息请点击以下链接:

http://blog.sqlauthority.com/2014/03/21/mysql-search-for-values-within-a-comma-separated-values-find_in_set/

答案 5 :(得分:1)

我提出了一个可以匹配任何可能情况的4x WHERE:单独的值,csv的开头,中间或结尾的值:

WHERE Categories = 'science'     /* CSV containing only the one value */
OR Categories LIKE 'science,%'   /* value at start of CSV */
OR Categories LIKE '%,science,%' /* value somewhere in the middle */
OR Categories LIKE '%,science'   /* value at the end of CSV */

这种方式所有的科学&#39;应该选择行但是没有“poo_science”#39;行。