簡體   English   中英

匹配列中的逗號分隔值

[英]Match comma separated values in column

如果我有一個名為 'Categories' 的列,在行中用逗號分隔,如圖所示,我將如何將所有行與包含science,maths,english的類別maths

我嘗試了一個簡單的LIKE ,但它不是很准確,因為在搜索'%science%'時可能會有 'poo_science' 匹配兩者。

我環顧了 StackOverflow,有很多類似的問題,但似乎都想以逗號分隔的列表或其他形式返回數據——這不是我想要的。

我寧願不使用存儲過程,也不能使用全文搜索。 我有一個我使用的存儲過程,它在每個值周圍添加了另一個字符('$') ,然后會搜索'$value$'...這太討厭了嗎? 我追求更簡單的方法。

免責聲明:評論員是對的……單個字段中的 CSV 是一個糟糕的設計,應該重新做。

話雖如此,以下是解決問題的方法:

使用前導和尾隨,填充Categories ,這樣您就可以將它們包含在通配符搜索中:

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

使用 FIND_IN_SET(,)

SQL:

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

或者可以檢查這個鏈接FIND_IN_SET() vs IN()

我提出了一個 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 */

這樣,應該選擇所有“科學”行,但不選擇“poo_science”行。

這個問題在google上是可見的並且有很多觀點,所以我想分享我對這個問題的處理方法。 我不得不處理如此糟糕的設計,因為逗號分隔的值也存儲為字符串。 我在調整負責標簽的 CMS 插件時遇到了這個問題。

是的,與網站文章相關的標簽是這樣存儲的:“ tag1,tag2,...,tagN ”。 因此,獲得精確匹配並不像最初看起來那么簡單:使用簡單的LIKE ,文章標記為“”,我也得到了標記為“足球”和“球”的文章。 不重要,但很煩人。

FIND_IN_SET函數起初看起來很棒,但后來發現它不使用索引並且如果第一個參數包含逗號字符則無法正常工作。

我不想改變插件本身或構建該插件的更深層次的 CMS 核心功能。

另外值得注意的是,需要的標簽(子字符串)可以是字符串中的第一個、最后一個元素也可以是中間的某個地方,所以這段代碼WHERE (',' + Categories + ',') LIKE '%,science,%'沒有涵蓋所有三種情況。

最后,我得到了非常簡單的解決方案。 它對我有用:

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

涵蓋所有情況; 逗號用作分隔符。 希望它可以幫助遇到類似陷阱的其他人。

PS。 我根本不是 MySQL/DB 專家,我很想了解這種方法的潛在缺點,尤其是在非常大的表上(這不是我的情況,順便說一句)。 我只是分享了我的小型研究的結果,以及我為解決這個問題所做的努力。

我對您的數據布局做了一些假設。 試試這個 - 使用 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;

它絕對不會是超高效或非常可擴展的,但是處理非規范化數據往往會固有地存在這些問題。

使用 FIND_IN_SET() mysql 函數

句法

SELECT * FROM as a WHERE FIND_IN_SET(value to search in string,comma separated string);

例子

SELECT * FROM as a 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/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM