查询不同标签列表的最佳(简单而有效)方法?

时间:2010-12-13 06:06:13

标签: sql sql-server tsql sql-server-2000

有一个很大的表 - 博客(假设记录大于1万),结构如下:

Blog_ID  Title  Tag
----------------------
1        AAA    T1|T2|T3
2        BBB    T2|T4
3        CCC    T3|T1|T2|T6|

..................

博客标签与“|”分开,绝对可以重复,我想写一个查询来获取所有不同标签以及标签外观,结果如下:

Tags   Appearance Count
------------------------
T1     14
T2     35
T3     88
T4     45

............

那么最好(简单而有效)的方法是什么?再一次限制,SQL Server 2000功能是首选,因为我的Web应用程序主机提供程序使用的是SQL Server 2000。

感谢任何帮助!!

2 个答案:

答案 0 :(得分:6)

您必须规范化您的数据。意思是,单个列中不应该有多个值 - 没有分隔符。要规范化数据,您需要创建一个表来保存标记:

标记

  • tag_id(主键)
  • tag_name

然后,您需要一个将BLOG记录链接到特定标记的表:

BLOG_TAGS

  • blog_id(主键)
  • tag_id(主键)

有趣的部分是使用管道分隔符从现有格式中提取数据,以便正确存储。

然后,您将能够使用以下方式获得所需的输出:

   SELECT t.tag_name, 
          COUNT(bt.blog_id) AS appearanceCount
     FROM TAGS t
LEFT JOIN BLOG_TAGS bt ON bt.tag_id = t.tag_id

答案 1 :(得分:1)

一般来说,OMG小马绝对是对的! 但是,如果您真的必须这样做,请查看此代码示例(我希望它对SQL Server 2000有效):

create table #t (Blog_ID int, Title varchar(50), Tag varchar(4000));
insert into #t select 1, 'AAA', 'T1|T2|T3';
insert into #t select 2, 'BBB', 'T2|T4';
insert into #t select 3, 'CCC', 'T3|T1|T2|T6';

select Tag, count(*) as AppearanceCount from (
select substring(t.Tag,
        a.n+b.n+c.n+d.n+e.n+f.n+g.n+h.n+i.n+j.n+k.n+l.n,
        charindex('|',t.Tag+'|',a.n+b.n+c.n+d.n+e.n+f.n+g.n+h.n+i.n+j.n+k.n+l.n)
            - (a.n+b.n+c.n+d.n+e.n+f.n+g.n+h.n+i.n+j.n+k.n+l.n)) as Tag
from    (select 0 as n union select 1) a,
        (select 0 as n union select 2) b,
        (select 0 as n union select 4) c,
        (select 0 as n union select 8) d,
        (select 0 as n union select 16) e,
        (select 0 as n union select 32) f,
        (select 0 as n union select 64) g,
        (select 0 as n union select 128) h,
        (select 0 as n union select 256) i,
        (select 0 as n union select 512) j,
        (select 0 as n union select 1024) k,
        (select 0 as n union select 2048) l,
        #t t
where substring('|'+t.Tag,a.n+b.n+c.n+d.n+e.n+f.n+g.n+h.n+i.n+j.n+k.n+l.n,1)='|'
) x
group by Tag;

drop table #t;

您可以(也许应该)使用UDF生成数字。它更容易阅读:

seelct Tag, count(*) as AppearanceCount from (
select substring(t.Tag, n.n, charindex('|',t.Tag+'|',n.n) as Tag
from dbo.fn_Numbers(4000) n cross join #t t
where substring('|'+t.Tag,n.n,1)='|') x group by Tag;

(感谢Itzik Ben-Gan)