SUM CASE LEFT JOIN выводит неверную сумму - PullRequest
0 голосов
/ 10 апреля 2019

У меня есть несколько левых объединений, которые мне нужны для агрегирования и денормализации данных. Как показано в этом примере, я получаю СУММУ из 3 FanActivities вместо 1 FanActivities от Fan.

пример: 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 ]

1 голос
/ 11 апреля 2019

Вы можете получить желаемый результат с помощью различных логик.Для вашего данного сценария вы можете добиться этого путем изменения в вашем случае, когда логика

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

В этой логике СЛУЧАЙ, КОГДА УСТАНАВЛИВАЕТ строку с комбинацией желаемого поля, а когда обход условия устанавливает нулевое значение, потому что мызнать, что предложение count не считает нулевое поле и с помощью различных вы получаете 1 вместо 3

0 голосов
/ 10 апреля 2019

# 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, если я ленив, как я)

...