Sql server SUM CASE LEFT JOIN输出给出错误的SUM

Sql server SUM CASE LEFT JOIN输出给出错误的SUM,sql-server,sum,left-join,case,Sql Server,Sum,Left Join,Case,我有多个左连接,需要聚合和反规范化数据 如本例所示,我得到的是3个FA的和,而不是1个FA乘以F 例如: 当我删除最后2个左连接时,它将给出所需的输出1。但我需要这两个连接来聚合这两个表中的其他数据 SELECT SUM(CASE WHEN fa.ProfileFanId=1111 and fa.ActivityId=2 THEN 1 ELSE 0 END) as conditionalcountall FROM #Fan f LEFT JOIN #ProfileFa

我有多个左连接,需要聚合和反规范化数据 如本例所示,我得到的是3个FA的和,而不是1个FA乘以F

例如:

当我删除最后2个左连接时,它将给出所需的输出1。但我需要这两个连接来聚合这两个表中的其他数据

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

我做错了什么?

#DeliveryActions和#DA在联接中必须有多行。如果您只想知道它是否存在一次,那么必须将这些表中的数据分组

--替换这个

LEFT JOIN #DA das
    ON das.PFId = pf.Id
LEFT JOIN #DA da
    ON da.Id = das.DAId
--用这个

LEFT JOIN (SELECT PFId
            FROM #DA ia
            LEFT JOIN #DA ib
            ON ia.DAId = ib.Id
            GROUP BY PFId) das
            ON das.PFId = pf.Id

请注意,因为到处都使用左联接,所以其他任何表中都可能有0行?我不知道你是不是在追求这个。如果您需要所有表中存在的计数,只需将左连接更改为内部连接(或者如果像我一样懒惰,则更改为连接)

您可以借助不同的逻辑获得所需的结果。 对于您给定的场景,您可以通过更改案例逻辑来实现这一点

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

在这种逻辑情况下,当使用所需字段的组合设置字符串时,当条件绕过设置null时,因为我们知道count子句不计算null字段,并且在distinct的帮助下,您得到的是1而不是3

这是一个常见错误,人们希望加入某些聚合(每个聚合可能涉及加入)但他们错误地尝试进行所有的连接,然后进行所有的聚合。这是一个常见问题。在考虑发帖之前,请总是用谷歌搜索你的错误信息或你的问题/问题/目标的许多清晰、简洁和准确的措辞,有没有你的特定字符串/名称,并阅读许多答案。如果你发布一个问题,用一句话作为标题。请参阅文本上的投票箭头和鼠标。当您只需要对来自活动表的两个字段求和时,为什么要使用联接中的所有表?你的数据是多余的,这就是为什么它会返回3的正确总和。你给出代码很好,但请在你的问题中把它作为文本,而不仅仅是一个链接——让你的文章自我包含。要使其“最小”,请包含您所能提供的最少代码,即您显示为OK的代码,并由您显示为不OK的代码扩展。(调试基础。)您需要“聚合其他数据”,但不需要“这两个连接”--它提供了一个没有用的表。如果你看看你的部分结果,你可能会看到。您的MCVE实际上并没有告诉我们您想要在结果中显示哪些行。另外,写出来可能会让您看到您需要子查询。可能是“确定”的重复,因此最后2个连接需要分组为一个具有单个ID的子查询。我将进行编辑。
LEFT JOIN (SELECT PFId
            FROM #DA ia
            LEFT JOIN #DA ib
            ON ia.DAId = ib.Id
            GROUP BY PFId) das
            ON das.PFId = pf.Id
SELECT  COUNT(DISTINCT 
             CASE WHEN fa.PFId=1111 and fa.AId=2 
                  THEN CAST(fa.PFId AS VARCHAR) + '-' + CAST(fa.ActivityId AS VARCHAR) 
             ELSE NULL END
        ) as conditionalcountall