2012-02-23 237 views
1

如果我在列中以逗號分隔的行中有一個名爲'Categories'的列,其中包含science,maths,english,那麼如何匹配包含maths的類別的所有行?在列中匹配逗號分隔值

我試過一個簡單的LIKE,但它不太準確,因爲可能有'poo_science',它在搜索'%science%'時會匹配兩者。

我看了一下週圍的StackOverflow,有很多類似的問題,但似乎都想返回數據作爲逗號分隔列表或什麼 - 不完全是我以後。

我不想使用存儲過程,也不能使用全文搜索。我有一個存儲過程,我在每個值附加了另一個字符('$'),然後搜索'$value$'...這是不是太討厭?我更簡單一些。

+9

這就是爲什麼多值屬性是**邪惡**。 – Yuck 2012-02-23 22:09:16

+0

@Yuck我認爲併發問題的增加是他們爲什麼**邪惡**。 – 2012-02-23 22:10:40

+5

我不會讓這個設計站得住腳。你需要一個子表格來存儲數據,這樣你纔能有效地對它進行調整。永遠不要存儲逗號列表。 – HLGEM 2012-02-23 22:12:27

回答

9

免責聲明:評論者是正確的...在單一領域的CSV是一個可怕的設計,應該重新做。

隨着中說,這裏是你如何能解決你的問題:

Categories首尾的,,這樣你可以將它們包含在你的通配符搜索:

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

我修復了一個小小的語法錯誤。該解決方案將起作用,並且將比XML解決方案更快。 (當然,它仍然需要表掃描或索引掃描)。 – usr 2012-02-23 22:25:20

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; 

這肯定不會是超高效和可伸縮性非常,但隨後對非規範化的數據時往往本身有這些問題。

5

使用FIND_IN_SET(,)

SQL:

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

或 可以檢查此鏈接FIND_IN_SET() vs IN()

+0

哇!優秀的逗號分隔列解決方案!照顧所有特殊情況。應該是被接受的答案之一! – jahackbeth 2014-10-06 08:27:08

+0

FIND_IN_SET僅限於MySQL。偉大的解決方案,但不是在SQL Server上。 – snort 2014-11-11 00:30:32

1

這個問題是可見谷歌,有很多意見,所以我想分享我的方法解決這個問題。我不得不將這種糟糕的設計作爲以逗號分隔的值存儲爲字符串來處理。我在調整CMS負責標籤的插件時遇到了這個問題。

是的,與網站文章相關的標籤存儲如下:「tag1,tag2,...,氨基胍「因此,獲得完全匹配的不是,因爲它可能最初是微不足道的出現:使用簡單LIKE,與文章標籤‘’我也得到了那些標記爲‘腳’和」 房」。不是關鍵,而是討厭。

FIND_IN_SET功能起初看起來真棒但後來事實證明,它不使用索引,如果第一個參數包含一個逗號不能正常工作。

我不想改變插件本身或更深的CMS核心這個插件是建立在這個功能上的。

另外值得一提的是,需要的標籤(substring)可以是字符串中的第一個,也可以是中間的某個地方,因此這段代碼WHERE (',' + Categories + ',') LIKE '%,science,%'並不包含所有三種情況。

最後,我結束了非常簡單的解決方案。它的工作對我來說是這樣的:

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

覆蓋所有三項方的案件;逗號作爲分隔符。希望它能幫助那些遇到過類似陷阱的人。

PS。我不是一個MySQL/DB專家,我很想閱讀這種方法的潛在缺陷,特別是在真正巨大的表格上(這不是我的情況,順便說一句)。我只是分享了我的小型研究的成果,以及我以最小的努力解決了這個問題。