请教大家:有一列装的是多段字串,分隔符统一,有单段有多段,单段无分隔符,形式如下:列A
---
A
A|B
D|A|G
…如何做到:WHERE xx IN (?)的效果为WHERE xx IN ('A')
WHERE xx IN ('A','B')
WHERE xx IN ('D','A','G')
…问号部分应该怎么写?我尝试过写成WHERE xx IN ('''' + REPLACE(列A,'|','''' + ',' +'''') + '''')但实践证明是行不通的,想想也是,xx要的条件是值,不是样子,还请大师们拨开云雾、指点迷津,感激不尽!

解决方案 »

  1.   


    where charindex('|'+xx+'|','|',+列A+'|') > 0
      

  2.   

    如果字符长度相同的话,可以直接用 列A like '%A%' or 列A like '%B%' or ...
    如果字符长主不同的话,可以用 '|'+列A+'|' like '%|A|% or '|'+列A+'|' like '%|B|% or ...
      

  3.   

    charindex.
    或都您那个 用动态语句。
      

  4.   

    谢谢各位热心回复,可能我没表达清楚,大家的回复仍然不能解决我的问题。
    首先1#兄台的matches实在不明白是什么,还请明示。
    charindex则是在【列A】中去找xx,实现不了用列A的字段作为xx的并列条件这一目的,列A有几个字段就并列几个条件,即WHERE xx IN ('A')
    WHERE xx IN ('A','B')
    WHERE xx IN ('D','A','G')like亦如此,首先列A中有些什么字段是不确定的,就谈不上%A%、%B%了。再来看看我的失败方法,【'''' + REPLACE(列A,'|','''' + ',' +'''') + ''''】是可以把列A格式化成:
    'A'
    'A','B'
    'D','A','G'

    这样的效果,但是无法原样传递给xx作为条件,始终跟手输有区别,所以失败。还请高人帮忙,谢谢!
      

  5.   

    用where charindex('|'+xx+'|','|',+列A+'|') > 0 不需要replace
      

  6.   


    xx的条件一定要精确,结合实际情况说吧,不然可能不大好理解。xx和【列A】其实都叫Brand(品牌列),A/B/C/D这些是品牌代码,两个Brand列来自不同的表,分别属于tdefstyle(货品表)和tdefstore(店仓表),在本次查询中,所有的连接关系如下(看名字就知道各表是干什么的):
    FROM TDefStore
    LEFT JOIN TBusRetail ON TDefStore.Store = TBusRetail.Store
    LEFT JOIN TBusRetailDt ON TBusRetailDt.MasterId = TBusRetail.MasterId
    LEFT JOIN TDefSku ON TBusRetailDt.Sku = TDefSku.Sku
    LEFT JOIN TDefStyle ON TDefSku.Style = TDefStyle.Style
    货品有brand属性,店仓也有brand属性,不同的是,货品的品牌属性是唯一的,一件货品只能属于一种品牌,但店仓不是,一个店可能售卖多种品牌的货品,属于品牌复合店,所以店仓表的Brand列就是这样:
    Brand
    ---
    A
    A|B
    D|A|G

    店铺经营哪几个品牌就在Brand字段填入几个品牌代码,代码间用“|”分割,各店铺除了销售Brand指定的品牌货品外,还会销售一些无品牌的小饰品以及少量其他品牌的货品,例如001店的Brand为A,但偶尔也可能会销售几件品牌=B的货品,以及大量无品牌的小饰品。说了大堆,现在要查询的是各店铺经营品牌范围内的货品销售情况,所以才有这个需求,即:
    where tdefstyle.brand in (对应店铺的brand)
      

  7.   

    还有这句多了个逗号吧where charindex('|'+xx+'|','|',+列A+'|')
      

  8.   

    多了个 
    where charindex('|'+xx+'|', '|'+列A+'|')
      

  9.   

    where charindex('|'+xx+'|', '|'+列A+'|')>0 不行吗?
      

  10.   


    现在不是要在列A里找XX,而是要把列A的每个字段作为xx的并列条件,你说行么
      

  11.   

    说实话,这种表设计实在是糟糕透顶,查询起来一是不好写,二是效率奇差,一点办法都没有.你的表已经是用这种分隔的段的形式了,为什么你的查询还要去用多个段去匹配呢,一个一个段去找不成么?比如
    where charindex('A',列A)>0 or charindex('B',列A)>0 or charindex('D',列A)>0
    这样不行么?当然,上面这样是当每段长度都相等时的办法,如果有长有短,那要这样:where charindex('|A|','|'+列A+'|')>0 or charindex('|B|','|'+列A+'|')>0 or charindex('|D|','|'+列A+'|')>0
    可见,相当地麻烦!
      

  12.   

    谢谢兄台热心回复,可有什么更好的办法用来记录店仓的品牌属性呢?
    说回问题,每一个店的brand是多变的,可以说是未知的,所以把品牌代码A/B/D写进条件不是办法,也实现不了某店有几个品牌就查那几个品牌的销售:
    where charindex('A',列A)>0 or charindex('B',列A)>0 or charindex('D',列A)>0
    现在的情况是,每个店明明已经有brand存储着品牌代码,只需把里面的代码提取出来,并传递给xx作为并列条件,我就不信没办法。
      

  13.   

    从数据库设计的基本处理原则来看,你这个表应该是设计成两个表才是合理的,这两个表一个是除列A以外其他的列,另一个表保存对应于前一表中各行,列A的拆分值:id  列A
    1   A
    2   A
    2   B
    3   D
    3   A
    3   G(ID 列是前一表各行的标识)
    这样,查询起来才更容易,效率也高(在设置了合理的索引时)数据库的设计和查询是根据数据库原理和设计原则来的,你没按正确的方法来设计,你就不可能有好的效果,这不是你相信不相信的事情,因为,人家的语言设计就是按人家的表设计来的,而不是按你想像的那种存储结构来的.
      

  14.   

    是啊,有道理,这么一来是明了很多。那这个问题只消把id列改成store,外键到店仓表的主键store,然后where xx in (select 列A from 品牌表 where store = '?')就成了不好意思,还得请教,现在?应该怎么写?我的预期结果集是这样:store(店仓)    qty(件数)   amt(金额)
    --------------------------------------
    001             15           3560.00
    002             21           6540.00
    ……
      

  15.   

    参考http://www.cnblogs.com/insus/articles/1918003.html试试:CREATE TABLE #T (s NVARCHAR(20))INSERT INTO #T VALUES ('G'),('D'),('E'),('F'),('A'),('G')
    DECLARE @s NVARCHAR(50) = 'D|A|G' --列ADECLARE @u NVARCHAR(50) =  REPLACE(@s,'|',''',''')EXECUTE ('SELECT * FROM #T WHERE [s] IN (''' + @u + ''')')
    上面代码在sql2008执行成功,如果不成功,请联系Insus.NET