SQL根据类型字段连接两个实体

问题描述 投票:0回答:1

在我使用MSSQL Server 2016的Microsoft Dynamics CRM 2016(内部)中,我尝试创建一个报告(使用ReportServer),该报告提供有关所有未解决机会的最新活动:

我想找到机会(FilteredOpportunity)的最新活动(即FilteredActivityPointer)。此问题的第一个(简单)解决方案(带有针对MSSQL的高性能查询)随以下代码一起提供:SQL Query get most recent activiy per account (efficient query)

现在,我需要像以下那样扩展方案(从活动到机会遍历2条替代路径):enter image description here

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
sql sql-server dynamics-crm sql-server-2016 dynamics-crm-2016
1个回答
0
投票

我试图在我的MicrosoftDynamics CRM 2016中找到所有未解决机会(FilteredOpportunity)的最新活动(FilteredActivity)。听起来如此简单的事情相当复杂,因为活动可能与联系人有关,或者与机会直接相关。因此,该问题归结为以下问题:如何合并两个结果集,然后从两个结果集的组合中选择最近的活动:*每个机会提供最新活动的活动*一种提供每个帐户(每个联系人)的最新活动的]

这将需要工会。为了理解整个问题,我在下图中可视化了这种关系。:

enter image description here

对于结果集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 LinoffGMB提供的。没有那些出色的SQL专家的帮助,我将无法做到!

© www.soinside.com 2019 - 2024. All rights reserved.