首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > SQL Server >

求sql 可能存储过程!<统计每个用户发表的不同种类文章数量>

2013-09-05 
求sql 或者存储过程!统计每个用户发表的不同种类文章数量--用户表create table t_user(userId int ident

求sql 或者存储过程!<统计每个用户发表的不同种类文章数量>


--用户表
create table t_user

  userId int identity(1,1) primary key,
  userName nvarchar(10)
)
go

--文章类型表
create table t_type
(
  typeId int identity(1,1) primary key,
  typeName nvarchar(10)
)
go

--文章表
create table t_article
(
  articleId int identity(1,1) primary key,
  userId int not null,
  typeId int not null,
  articleName nvarchar(20)
  constraint [fk_article_user] foreign key (userId)  references t_user(userId),
  constraint [fk_article_type] foreign key (typeId)  references t_type(typeId)
)
go

insert into t_user values('张三') --1
insert into t_user values('李四') --2
insert into t_user values('王五') --3

insert into t_type values('新闻') --1
insert into t_type values('体育') --2
insert into t_type values('娱乐') --3

--张三(新闻3篇 ,体育2篇,娱乐1篇)
insert into t_article values(1,1,'新闻标题1')
insert into t_article values(1,1,'新闻标题2')
insert into t_article values(1,1,'新闻标题3')
insert into t_article values(1,2,'体育标题1')
insert into t_article values(1,2,'体育标题2')
insert into t_article values(1,3,'娱乐标题1')

--李四(新闻0篇,体育2篇,娱乐2篇)
insert into t_article values(2,2,'体育标题1')
insert into t_article values(2,2,'体育标题2')
insert into t_article values(2,3,'娱乐标题1')
insert into t_article values(2,3,'娱乐标题2')

--王五(无发表)

--问题:需要统计每个用户发表的不同种类文章数量,格式如下:
/*
 用户姓名 新闻类别 体育类别 娱乐类别
  张三       3        2        1
  李四       0        2        2
  王五       0        0        0
*/


[解决办法]

SELECT 
用户姓名=username,
新闻类别 = ISNULL([新闻], 0),
体育类别 = ISNULL([体育], 0),
娱乐类别 = ISNULL([娱乐], 0)
FROM
(
SELECT a.username,c.typename, cnt=COUNT(b.articleid)
FROM t_user A
LEFT JOIN t_article b
ON A.userId=b.userId
LEFT JOIN t_type C
ON B.typeid = c.typeid
GROUP BY a.userid,a.username,c.typeid,c.typename
) a
PIVOT
(
MAX(cnt) FOR typename IN([新闻],[体育],[娱乐])
) b
/*
用户姓名新闻类别体育类别娱乐类别
李四022
王五000
张三321
*/

[解决办法]
SELECT 
用户姓名=username,
新闻类别 = ISNULL([新闻], 0),
体育类别 = ISNULL([体育], 0),
娱乐类别 = ISNULL([娱乐], 0)
FROM
(
SELECT a.userid,a.username,c.typename, cnt=COUNT(b.articleid)
FROM t_user A
LEFT JOIN t_article b
ON A.userId=b.userId
LEFT JOIN t_type C
ON B.typeid = c.typeid
GROUP BY a.userid,a.username,c.typeid,c.typename
--ORDER BY username
) a
PIVOT
(
MAX(cnt) FOR typename IN([新闻],[体育],[娱乐])
) b
ORDER BY userid--排序
/*
用户姓名新闻类别体育类别娱乐类别
张三321
李四022
王五000
*/

[解决办法]

SELECT userName 用户姓名,[新闻],[体育],[娱乐] FROM 
(SELECT t3.userName,t2.typeName,ISNULL(COUNT(*),0) Qty FROM t_article t1 
LEFT JOIN t_type t2 ON t1.typeId=t2.typeId
RIGHT JOIN t_user t3 ON t1.userId=t3.userId
GROUP BY t3.userName,t2.typeName) AS userName
PIVOT(SUM(Qty) FOR typeName IN([新闻],[体育],[娱乐])) a

/*结果:
用户姓名新闻体育娱乐
李四NULL22
王五NULLNULLNULL
张三321
*/

[解决办法]
动态sql语法

declare @sql varchar(8000)
set @sql=''
select @sql=@sql + ',['+rtrim(typeName)+']=count(case rtrim(typeName) when '''+rtrim(typeName)+''' then 1 end)'
from t_type group by rtrim(typeName)
print @sql

exec('select userName'+@sql+' from t_user a


left join t_article b on b.userId=a.userId
left join t_type c on b.typeId=c.typeId 
group by userName')

/*
用户名体育新闻娱乐
李四202
王五000
张三231
*/

热点排行