有一个很大的表 - 博客(假设记录大于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。
感谢任何帮助!!
答案 0 :(得分:6)
您必须规范化您的数据。意思是,单个列中不应该有多个值 - 没有分隔符。要规范化数据,您需要创建一个表来保存标记:
然后,您需要一个将BLOG记录链接到特定标记的表:
有趣的部分是使用管道分隔符从现有格式中提取数据,以便正确存储。
然后,您将能够使用以下方式获得所需的输出:
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)