【问题标题】:PIVOT result set produced by a query immediately following after CTE紧随 CTE 之后的查询生成的 PIVOT 结果集
【发布时间】:2016-06-24 20:51:15
【问题描述】:

我有两个表,我从 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))

上述查询返回以下输出:

最终的结果集应该是这样的:

如您所见,我的代码缺少转化百分比的计算。

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

--,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 中,这是正确的。只是我不知道更好的解决方案。

消息 512,级别 16,状态 1,第 1 行子查询返回超过 1 个 > 值。当子查询跟随 =、!=、 >、>= 或子查询用作表达式时,这是不允许的。

【问题讨论】:

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


    【解决方案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
    

    【讨论】:

    • 非常感谢。只是关于如何在 Conversion PIVOT 输出中使用 cast 或 convert 的问题?这是上面代码的最后两行: pivot (max(s.conversion) for s.yyyymm in ([201603],[201604],[201605],[201606])) pvt ) t;
    • 您可以添加 case 语句,例如 case when t.srce = 3 then cast(t.[201603] as varchar(max)) + '%' else cast(t.[201603] as varchar (max)) 在 cte 定义之后立即在 select 中以 [201603] 结尾
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多