有一数据表 如下:if object_id('tempdb.dbo.#A') is not null drop table #A
create table #A (ID INT IDENTITY(1,1),C1 VARCHAR(100),C2 VARCHAR(100))
insert into #A
select '|A|B|C|D','|D|C|A|'union all
select '|A|B|F|D','|D|F|A|B|'union all
select '|A|G|C|D','|D|G|A|'union all
select '|A|B|C|D','|D|C|A|'union all
select '|C|H|R|D','|D|C|H|'union all
select '|A|B|C|D','|D|C|A|B|'
select * from #A
就是说C2段中有的C1一定有 ,C1有的C2不一定有,就是C1包含于C2.如何判断这两这个字段中的字符是否相等呢。只是顺序乱掉而已。请各位高手指点指点。

解决方案 »

  1.   


    --1、创建字符串分割函数
    create function [dbo].[m_split](@c varchar(2000),@split varchar(2))   
      returns @t table(col varchar(200))   
      as   
        begin   
          while(charindex(@split,@c)<>0)   
            begin   
              insert @t(col) values (substring(@c,1,charindex(@split,@c)-1))   
                set @c = stuff(@c,1,charindex(@split,@c),'')   
            end   
          insert @t(col) values (@c)   
          return   
    ENDgo
    --2、创建字符串分割后的比较函数
    create FUNCTION GetState
        (
          @s1 VARCHAR(20) ,
          @s2 VARCHAR(20)
        )
    RETURNS INT
    AS 
        BEGIN
            DECLARE @i INT
            DECLARE @j INT
            DECLARE @k INT
            SELECT  @i = COUNT(DISTINCT a.col)
            FROM    dbo.m_split(@s1, '|') a
                    RIGHT JOIN ( SELECT *
                                 FROM   dbo.m_split(@s2, '|')
                               ) b ON a.col = b.col
            WHERE   a.col IS NOT NULL        SELECT  @j = COUNT(col)
            FROM    dbo.m_split(@s1, '|')
            WHERE   col IS NOT NULL        IF ( @i = @j ) 
                SET @k = 0
            ELSE 
                SET @k = 1
            RETURN @k
        ENDGO
    --3、测试数据
    declare  @A table(ID INT IDENTITY(1,1),C1 VARCHAR(20),C2 VARCHAR(20))
    insert into @A
    select '|A|B|C|D','|D|C|A|'union all
    select '|A|B|F|D','|D|F|A|B|'union all
    select '|A|G|C|D','|D|G|A|'union all
    select '|A|B|C|D','|D|C|A|'union all
    select '|C|H|R|D','|D|C|H|'union all
    select '|A|B|C|D','|D|C|A|B|'
    select * from @A WHERE dbo.GetState(C1,C2)=0--4、运行结果
    /*
    ID          C1                   C2
    ----------- -------------------- --------------------
    2           |A|B|F|D             |D|F|A|B|
    6           |A|B|C|D             |D|C|A|B|
    */
      

  2.   

    create table tb (ID INT IDENTITY(1,1),C1 VARCHAR(20),C2 VARCHAR(20))
    insert into tb
    select '|A|B|C|D','|D|C|A|'union all
    select '|A|B|F|D','|D|F|A|B|'union all
    select '|A|G|C|D','|D|G|A|'union all
    select '|A|B|C|D','|D|C|A|'union all
    select '|C|H|R|D','|D|C|H|'union all
    select '|A|B|C|D','|D|C|A|B|'
    goselect distinct t.* from tb t,
    (
    select a.ID , C1 = substring(a.C1 , b.number , charindex('|' , a.C1 + '|' , b.number) - b.number) 
    from tb a join master..spt_values  b 
    on b.type='p' and b.number between 1 and len(a.C1)
    where substring('|' + a.C1 , b.number , 1) = '|'
    ) m where t.id = m.id and m.c1 <> '' and not exists(select 1 from
    (
    select a.ID , C2 = substring(a.C2 , b.number , charindex('|' , a.C2 + '|' , b.number) - b.number) 
    from tb a join master..spt_values  b 
    on b.type='p' and b.number between 1 and len(a.C2)
    where substring('|' + a.C2 , b.number , 1) = '|'
    ) n where m.id = n.id and n.c2 <> '' and m.c1 = n.c2)drop table tb/*
    ID          C1                   C2                   
    ----------- -------------------- -------------------- 
    1           |A|B|C|D             |D|C|A|
    3           |A|G|C|D             |D|G|A|
    4           |A|B|C|D             |D|C|A|
    5           |C|H|R|D             |D|C|H|(所影响的行数为 4 行)
    */
      

  3.   

    select * from #A where ID not in
    (
    select id from
    (
    select id,cast('<root1><c1 v="'+REPLACE(stuff(c1,1,1,''),'|','"/><c1 v="')+'"/></root1>' as xml) as x1
    ,cast('<root2><c2 v="'+REPLACE(stuff(stuff(c2,1,1,''),LEN(c2)-1,1,''),'|','"/><c2 v="')+'"/></root2>' as xml) as x2
    from #a 
    ) x
    where 
    exists(
    select t1.c.value('@v','varchar(100)') from x.x1.nodes('/root1/c1') t1(c)
    except
    select t2.c.value('@v','varchar(100)') from x.x2.nodes('/root2/c2') t2(c)
    )
    )/*
    ID          C1                                  C2
    ----------- ----------------- -----------------
    2           |A|B|F|D          |D|F|A|B|
    6           |A|B|C|D          |D|C|A|B|*/
      

  4.   

    哦没注意。把前面not in 变成 in后面 exists变成not exists效率会高一点点