SQL语言艺术 第11章 精于计谋:挽救响应时间 复杂字段的解析

    测试数据

create table movies  --电影表
(movie_id int,           --电影ID
 
actors varchar(50))    --演员ID
go

insert into
movies
values
(1,'123,456,78,96') ,
(
2,'23,67,97') ,
(
3,'67,456')

  

     查询语句需用到枢轴表    SQL语言艺术 第11章 精于计谋:挽救响应时间 枢轴表

  

     该测试表的问题在于把需要处理的多项数据(演员ID)一个接一个的保存在单一字段内,数据之间以分隔符分开。而用户想看到的效果是抽取actors字段的不同的组成部分,然后以单独的形式依次返回这些不同部分。

最终结果

movie_id    actorid
----------- ----------------------------------------------------
1           123
1           456
1           78
1           96
2           23
2           67
2           97
3           67
3           456

(9 row(s) affected)

查询语句

方法一

select movie_id,  

      substring(
          
actors,
          
case id
                when 1 then 1
                else id + 1
           end,
          
case next_sep
                when 1 then len(actors)
               
else case id
                          when 1 then next_sep - 1
                          else next_sep - 2
                     end
           end
      
) as actorid
from
(select id,movie_id,actors,
 
charindex(',',substring(actors,id      ,len(actors)))      first_sep--分隔符第一次出现的位置
 
charindex(',',substring(actors,id + 1,len(actors))) + 1 next_sep   --将要分离的演员ID的长度(包括分隔符)
from movies,# where id <= 50 
   and (id = 1 or charindex(',',substring(actors,id,len(actors))) = 1)) as a

子查询结果

id          movie_id    actors                                             first_sep   next_sep
----------- ----------- -------------------------------------------------- ----------- -----------
1           1           123,456,78,96                                      4           4
4           1           123,456,78,96                                      1           5
8           1           123,456,78,96                                      1           4
11          1           123,456,78,96                                      1           1
1           2           23,67,97                                              3           3
3           2           23,67,97                                              1           4
6           2           23,67,97                                              1           1
1           3           67,456                                                 3           3
3           3           67,456                                                 1           1

(9 row(s) affected)


方法二  在字段两端添加分隔符
    本方法比第一个方法好在外部查询时不用分情况取值

select movie_id,substring(actor_id,id + 1,next_sep - 2) as actorid
from
(select id,movie_id,',' + actors + ',' as actor_id,
 
charindex(',',substring(',' + actors + ',',id     ,len(',' + actors + ',')))       first_sep--分隔符第一次出现的位置 
 
charindex(',',substring(',' + actors + ',',id + 1,len(',' + actors + ','))) + 1 next_sep  --将要分离的演员ID的长度(包括2个分隔符)
from movies,# where id <= 50 
  and charindex(',',substring(',' + actors + ',',id     ,len(',' + actors + ',')))        = 1
  and charindex(',',substring(',' + actors + ',',id + 1,len(',' + actors + ','))) + > ) as a

子查询结果

id          movie_id    actor_id                                             first_sep   next_sep
----------- ----------- ---------------------------------------------------- ----------- -----------
1           1           ,123,456,78,96,                                      1           5
5           1           ,123,456,78,96,                                      1           5
9           1           ,123,456,78,96,                                      1           4
12          1           ,123,456,78,96,                                      1           4
1           2           ,23,67,97,                                              1           4
4           2           ,23,67,97,                                              1           4
7           2           ,23,67,97,                                              1           4
1           3           ,67,456,                                                 1           4
4           3           ,67,456,                                                 1           5

(9 row(s) affected)

posted on 2011-04-21 17:54  天空一角  阅读(432)  评论(0编辑  收藏  举报