我的问题与这个问题并不完全相似
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
谢谢
答案 0 :(得分:3)
如果可行的话,使用逗号分隔值来存储在数据库中是不行的,尝试制作单独的表来存储它们,因为这很可能是1:n
关系。
如果这不可行,那么有以下几种方法可以做到这一点,
如果您要匹配的值的数量保持不变,那么您可能希望根据您的要求执行一系列Like
语句和OR/AND
。
前 -
WHERE
Media LIKE '%21%'
OR Media LIKE '%30%'
OR Media LIKE '%40%'
但是,上述查询可能会捕获包含21
的所有值,因此即使返回值为1210
,210
的列也是如此。为了克服这个问题,您可以执行以下技巧,这会妨碍性能,因为它使用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对表格进行逗号分隔值,最后你会得到如下表格。
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