本帖最后由 zhlinpb 于 2011-09-11 22:50:39 编辑

解决方案 »

  1.   

    到论坛上找一下拆分字符串类的例子,然后用公用表达式把表拆分成id,单个key的形式,然后就好查了.
      

  2.   

    先按照如下进行拆分,后面的事情自己搞定.
    /*
    标题:简单数据拆分(version 2.0)
    作者:爱新觉罗.毓华(十八年风雨,守得冰山雪莲花开)
    时间:2010-05-07
    地点:重庆航天职业学院
    描述:有表tb, 如下:
    id          value
    ----------- -----------
    1           aa,bb
    2           aaa,bbb,ccc
    欲按id,分拆value列, 分拆后结果如下:
    id          value
    ----------- --------
    1           aa
    1           bb
    2           aaa
    2           bbb
    2           ccc
    */--1. 旧的解决方法(sql server 2000)create table tb(id int,value varchar(30))
    insert into tb values(1,'aa,bb')
    insert into tb values(2,'aaa,bbb,ccc')
    go--方法1.使用临时表完成
    SELECT TOP 8000 id = IDENTITY(int, 1, 1) INTO # FROM syscolumns a, syscolumns b SELECT A.id, value = SUBSTRING(A.[value], B.id, CHARINDEX(',', A.[value] + ',', B.id) - B.id)
    FROM tb A, # B
    WHERE SUBSTRING(',' + A.[value], B.id, 1) = ','DROP TABLE #--方法2.如果数据量小,可不使用临时表
    select a.id , value = substring(a.value , b.number , charindex(',' , a.value + ',' , b.number) - b.number) 
    from tb a join master..spt_values  b 
    on b.type='p' and b.number between 1 and len(a.value)
    where substring(',' + a.value , b.number , 1) = ','--2. 新的解决方法(sql server 2005)
    create table tb(id int,value varchar(30))
    insert into tb values(1,'aa,bb')
    insert into tb values(2,'aaa,bbb,ccc')
    go--方法1.使用xml完成
    SELECT A.id, B.value FROM
    (
      SELECT id, [value] = CONVERT(xml,'<root><v>' + REPLACE([value], ',', '</v><v>') + '</v></root>') FROM tb
    ) A OUTER APPLY
    (
      SELECT value = N.v.value('.', 'varchar(100)') FROM A.[value].nodes('/root/v') N(v)
    ) B--方法2.使用CTE完成
    ;with tt as 
    (select id,[value]=cast(left([value],charindex(',',[value]+',')-1) as nvarchar(100)),Split=cast(stuff([value]+',',1,charindex(',',[value]+','),'') as nvarchar(100)) from tb
    union all
    select id,[value]=cast(left(Split,charindex(',',Split)-1) as nvarchar(100)),Split= cast(stuff(Split,1,charindex(',',Split),'') as nvarchar(100)) from tt where split>''
    )
    select id,[value] from tt order by id option (MAXRECURSION 0)
    DROP TABLE tb/*
    id          value
    ----------- ------------------------------
    1           aa
    1           bb
    2           aaa
    2           bbb
    2           ccc(5 行受影响)
    */
      

  3.   

    以下为sql 2000中使用临时表的方法,有关2005的方法见上.
    create table tb(ID varchar(10),keywords varchar(100))
    insert into tb values('a1', '中国,任命,程序,公式,故事')
    insert into tb values('a2', '中国,任命,程序,公式,故事')
    insert into tb values('a3', '欧洲,任命,程序,公式,故事')
    insert into tb values('a4', '欧洲,人民,公式,故事')
    insert into tb values('a5', '欧洲,程序,图像,公式,故事')
    insert into tb values('a6', '中国,人民,java,数据库,程序,公式')
    insert into tb values('a7', '其他,法律,程序')
    insert into tb values('a8', '发展,编程,公式,故事')
    insert into tb values('a9', '法律,补充')
    goSELECT TOP 8000 id = IDENTITY(int, 1, 1) INTO #1 FROM syscolumns a, syscolumns b SELECT A.id, keywords = SUBSTRING(A.keywords, B.id, CHARINDEX(',', A.keywords + ',', B.id) - B.id) into #2
    FROM tb A, #1 B
    WHERE SUBSTRING(',' + A.keywords, B.id, 1) = ',' and a.id <> 'a1'SELECT A.id, keywords = SUBSTRING(A.keywords, B.id, CHARINDEX(',', A.keywords + ',', B.id) - B.id) into #3
    FROM tb A, #1 B
    WHERE SUBSTRING(',' + A.keywords, B.id, 1) = ',' and a.id = 'a1'select top 5 m.id , count(1) cnt from #2 m,#3 n where m.keywords = n.keywords group by m.id order by cnt desc
    drop table tb,#1,#2,#3/*
    id         cnt         
    ---------- ----------- 
    a2         5
    a3         4
    a6         3
    a5         3
    a4         2(所影响的行数为 5 行)
    */
      

  4.   

    1. 先找出keywords的最大值。select max(len(keywords)) from tb
    2. 根据max(len(keywords))的值,确定要分拆成几列。
    3. 建立临时表,将keyword分拆插入进这个临时表,如果keywords长度不够的就插入null
    4. 进行你的匹配查询吧。
    5. 使用select top 5 * from 从你的匹配查询结果中得到你要的5条记录。