2016-11-28 3 views
0

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

DECLARE @Month int = MONTH(GETDATE()); 
DECLARE @Year int = YEAR(GETDATE()); 
DECLARE @ThisMth DATE = DATEFROMPARTS(@Year,@Month,1); 
DECLARE @BegYear DATE = DATEFROMPARTS(@Year, 7,1); 

--EMPLOYEES 
With EmpCount AS 
(
    SELECT 
     COUNT(DISTINCT(Employee)) As 'DistinctEmployees', PRCo 
    FROM 
     PREA 
    WHERE 
     Mth = @ThisMth 
    GROUP BY 
     PRCo), 
TotalEmp AS 
(
    SELECT 
     COUNT(DISTINCT(Employee)) As 'TotalDistinctEmployees', PRCo 
    FROM 
     PREA 
    WHERE 
     Mth >= @BegYear 
    GROUP BY 
     PRCo), 
Earnings AS 
(
    SELECT 
     SUM(Amount) AS Earnings, PRCo 
    FROM 
     PREA 
    WHERE 
     Mth = @ThisMth AND EDLType = 'E' 
    GROUP BY 
     PRCo), 
TotalEarnings AS 
(
    SELECT 
     SUM(Amount) as TotalEarnings, PRCo 
    FROM 
     PREA 
    WHERE 
     Mth >= @BegYear and EDLType = 'E' 
    GROUP BY 
     PRCo), 
Deductions AS 
(
    SELECT 
     SUM(Amount) AS Deduction, PRCo 
    FROM 
     PREA 
    WHERE 
     Mth = @ThisMth AND EDLType = 'D' 
    GROUP BY PRCo), 
TotalDeduction AS 
(
    SELECT 
     SUM(Amount) as TotalDed, PRCo 
    FROM 
     PREA 
    WHERE 
     Mth >= @BegYear AND EDLType = 'D' 
    GROUP BY 
     PRCo), 
Liabilities AS 
(
    SELECT 
     SUM(Amount) AS Liab, PRCo 
    FROM 
     PREA 
    WHERE 
     Mth = @ThisMth AND EDLType = 'L' 
    GROUP BY 
     PRCo), 
TotalLiabilities AS 
(
    SELECT 
     SUM(Amount) as TotalLiab, PRCo 
    FROM 
     PREA 
    WHERE 
     Mth >= @BegYear AND EDLType = 'L' 
    GROUP BY 
     PRCo) 
SELECT 
    a.PRCo, ec.DistinctEmployees, tem.TotalDistinctEmployees, 
    e.Earnings, te.TotalEarnings, d.Deduction, td.TotalDed, 
    l.Liab, tl.TotalLiab, te.TotalEarnings + tl.TotalLiab AS TotalCost 
FROM 
    PREA a 
INNER JOIN 
    EmpCount ec ON ec.PRCo = a.PRCo 
INNER JOIN 
    Earnings e ON e.PRCo = a.PRCo 
INNER JOIN 
    TotalEarnings te ON te.PRCo = a.PRCo 
INNER JOIN 
    TotalEmp tem ON tem.PRCo = a.PRCo 
INNER JOIN 
    Deductions d ON d.PRCo = a.PRCo 
INNER JOIN 
    TotalDeduction td ON td.PRCo = a.PRCo 
INNER JOIN 
    Liabilities l ON l.PRCo = a.PRCo 
INNER JOIN 
    TotalLiabilities tl ON tl.PRCo =a.PRCo 
WHERE 
    Mth = @ThisMth AND EDLType = 'E' 
GROUP BY 
    a.PRCo, ec.DistinctEmployees,e.Earnings, te.TotalEarnings, 
    tem.TotalDistinctEmployees, d.Deduction, td.TotalDed, l.Liab, tl.TotalLiab 
+2

Один из способов оценки запроса, чтобы смотреть на _execution plan_. Это покажет вам, что оптимизатор запросов сделал, чтобы помочь или повредить. Совет. Полезно помечать вопросы базы данных как с помощью соответствующего программного обеспечения (MySQL, Oracle, DB2, ...) и версии, например. 'SQL-сервер-2014'. 'tsql' также не указывается. И используйте псевдонимы повсюду, т. Е. Где 'Mth' происходит из последнего предложения WHERE? – HABO

+0

Операторы CASE, а также использование предложения OVER (https://msdn.microsoft.com/en-us/library/ms189461.aspx) _might_ помогут вам избежать выполнения всех запросов CTE, но действительно ли это будет работать лучше в вашей ситуации требуется тестирование. –

+0

http://stackoverflow.com/questions/30624475/multi-column-conditional-aggregation –

ответ

2

попробовать это:

SELECT PRCo 
      ,COUNT(DISTINCT(CASE WHEN Mth = @ThisMth THEN Employee ELSE NULL END)) As 'DistinctEmployees' 
      ,COUNT(DISTINCT(CASE WHEN Mth >= @BegYear THEN Employee ELSE NULL END)) As 'TotalDistinctEmployees' 
      ,SUM(CASE WHEN Mth = @ThisMth AND EDLType = 'E' THEN Amount ELSE 0 END) AS Earnings 
      ,SUM(CASE WHEN Mth >= @BegYear and EDLType = 'E' THEN Amount ELSE 0 END) AS TotalEarnings 
      ,SUM(CASE WHEN Mth = @ThisMth AND EDLType = 'D' THEN Amount ELSE 0 END) AS Deduction 
      ,SUM(CASE WHEN Mth >= @BegYear and EDLType = 'D' THEN Amount ELSE 0 END) AS TotalDed 
      ,SUM(CASE WHEN Mth = @ThisMth AND EDLType = 'L' THEN Amount ELSE 0 END) AS Liab 
      ,SUM(CASE WHEN Mth >= @BegYear and EDLType = 'L' THEN Amount ELSE 0 END) AS TotalLiab 
      ,SUM(CASE WHEN Mth >= @BegYear and EDLType like '[EL]' THEN Amount ELSE 0 END) AS TotalCost 
    FROM PREA AS p 
    GROUP BY PRCo 
+0

Спасибо, Нолан, это сработало, и это разрешает случаи, когда данных нет. – Phalanx

Смежные вопросы