Перекрестное применение TSQL с подсчетом и суммой

Я только что обнаружил оператор CROSS APPLY, и у меня сложилось впечатление, что он очень полезен при манипулировании производными столбцами для вычислений.

Итак, я попробовал следующее:

SELECT leadYear,TotalLeadsCalled,SuccessLeadsCalled,SuccessLeadsPercent
FROM dbo.tblBinOutboundCallActivity 
CROSS APPLY(VALUES (YEAR(leadactivitydate))) AS a1(leadyear) 
CROSS APPLY(VALUES (COUNT(leadStatusID))) AS a2(TotalLeadsCalled) 
CROSS APPLY(VALUES (COUNT(CASE WHEN leadStatusID = 2 THEN 1 ELSE NULL END))) AS a3(SuccessLeadsCalled) 
CROSS APPLY(VALUES (SUM((SuccessLeadsCalled/TotalLeadsCalled)*100))) AS a4(SuccessLeadsPercent) 
GROUP BY leadYear

Но я получаю следующую ошибку:

Агрегаты с правой стороны APPLY не могут ссылаться на столбцы с левой стороны.

Я действительно не понимаю ошибку, тем более что первое перекрестное применение фактически работает изолированно. Я только что совершенно неправильно понял концепцию?


person ComfortablyNumb    schedule 24.02.2014    source источник


Ответы (2)


Cross apply работает на линейном уровне.

«Для каждой строки слева мы применяем функцию справа».

Ваша агрегация не имеет значения для каждой строки.

person Dumitrescu Bogdan    schedule 24.02.2014

Это сработает.

Только используя ПРИМЕНИТЬ:

SELECT leadYear,TotalLeadsCalled,SuccessLeadsCalled,SuccessLeadsPercent
FROM dbo.tblBinOutboundCallActivity a
    CROSS APPLY (SELECT YEAR(leadactivitydate) leadyear FROM dbo.tblBinOutboundCallActivity WHERE YEAR(leadactivitydate) = YEAR(a.leadactivitydate)) a1
    CROSS APPLY (SELECT COUNT(leadStatusID) TotalLeadsCalled FROM dbo.tblBinOutboundCallActivity WHERE YEAR(leadactivitydate) = a1.leadyear) a2
    CROSS APPLY (SELECT COUNT(CASE WHEN leadStatusID = 2 THEN 1 ELSE NULL END) SuccessLeadsCalled FROM dbo.tblBinOutboundCallActivity WHERE YEAR(leadactivitydate) = a1.leadyear) a3
    CROSS APPLY (SELECT 100.*SuccessLeadsCalled/TotalLeadsCalled SuccessLeadsPercent) a4
GROUP BY leadYear,TotalLeadsCalled,SuccessLeadsCalled,SuccessLeadsPercent

CTE и ПРИМЕНЕНИЕ:

WITH Years AS
(
    SELECT YEAR(leadactivitydate) leadyear
    FROM dbo.tblBinOutboundCallActivity
    GROUP BY YEAR(leadactivitydate)
)
    SELECT leadYear,TotalLeadsCalled,SuccessLeadsCalled,SuccessLeadsPercent
    FROM Years      
        CROSS APPLY (SELECT COUNT(leadStatusID) TotalLeadsCalled FROM dbo.tblBinOutboundCallActivity WHERE YEAR(leadactivitydate) = leadyear) a2
        CROSS APPLY (SELECT COUNT(CASE WHEN leadStatusID = 2 THEN 1 ELSE NULL END) SuccessLeadsCalled FROM dbo.tblBinOutboundCallActivity WHERE YEAR(leadactivitydate) = leadyear) a3
        CROSS APPLY (SELECT 100.*SuccessLeadsCalled/TotalLeadsCalled SuccessLeadsPercent) a4
person EarlOfEnnui    schedule 29.04.2014