在CTE之后紧跟在查询之后产生的PIVOT结果集

时间:2016-06-24 20:51:16

标签: sql-server subquery pivot common-table-expression

我有两张桌子,我从CTE得到了所需的结果,并在CTE查询后立即关注。

我唯一不确定如何通过[Lead_Created_Month]列来旋转结果集。我可能需要将结果集包装到子查询中并给它一个别名,但不确定如何。这是我的代码,它可以很好地生成所需的结果集,但是这个结果集需要通过[Lead_Created_Month]列进行旋转。

USE DatabaseName
GO
Create Table #TempSales
(
LeadID_fk int identity (1,1),
[dateCreated] datetime 
)

insert into #TempSales
values 
(NULL),
(getdate()),
(getdate()),
(NULL),
(getdate()),
(getdate()),
(getdate()),
(NULL),
(getdate()),
('2016-05-24 14:17:41.330'),
('2016-03-24 14:17:41.330'),
('2016-03-22 14:17:41.330'),
('2016-03-21 14:17:41.330'),
('2016-04-24 14:17:41.330'),
(NULL);

Create Table #TempLead
(
LeadID int identity (1,1),
[dateCreated] datetime 
)

insert into #TempLead
values 
(getdate()),
(getdate()),
(getdate()),
(getdate()),
(getdate()),
(getdate()),
(getdate()),
(getdate()),
(getdate()),
('2016-05-24 14:17:41.330'),
('2016-03-24 14:17:41.330'),
('2016-03-22 14:17:41.330'),
('2016-03-21 14:17:41.330'),
('2016-04-24 14:17:41.330'),
(getdate());
Select * from #TempLead;
Select * from  #TempSales

;with cte
as 
(Select * from #TempLead)
select count(l.LeadID) as [count of Leads], count(s.LeadID_fk) as [count of Sales],
 Cast(datepart(mm,[l].[dateCreated]) as varchar(2))+'/'+
--Cast(datepart(dd,[dateCreated]) as varchar(3))+'/'+
Cast(datepart(yyyy,[l].[dateCreated]) as varchar(5)) as [Lead_Created_Month]
from cte as l
    left join #TempSales as s on s.LeadID_fk=l.LeadID 
    and s.[dateCreated] is not null
    group by Cast(datepart(mm,[l].[dateCreated]) as varchar(2))+'/'+
    Cast(datepart(yyyy,[l].[dateCreated]) as varchar(5))

以上查询返回以下输出: Current result sent

最终结果集应如下所示:

final result set

正如您所看到的,我的代码缺少转换百分比的计算。

所以我写了这段代码来计算它:

--,Cast((Select count([s].LeadID_fk) from #TempSales as s where [s].[dateCreated] is not null 
--/* group by Cast(datepart(mm,[s].[dateCreated]) as varchar(2)) +'/'+ Cast(datepart(yyyy,[s].[dateCreated]) as varchar(5)) */
-- ) / count([l].LeadID) *100 as nvarchar(10)) + '%' as Conversion

但是这会导致此警告消息出现在SSMS中,这是正确的。只是我不知道更好的解决方案。

  

Msg 512,Level 16,State 1,Line 1 Subquery返回多于1>值。当子查询遵循=,!=,<,< =,>时,不允许这样做。 >,> =或当子查询用作表达式时。

1 个答案:

答案 0 :(得分:1)

如果你想使用一个支点,我认为你需要这样的东西 - 如果你不想硬编码yyyymm,你需要使用动态的SQL。

;with    cte as
(
select   1 as srce,year(tl.dateCreated) *100 + month(tl.dateCreated) as yyyymm,count(*) as leadcount
from    #templead tl 
group   by year(tl.dateCreated) *100 + month(tl.dateCreated) 
union all
select   2 as srce,year(ts.dateCreated) *100 + month(ts.dateCreated) ,count(*) as leadcount
from     #tempsales ts 
group   by year(ts.dateCreated) *100 + month(ts.dateCreated) 
)
select   case   
            when t.srce = 1 then 'leads'
            when t.srce = 2 then 'sales'
            when t.srce = 3 then 'comversions'
          end as ' '
          ,t.[201603],t.[201604],t.[201605],t.[201606]
from
(
select   pvt.* from
(
select   1 srce,year(tl.dateCreated) *100 + month(tl.dateCreated) as yyyymm,1 as leadcount
from    #templead tl 
) s
pivot (sum(s.leadcount) for s.yyyymm in ([201603],[201604],[201605],[201606])) pvt 
union all
select   pvt.* from
(
select   2 srce,year(ts.dateCreated) *100 + month(ts.dateCreated) as yyyymm,1 as leadcount
from    #tempsales ts 
) s
pivot (sum(s.leadcount) for s.yyyymm in ([201603],[201604],[201605],[201606])) pvt 
union all
select * from
(
select  3 srce,c1.yyyymm,cast(cast(c2.leadcount as decimal (10,5)) / cast(c1.leadcount as decimal(10,5)) * 100 as int) as conversion
from    cte c1
join    cte c2 on c1.yyyymm = c2.yyyymm and c2.srce = 2
where   c1.srce = 1
) s
pivot (max(s.conversion) for s.yyyymm in ([201603],[201604],[201605],[201606])) pvt 
) t