SQL Server 的逗号分隔输入字符串

Posted

技术标签:

【中文标题】SQL Server 的逗号分隔输入字符串【英文标题】:Comma-separated input string for SQL Server 【发布时间】:2015-10-05 14:44:48 【问题描述】:

您好 SQL Server 专家。请帮助我将布尔逻辑(与、或)应用于 SQLsServer 中以逗号分隔的输入字符串的有效方法。

例子:

DECLARE @ATable TABLE(ID INT, Value varchar(50))

INSERT INTO @ATable 
VALUES (1, 'A'), (1, 'B'), (1, 'C'), (2, 'C'), (2, 'D'), (3, 'A'), (4, 'B')

declare @inputStr varchar(max)
set  @inputStr = 'A,B,C,D'

declare @andOr varchar(30)  -- can be either 'and' or 'or'

if @andOr = 'and',我想获取同时具有值​​ A 和 B 的 Id。在上表中,结果将是 Id 为 1 的数据。所以结果将是

ID | Values
-----------
1  | A,B,C

if @andOr = 'or',我想获取值为 A 或 B 的 Id。在上表中,结果将是 Id 为 1,3 和 4 的数据。所以结果将是

ID | Values
-----------
1  | A,B,C
3  | A
4  | B

谢谢。

【问题讨论】:

我尝试过使用动态sql,但是当输入字符串的长度增加时它变得很慢 您需要将字符串拆分为单独的行,以便能够最好地处理对其进行的任何类型的查询。更好的是 - 首先有一个表值参数而不是字符串! 对于 AND 案例,您需要按照 Bridge 的建议进行操作。 IN 子句通常适用于您的 OR 案例。 对于您的 @andOr 案例,为什么包含 2 个而排除 4 个? 谢谢@Beth。更新 【参考方案1】:

请测试以下 SQL Select 语句

首先要注意的是SQL string split function 您可以在数据库上创建用户定义的拆分函数的副本

我使用COUNT() aggregate function with Partition By 子句。这对于程序员来说也是 T-SQL 的一大增强。我用它来检查所有输入参数字符串是否与@ATable 值匹配

最后一个技巧是string concatenation in SQL 用于显示。我使用“For XML Path”进行字符串连接以满足您的要求

DECLARE @ATable TABLE(ID INT, Value varchar(50))
INSERT INTO @ATable VALUES (1,'A'),(1,'B'),(1,'C'),(2,'C'),(2,'D'),(3,'A'),(4,'B')

declare @inputStr varchar(max)
set  @inputStr='A,B'
declare @andOr varchar(30) 

set @andOr='and'

SELECT
  t.ID,
  STUFF(
    (
      SELECT ',' + t1.Value
      FROM @ATable t1
      WHERE t1.ID = t.ID
      FOR XML PATH(''),TYPE
      ).value('.','VARCHAR(MAX)'
    ), 1, 1, '') as [Values]
FROM (
    select 
        distinct ID
    from (
    select
        s.cnt, t.*, 
        tcount = count(t.value) over (partition by t.id)
    from (
        select *, cnt = count(*) over (partition by 1) from dbo.split(@inputStr,',') s
    ) s
    left join @ATable t on s.val = t.value
    ) r
    where tcount = cnt
) t

set @andOr='or'

SELECT
  t.ID,
  STUFF(
    (
      SELECT ',' + t1.Value
      FROM @ATable t1
      WHERE t1.ID = t.ID
      FOR XML PATH(''),TYPE
      ).value('.','VARCHAR(MAX)'
    ), 1, 1, '') as [Values]
FROM (
    select
        distinct t.ID
    from dbo.split(@inputStr,',') s
    inner join @ATable t on s.val = t.value
) t

结果是

【讨论】:

以上是关于SQL Server 的逗号分隔输入字符串的主要内容,如果未能解决你的问题,请参考以下文章

使用 SQL Server 将逗号分隔的文本转换为多列结果

在 SQL Server 中检查逗号分隔字符串中是不是存在子字符串的最有效方法

我想拆分用逗号分隔的字符串并在 SQL Server 中另存为新行 [重复]

在 SQL 的 INT 列中输入逗号分隔的字符串

基于输入范围的排序逗号分隔字符串的 MAX/MIN 的 SQL 查询

拆分逗号分隔参数传递给SQL Server 2008 R2中的存储过程