SUM CASE LEFT JOIN输出给出错误的总和

时间:2019-04-10 14:57:46

标签: sql-server sum left-join case

我有多个左联接,需要聚合和非规范化数据 如本例所示,我得到3个FanActivities的总和,而不是Fan的1个FanActivities。

示例:https://rextester.com/FOO26444

SELECT 
SUM(CASE WHEN fa.ProfileFanId=1111 and fa.ActivityId=2 THEN 1 ELSE 0 END) as conditionalcountall

FROM #Fan f
LEFT JOIN #ProfileFan pf
    ON pf.FanId = f.Id
LEFT JOIN #LinkedInProfile lip
    ON lip.Id = pf.ProfileId
LEFT JOIN #FanActivity fa
    ON fa.ProfileFanId = pf.Id
LEFT JOIN #Activity a
    ON a.Id = fa.ActivityId
LEFT JOIN #DeliveryActions das
    ON das.ProfileFanId = pf.Id
LEFT JOIN #DeliveryAction da
    ON da.Id = das.DeliveryActionId

-------------------------   
id |conditionalcountall |
-------------------------
  1          3          |
-------------------------

当我删除最后2个左联接时,它会提供所需的输出1。但是我需要这2个联接来聚合来自这2个表的其他数据。

SELECT 
    SUM(CASE WHEN fa.ProfileFanId=1111 and fa.ActivityId=2 THEN 1 ELSE 0 END) as conditionalcountall

    FROM #Fan f
    LEFT JOIN #ProfileFan pf
        ON pf.FanId = f.Id
    LEFT JOIN #LinkedInProfile lip
        ON lip.Id = pf.ProfileId
    LEFT JOIN #FanActivity fa
        ON fa.ProfileFanId = pf.Id
    LEFT JOIN #Activity a
        ON a.Id = fa.ActivityId

id |conditionalcountall |
-------------------------
 1 |             1      |
-------------------------

我在做什么错了?

2 个答案:

答案 0 :(得分:1)

您可以借助不同的逻辑获得所需的结果。 对于给定的方案,您可以通过更改逻辑情况来实现此目的

SELECT  COUNT(DISTINCT 
             CASE WHEN fa.ProfileFanId=1111 and fa.ActivityId=2 
                  THEN CAST(fa.ProfileFanId AS VARCHAR) + '-' + CAST(fa.ActivityId AS VARCHAR) 
             ELSE NULL END
        ) as conditionalcountall

在这种逻辑情况下,当使用所需字段的组合设置字符串时,当条件旁路设置为null时,因为我们知道count子句不对null字段进行计数,并且借助distance,您将得到1而不是3

答案 1 :(得分:0)

#DeliveryActions和#DeliveryAction在联接上必须有多行。如果您只想查找一次它是否存在,则必须将这些表中的数据分组。

-替换此

LEFT JOIN #DeliveryActions das
    ON das.ProfileFanId = pf.Id
LEFT JOIN #DeliveryAction da
    ON da.Id = das.DeliveryActionId

-这是

LEFT JOIN (SELECT ProfileFanId
            FROM #DeliveryActions ia
            LEFT JOIN #DeliveryAction ib
            ON ia.DeliveryActionId = ib.Id
            GROUP BY ProfileFanId) das
            ON das.ProfileFanId = pf.Id

请注意,因为您到处都在使用LEFT JOIN,所以其他任何表中都可能有0行?不知道那是不是你所追求的。如果需要所有表中都存在的计数,只需将LEFT JOIN更改为INNER JOIN(如果像我一样懒,则将JOIN更改)