【问题标题】:compare comma separated value with column collection of a table将逗号分隔值与表的列集合进行比较
【发布时间】:2015-02-26 23:18:50
【问题描述】:

一个表 X 有一个列 C1 并具有用逗号分隔的值,即 1,2,3

另一个表Y 的列C2 具有唯一的tinyint 值并且具有多行,而列C2 的值是,即

1
2
3
4
5

要求:检查X(C1)的所有值是否都存在于Y(C2)表中 试过一个:

((select Data from dbo.split(X.C1,',')) in  ((Select C2 from Y where <some condition>))) 

其中 Split 是一个用户定义的函数,它基于“逗号”进行拆分并将其放入表的各个行并返回该表,即 Split(X.C1,',') 返回一个包含多行的表,如

1
2
3

但是,使用这个查询会产生运行时错误:

子查询返回超过 1 个值。这是不允许的,当 子查询遵循 =、!=、、>= 或当子查询用作 一个表达式。

请任何人帮助获得更可行的解决方案

提前致谢 基兰布萨

【问题讨论】:

  • 发布您的完整查询。在您给定的查询中,没有异常运算符。
  • 理想情况下,更改设计。 SQL 有一种设计 的数据类型,用于保存多个值并为处理这些值提供了很多支持——它被称为表。将多个值填充到一个字符串中,然后努力将它们作为单独的值使用,这不是由 SQL 的限制引起的,而是由使用错误的数据类型引起的。

标签: sql-server


【解决方案1】:

我认为您必须加入查询的两个部分。

((SELECT Data from dbo.split(X.C1,',') WHERE data.C1 IN ((Select C2 from Y WHERE <some condition>))) 

【讨论】:

    【解决方案2】:

    删除不需要的括号并添加where条件

    SELECT Data
    FROM   dbo.Split(X.C1, ',')
    WHERE  data IN (SELECT C2
                    FROM   Y
                    WHERE <SOME condition>) 
    

    【讨论】:

      【解决方案3】:

      我建议您拆分逗号分隔值并存储在表变量中。这将帮助您查询您的记录。

      为了您的参考,我使用 CROSS Apply 创建了一个小 sqlfiddle 来拆分逗号分隔值并签入 Y 表。

      CLICK HERE FOR FIDDLE

      你也可以参考下面的完整代码:

      Create table x (c1 varchar(10) )
      
      insert into x values ('1,2,3')
      insert into x values ('1,2,4')
      insert into x values ('2,3,4')
      insert into x values ('1,2')
      
      create table Y (c1 tinyint) 
      insert into Y values (1)
      insert into Y values (2)
      insert into Y values (3)
      insert into Y values (4)
      insert into Y values (5)
      
      
      SELECT DISTINCT Data.C1
      FROM   
      (select 
        n.r.value('.', 'varchar(50)') AS C1
      from x as T
        cross apply (select cast('<r>'+replace(replace(c1,'&','&amp;'), ',', '</r><r>')+'</r>' as xml)) as S(XMLCol)
        cross apply S.XMLCol.nodes('r') as n(r))  DATA
      WHERE  data.C1 IN (SELECT C1
                      FROM   Y) 
      

      编辑:根据评论用 Where 条件编辑答案

      请参考下面的新小提琴链接 编辑小提琴CLICK HERE

      对于相同的表结构,新的选择查询来识别值出现的列。

      SELECT DISTINCT Data.C1, DATA.FROMX
      FROM   
      (select 
       T.C1 as FROMX, 
        n.r.value('.', 'varchar(50)') AS C1
      from x as T
        cross apply (select cast('<r>'+replace(replace(c1,'&','&amp;'), ',', '</r><r>')+'</r>' as xml)) as S(XMLCol)
        cross apply S.XMLCol.nodes('r') as n(r))  DATA
      WHERE  data.C1 IN (SELECT C1
                      FROM   Y WHERE Y.C1 = 4) 
      

      【讨论】:

      • 指定的条件,SELECT Data FROM dbo.Split(X.C1, ',') WHERE data IN (SELECT C2 FROM Y WHERE ) 在存储过程中使用获取布尔值值(真/假),为了从其他表中选择更多的值,给定的解决方案来获得表结果,即使我们是通过“拆分”方法获得的。任何其他解决方案,请
      • 您可以在查询中添加您的条件,例如WHERE Y.C1 = 2
      • X.C1= 1,2,3 and Y.C1(rows) = 1 2 3 4 5 6,在这种情况下,X.C1的1,2,3存在于Y.C1中(行),并且该条件应返回未发生的适当布尔值
      • 请检查更新的链接,如果您有任何问题,请告诉我。
      【解决方案4】:

      万岁!!!!终于找到解决办法了:)

      声明@Int_Res varchar(max) 设置@Int_Res = '' SELECT @Int_Res = @Int_Res + ',' + Cast(C1 as varchar) FROM X where

      dbo.Split((@Int_Res ),',') Int_Result

      (Int_Result.Data in (Select C1 from Y where ))

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-10-17
        • 1970-01-01
        • 2020-05-14
        • 2017-04-20
        • 1970-01-01
        • 2019-03-18
        • 1970-01-01
        相关资源
        最近更新 更多