2015-12-31 31 views
-1

我有一个像下面检查逗号分隔的列值 - SQL服务器

Id Col 
---- ------ 
1  a 
2  b 
3  a,b 
4  b,c 
5  b,a 
6  c 
7  ab 

我找SQL表,其中用户选择值“A”或“B”或两者(它可以蜜蜂可以从前端获得任何数量的值,如'a','b')。

Declare @searchval varchar(max) 
SET @Searchvalue = 'a' 
    Select id from tbl where col in (@Searchvalue) should return 1,3,5 

SET @Searchvalue = 'a,b' 
    select id from tbl where col in (@Searchvalue) should return 1,2,3,4,5 

上面的查询排除搜索数据在一起的行。

+3

您应该规范化数据库表。戈登·林诺夫会同意我的看法。 –

+0

这是正在运行的结构...我们需要解决这个问题 – Saravanan

+1

@TimBiegeleisen:我也同意 - 全心全意!什么时候所有这些自称为“数据库设计者”的人最终都会停止将多个值**放入单个数据单元中,甚至违反了关系设计的**第一范式**。 –

回答

-1

大家感谢您的贡献。我也承认DB设计不合适。我通过将列值填充到表变量中并将其用于我的查询来解决问题

DECLARE @Prog TABLE 
(
UserID INT, 
Program VARCHAR(8000) 
) 
INSERT @Prog 
SELECT UserID, 
LTRIM(RTRIM(m.n.value('.[1]','varchar(8000)'))) AS Program 
FROM 
(
SELECT ID,CAST('<XMLRoot><RowData>' + REPLACE(col,',','</RowData><RowData>') + '</RowData></XMLRoot>' AS XML) AS x 
FROM tbl 
)t 
CROSS APPLY x.nodes('/XMLRoot/RowData')m(n) 

Select * from @Prog where Program in (@SearchValue) 
0

事情是这样的:

where col = 'a' 
or col like 'a,%' 
or col like '%,a,%' 
or col like '%,a' 
or col = 'b' 
or col like 'b,%' 
or col like '%,b,%' 
or col like '%,b' 
+0

我的输入值可以是任意数量的值。 – Saravanan

+0

然后,无论您选择什么语法,您都必须快速构建sql。 –

3

显然,做正确的事情就是为您列出了合适的数据结构。 SQL对于列表有很好的数据类型:它被称为表格,而不是字符串。

有时候,你会被其他人的糟糕决定所困扰。也许构建您想查询的最简单的方法是:

where ',' + col + ',' like '%,a,%' or 
     ',' + col + ',' like '%,b,%' 

如果值实际上是单个字母,那么这可以简化 - 事实上,逗号并不真正服务在这种情况下,有目的的。你可以这样做:

where col like '%[ab]%' 
0

它`冗长,但你可以替换其中具有CHARINDEX

SELECT t.id FROM t 
JOIN t tt ON CHARINDEX(',a,',CONCAT(',',t.col,','))>0      
GROUP BY t.id 

和第二查询

SELECT t.id FROM t 
JOIN t tt ON CHARINDEX(',a,',CONCAT(',',t.col,','))>0 
         OR CHARINDEX(',b,',CONCAT(',',t.col,','))>0 
GROUP BY t.id 

FIDDLE

+0

它不限于'a'或'b',它可以是任意数量的字符 – Saravanan

0

你必须拆分搜索字符串到单独的部分,然后在您的查询中使用... 试试这个

CREATE TABLE #A(
    Id  int, 
    Col  varchar(10)) 

INSERT INTO #A 
VALUES (1, 'a'), 
     (2, 'b'), 
     (3, 'a,b'), 
     (4, 'b,c'), 
     (5, 'b,a'), 
     (6, 'c'), 
     (7, 'ab') 

DECLARE @InExp VARCHAR(255) = 'a,c', 
     @Sep VARCHAR(10) = ','; 

--<Make sure there's at least one separator in the search string  
IF CHARINDEX(@Sep, @InExp) = 0  
    SET @InExp = @InExp + @Sep; 

--Split the search string into parts 
WITH data AS (
    SELECT SUBSTRING(@InExp, 1, CHARINDEX(@Sep, @InExp)-1) AS Chr, CHARINDEX(@Sep, @InExp) as Stop 
    UNION ALL 
    SELECT SUBSTRING(@InExp, Stop + 1, CHARINDEX(@sep, @InExp, Stop)-1) AS Chr, CHARINDEX(@sep, @InExp, Stop + 1) 
    FROM data 
    WHERE Stop > 0 
) 

--Join the parts on your table 
SELECT DISTINCT a.* 
FROM #A a 
    JOIN data d ON CHARINDEX(d.Chr, a.Col) > 0 

DROP TABLE #A;