在我使用MSSQL Server 2016的Microsoft Dynamics CRM 2016(内部)中,我尝试创建一个报告(使用ReportServer),该报告提供有关所有未解决机会的最新活动:
我想找到机会(FilteredOpportunity)的最新活动(即FilteredActivityPointer)。此问题的第一个(简单)解决方案(带有针对MSSQL的高性能查询)随以下代码一起提供:SQL Query get most recent activiy per account (efficient query)
现在,我需要像以下那样扩展方案(从活动到机会遍历2条替代路径):
FilteredActivityPointer包含一个称为referenceobjecttypecode的字段:该字段包含:* 1与活动相关的活动,在这种情况下,字段referenceobjectid包含一个帐户的ID* 2用于与联系人相关的活动,在这种情况下,字段referenceobjectid包含联系人的ID
如何扩展以下查询...
SELECT opp.opportunityid, opp.name as OpportunityName, opp.statecode, opp.statecodename, fac.accountid, fac.name As AccountName, fa.regardingobjecttypecode, fa.activitytypecodename, fa.owneridname, fa.actualend As DateCompleted, fa.description As ActivityDescription
FROM FilteredAccount fac cross apply
(SELECT TOP 1 *
FROM FilteredActivityPointer fa
WHERE fa.regardingobjectid = fac.accountid and fa.statecode = 1 and fa.regardingobjecttypecode=1
order by fa.actualend desc
) fa
JOIN FilteredOpportunity as opp
ON fac.accountid = opp.accountid
WHERE opp.statecode = 0
...因此,我可以通过加入帐户并加入opps OR来获得最新的FilteredActivityPointer,方法是加入联系人,加入帐户并加入帐户。
我不知道如何完成此任务我以这种方式尝试过,但迷路了:
SELECT opp.opportunityid, opp.name as OpportunityName, opp.statecode, opp.statecodename, fac.accountid, fac.name As AccountName, fa.regardingobjecttypecode, fa.activitytypecodename, fa.owneridname, fa.actualend As DateCompleted, fa.description As ActivityDescription
FROM FilteredAccount fac cross apply
(SELECT TOP 1 *
FROM FilteredActivityPointer fa
WHERE fa.regardingobjectid = fac.accountid and fa.statecode = 1 and fa.regardingobjecttypecode=1
order by fa.actualend desc
) fa
FilteredAccount fac2 cross apply
(SELECT TOP 1 *
FROM FilteredActivityPointer fa2
join FilteredContact as co
ON fa2.regardingobjectid = co.contactid and fa2.regardingobjecttypecode = 2
join FilteredAccount as ac
on ac.accountid = opp.account.id;
WHERE fa.statecode = 1
order by fa.actualend desc
) fa2
JOIN FilteredOpportunity as opp
ON fac.accountid = opp.accountid
WHERE opp.statecode = 0
我试图在我的MicrosoftDynamics CRM 2016中找到所有未解决机会(FilteredOpportunity)的最新活动(FilteredActivity)。听起来如此简单的事情相当复杂,因为活动可能与联系人有关,或者与机会直接相关。因此,该问题归结为以下问题:如何合并两个结果集,然后从两个结果集的组合中选择最近的活动:*每个机会提供最新活动的活动*一种提供每个帐户(每个联系人)的最新活动的]
这将需要工会。为了理解整个问题,我在下图中可视化了这种关系。:
对于结果集1 Gordon Linoff并交付此非常有效的query:对于结果集2 GMB提供了非常聪明的query:
这两个结果都是有效的,并且非常有效。可以将两个结果集设计为提供相同的结构:与机会相关的活动。
因此对于结果集1,我准备了以下查询:
select fac.name as accountname, fa.actualend, fa.description, fa.activitytypecodename, fa.activitytypecode, fac.accountid, opp.opportunityid, opp.name as opportunityname
from FilteredAccount fac cross apply
(select top (1) fa.*
from FilteredActivityPointer fa
where fa.regardingobjectid = fac.accountid and fa.statecode = 1 and fa.activitytypecode != 10004
order by fa.actualend desc
) fa
Join FilteredOpportunity opp on opp.accountid = fac.accountid and opp.statecode = 0
并且对于结果集2,我准备了以下查询:
select t.name as accountname, t.actualend, t.description, t.activitytypecodename, t.activitytypecode, t.accountid, t.opportunityid, t.opportunityname
from (
select ac.accountid, opp.name as opportunityname, opp.opportunityid, ac.name, fa.actualend, fa.description, fa.activitytypecodename, fa.activitytypecode, row_number() over(partition by ac.accountid order by fa.actualend desc) rn
from FilteredContact co
inner join FilteredActivityPointer fa
on fa.regardingobjectid = co.contactid
and fa.regardingobjecttypecode = 2
and fa.activitytypecode != 10004
inner join FilteredAccount ac
on ac.accountid = co.accountid
inner join FilteredOpportunity opp
on opp.accountid = ac.accountid
and opp.statecode = 0
) t
where rn = 1
我试图用相同的列名排列结果集。
现在我使用联合来合并两个结果集:
select allactivities.accountname as accountname, allactivities.actualend, allactivities.description, allactivities.activitytypecodename, allactivities.activitytypecode, allactivities.accountid, allactivities.opportunityid, allactivities.opportunityname
from
(
(select fac.name as accountname, fa.actualend, fa.description, fa.activitytypecodename, fa.activitytypecode, fac.accountid, opp.opportunityid, opp.name as opportunityname
from FilteredAccount fac cross apply
(select top (1) fa.*
from FilteredActivityPointer fa
where fa.regardingobjectid = fac.accountid and fa.statecode = 1 and fa.activitytypecode != 10004
order by fa.actualend desc
) fa
Join FilteredOpportunity opp on opp.accountid = fac.accountid and opp.statecode = 0
)
Union
(select t.name as accountname, t.actualend, t.description, t.activitytypecodename, t.activitytypecode, t.accountid, t.opportunityid, t.opportunityname
from
(
select ac.accountid, opp.name as opportunityname, opp.opportunityid, ac.name, fa.actualend, fa.description, fa.activitytypecodename, fa.activitytypecode, row_number() over(partition by ac.accountid order by fa.actualend desc) rn
from FilteredContact co
inner join FilteredActivityPointer fa
on fa.regardingobjectid = co.contactid
and fa.regardingobjecttypecode = 2
and fa.activitytypecode != 10004
inner join FilteredAccount ac
on ac.accountid = co.accountid
inner join FilteredOpportunity opp
on opp.accountid = ac.accountid
and opp.statecode = 0
) t
where rn = 1
)
) allactivities
结果到这里似乎还可以。
现在我第二次使用“ over(partition)”方法,结果是:
select activity.accountname, activity.actualend, activity.description, activity.activitytypecodename, activity.activitytypecode, activity.accountid, activity.opportunityid, activity.opportunityname
from
(
select allactivities.accountname as accountname, allactivities.actualend, allactivities.description, allactivities.activitytypecodename, allactivities.activitytypecode, allactivities.accountid, allactivities.opportunityid, allactivities.opportunityname, row_number() over(partition by allactivities.accountid order by allactivities.actualend desc) row_nr
from
(
(select fac.name as accountname, fa.actualend, fa.description, fa.activitytypecodename, fa.activitytypecode, fac.accountid, opp.opportunityid, opp.name as opportunityname
from FilteredAccount fac cross apply
(select top (1) fa.*
from FilteredActivityPointer fa
where fa.regardingobjectid = fac.accountid and fa.statecode = 1 and fa.activitytypecode != 10004
order by fa.actualend desc
) fa
Join FilteredOpportunity opp on opp.accountid = fac.accountid and opp.statecode = 0
)
Union
(select t.name as accountname, t.actualend, t.description, t.activitytypecodename, t.activitytypecode, t.accountid, t.opportunityid, t.opportunityname
from
(
select ac.accountid, opp.name as opportunityname, opp.opportunityid, ac.name, fa.actualend, fa.description, fa.activitytypecodename, fa.activitytypecode, row_number() over(partition by ac.accountid order by fa.actualend desc) rn
from FilteredContact co
inner join FilteredActivityPointer fa
on fa.regardingobjectid = co.contactid
and fa.regardingobjecttypecode = 2
and fa.activitytypecode != 10004
inner join FilteredAccount ac
on ac.accountid = co.accountid
inner join FilteredOpportunity opp
on opp.accountid = ac.accountid
and opp.statecode = 0
) t
where rn = 1
)
) allactivities
) activity
where row_nr = 1
还有,瞧!
[请注意,我曾经在解决方案中添加了“联合”。上述问题的真正解决方案是由Gordon Linoff和GMB提供的。没有那些出色的SQL专家的帮助,我将无法做到!