,帮忙写个SQL语句,多谢

各位高手,帮忙写个SQL语句,谢谢
create table dp(did varchar(10),dname varchar(20));--部门

insert into dp values('1','部门1'),('2','部门2')

create table sl(did varchar(10),pid varchar(10),pname varchar(10))--产品

insert into sl values('1','1','产品1'),('2','2','产品2'),('1','3','产品3'),('2','4','产品4')

create table xl(pid varchar(10),count int,xdate date);--销量

insert into xl values('1',5,'2014-01-01'),('2',6,'2014-01-01'),('3',7,'2014-02-01'),('4',8,'2014-02-01')

统计每个部门每个月每个产品的销量。


------解决方案--------------------

declare @s varchar(max)
select @s=ISNULL(@s+',','')+'sum(case when month(xdate)='''+convert(varchar,month(xdate))+''' and a.pid='''+a.pid+''' then count end)
       as ['+CONVERT(varchar,month(xdate))+'月'+pname+']' from xl a,sl b where a.pid=b.pid group by a.pid,MONTH(xdate),pname
set @s='select case when grouping(dname)=0 then dname else ''Total'' end as 部门,'+@s+',sum(count) as total from dp c,sl b,xl a where c.did=b.did and b.pid=a.pid group by dname with rollup'
--print @s
exec(@s)
------解决方案--------------------

use tempdb
go

declare @Month1 date='20140101' --左邊的1月份
declare @Month2 date='20140201' --右邊的2月份

--pivot中的in列表
declare @ProductList nvarchar(max)=(select stuff((select ','+quotename(pname) from sl for xml path('')),1,1,''))

--最後顯示控制
declare @select_1 nvarchar(max)=(select stuff((select ',b.'+quotename(pname)+' as '+quotename(pname+N'销量_1') from sl for xml path('')),1,1,''))
declare @select_2 nvarchar(max)=(select stuff((select ',b.'+quotename(pname)+' as '+quotename(pname+N'销量_2') from sl for xml path('')),1,1,''))

declare @sql nvarchar(max)=''

set @sql='
;with cte_xl as 
(
select a.xdate,a.count,b.pname,c.dname
from xl a
inner join sl b on b.pid=a.pid
inner join dp c on c.did=b.did
where a.xdate in(@Month1,@Month2)
),cte_left as
(
select * 
from cte_xl a
 pivot(max([count]) for pname in('+@ProductList+')) b
where xdate=@Month1
),cte_right as
(
select * 
from cte_xl a
 pivot(max([count]) for pname in('+@ProductList+')) b
where xdate=@Month2
)
select a.dname as [部门名称],'+@select_1+','+@select_2+'
from dp a
left join cte_left b on b.dname=a.dname
left join cte_right c on c.dname=a.dname 
'   
exec sp_executesql @sql,N'@Month1 date,@Month2 date',@Month1,@Month2

/*
部门名称 产品1销量_1 产品2销量_1 产品3销量_1 产品4销量_1 产品1销量_2 产品2销量_2 产品3销量_2 产品4销量_2
部门1 5 NULL NULL NULL 5 NULL NULL NULL
部门2 NULL 6 NULL NULL NULL 6 NULL NULL
*/



實際報表填充時,標題名中"_1" and "_2"部份可以通過程序過濾掉不顯示。

------解决方案--------------------

难道你要介个效果?

引用:
Quote: 引用:

你是想要什么结果呢?上面按月份的合计,下面按月份,产品的合计,横向,纵向合计不都有了么?


横向合计分开,即部门1所有月份产品1合计,部门1所有月份产品2合计,这样显示可以实现吗?



IF OBJECT_ID('tempdb..#ColName','U') IS NOT NULL DROP TABLE #ColName
SELECT CAST([Month] AS NVARCHAR)+N'月'+B.pname AS ColName
,[Month]
,pname
INTO #ColName
FROM (SELECT DISTINCT MONTH(xdate) AS [Month] FROM xl ) A
CROSS JOIN (SELECT DISTINCT pname FROM sl) B

DECLARE @Sql NVARCHAR(MAX),@Sql1 NVARCHAR(MAX),@Sql2 NVARCHAR(Max),@Sql3 NVARCHAR(Max)
,@Sql4 NVARCHAR(MAX),@Sql5 NVARCHAR(MAX)
SELECT @Sql=ISNULL(@Sql+',','')+'['+ColName+']' FROM #ColName GROUP BY ColName
SELECT @Sql1=ISNULL(@Sql1+',','')+'ISNULL('+'SUM(['+ColName+'])'+',0) AS '+'['+ColName+']' FROM #ColName GROUP BY ColName
SELECT @Sql2=ISNULL(@Sql2+',','')+'['+pname+']' FROM #ColName GROUP BY pname
SELECT @Sql4=ISNULL(@Sql4+',','')+'ISNULL('+'SUM(['+pname+'])'+',0) AS '+'['+pname+N'合计'+']' FROM #ColName GROUP BY pname
SELECT @Sql5=ISNULL(@Sql5+'+','')+'ISNULL('+'SUM(['+pname+'])'+',0)'  FROM #ColName GROUP BY pname
SELECT @Sql5=ISNULL(@Sql5+N' AS 合计','')

SELECT @Sql3=N'SELECT CASE WHEN dname IS NULL THEN +'+N'N''合计'''+' ELSE dname END AS dname,'+@Sql1+','+@Sql4+','+@Sql5+N'
FROM (
SELECT did,dname,'+@Sql1+'
FROM (
SELECT A.did, A.dname
,CAST(MONTH(xdate) AS NVARCHAR(10))+'+N'N''月'''+'+B.pname AS MonthProd
,C.count
FROM dp AS A