2016-02-16 2 views
0

Как это 3 запросы могут быть объединены в 1.Как я могу присоединиться к 3 SQL запросов

Я не смотрю для UNION ALL результата.

Per строки Я хочу прогноз, бюджет, Actual

SELECT 
    ps.PersonId, 
    SUM(TF.Hours * r.Amount) as Forecast 
FROM ProjectStaffing ps 
INNER JOIN Rate r on (r.ProviderId = ps.ProviderId AND r.OrganizationId = ps.OrganizationId AND r.RoleId = ps.RoleId) 
INNER JOIN TimeForecast TF on (TF.ProjectStaffingId = ps.Id) 
WHERE ps.ProjectId = @ProjectId 
GROUP BY ps.PersonId 

SELECT 
    ps.PersonId, 
    SUM(tb.Hours * r.Amount) as Budget 
FROM ProjectStaffing ps 
INNER JOIN Rate r on (r.ProviderId = ps.ProviderId AND r.OrganizationId = ps.OrganizationId AND r.RoleId = ps.RoleId) 
INNER JOIN TimeBudget tb on (tb.ProjectStaffingId = ps.Id) 
WHERE ps.ProjectId = @ProjectId 
GROUP BY ps.PersonId 

SELECT 
    ps.PersonId, 
    SUM(ta.Hours * r.Amount) as Actual 
FROM ProjectStaffing ps 
INNER JOIN Rate r on (r.ProviderId = ps.ProviderId AND r.OrganizationId = ps.OrganizationId AND r.RoleId = ps.RoleId) 
INNER JOIN TimeActual ta on (ta.ProjectStaffingId = ps.Id) 
WHERE ps.ProjectId = @ProjectId 
GROUP BY ps.PersonId 

Я попробовал это, но только получает странные результаты

SELECT 
    PS.PersonId, 
    SUM(TF.Hours * r.Amount) as Forecast, 
    SUM(TB.Hours * r.Amount) as Budget, 
    SUM(TA.Hours * r.Amount) as Actual 
FROM ProjectStaffing PS 
INNER JOIN Rate r on (r.ProviderId = PS.ProviderId AND r.OrganizationId = PS.OrganizationId AND r.RoleId = PS.RoleId) 
LEFT JOIN TimeForecast TF on (TF.ProjectStaffingId = PS.Id) 
LEFT JOIN TimeBudget TB on (TB.ProjectStaffingId = PS.Id) 
LEFT JOIN TimeActual TA on (TA.ProjectStaffingId = PS.Id) 
WHERE PS.ProjectId = @ProjectId 
    AND TF.Hours is not null 
GROUP BY PS.PersonId 
+0

удалить 'и TF.Hours не null' или заменить его' и (TF.Hours не является нулевым или TB.Hours не является нулевым или TA.Hours не равно нулю) ' –

+0

что вы имеете в виду странный результат? можете ли вы просто добавить образец результата к вопросу? – Susilo

ответ

0

Я узнал, что это делает эту работу. Но это слишком сложно. Должен быть более простой способ.

SELECT * 
FROM 
(
    SELECT 
     --ps.PersonId, 
     'FORECAST' AS Description, 
     SUM(TF.Hours * r.Amount) as Total --Forecast 
    FROM ProjectStaffing ps 
    INNER JOIN Rate r on (r.ProviderId = ps.ProviderId AND r.OrganizationId = ps.OrganizationId AND r.RoleId = ps.RoleId) 
    INNER JOIN TimeForecast TF on (TF.ProjectStaffingId = ps.Id) 
    WHERE ps.ProjectId = @ProjectId 
    --GROUP BY ps.PersonId 

    UNION ALL 

    SELECT 
     --ps.PersonId, 
     'BUDGET' AS Description, 
     SUM(tb.Hours * r.Amount) as Total --Budget 
    FROM ProjectStaffing ps 
    INNER JOIN Rate r on (r.ProviderId = ps.ProviderId AND r.OrganizationId = ps.OrganizationId AND r.RoleId = ps.RoleId) 
    INNER JOIN TimeBudget tb on (tb.ProjectStaffingId = ps.Id) 
    WHERE ps.ProjectId = @ProjectId 
    --GROUP BY ps.PersonId 

    UNION ALL 

    SELECT 
     --ps.PersonId, 
     'ACTUAL' AS Description, 
     SUM(ta.Hours * r.Amount) as Total --Actual 
    FROM ProjectStaffing ps 
    INNER JOIN Rate r on (r.ProviderId = ps.ProviderId AND r.OrganizationId = ps.OrganizationId AND r.RoleId = ps.RoleId) 
    INNER JOIN TimeActual ta on (ta.ProjectStaffingId = ps.Id) 
    WHERE ps.ProjectId = @ProjectId 
    --GROUP BY ps.PersonId 
) p 
PIVOT (SUM(p.Total) FOR [Description] in ([FORECAST], [BUDGET], [ACTUAL])) AS pvt 
2

Один прямой способ сделать это состоит в использовании Common Table Expressions ,

Если у всех трех подзапросов есть строки для каждого PersonId, то вы можете INNER JOIN их в любом порядке. Если в одном из подзапросов нет строк для всех PersonIds, тогда LEFT JOIN это.

WITH CTE_Forecast AS 
(
    SELECT 
     ps.PersonId, 
     SUM(TF.Hours * r.Amount) as Forecast 
    FROM 
     ProjectStaffing ps 
    INNER JOIN 
     Rate r ON (r.ProviderId = ps.ProviderId 
        AND r.OrganizationId = ps.OrganizationId 
        AND r.RoleId = ps.RoleId) 
    INNER JOIN 
     TimeForecast TF on (TF.ProjectStaffingId = ps.Id) 
    WHERE 
     ps.ProjectId = @ProjectId 
    GROUP BY 
     ps.PersonId 
) 
, CTE_Budget AS 
(
    SELECT 
     ps.PersonId, 
     SUM(tb.Hours * r.Amount) as Budget 
    FROM 
     ProjectStaffing ps 
    INNER JOIN 
     Rate r ON (r.ProviderId = ps.ProviderId 
        AND r.OrganizationId = ps.OrganizationId 
        AND r.RoleId = ps.RoleId) 
    INNER JOIN 
     TimeBudget tb on (tb.ProjectStaffingId = ps.Id) 
    WHERE 
     ps.ProjectId = @ProjectId 
    GROUP BY 
     ps.PersonId 
) 
, CTE_Actual AS 
(
    SELECT 
     ps.PersonId, 
     SUM(ta.Hours * r.Amount) as Actual 
    FROM 
     ProjectStaffing ps 
    INNER JOIN 
     Rate r ON (r.ProviderId = ps.ProviderId 
        AND r.OrganizationId = ps.OrganizationId 
        AND r.RoleId = ps.RoleId) 
    INNER JOIN 
     TimeActual ta on (ta.ProjectStaffingId = ps.Id) 
    WHERE 
     ps.ProjectId = @ProjectId 
    GROUP BY 
     ps.PersonId 
) 
SELECT 
    CTE_Forecast.PersonId, 
    CTE_Forecast.Forecast, 
    CTE_Budget.Budget, 
    CTE_Actual.Actual 
FROM 
    CTE_Forecast 
INNER JOIN 
    CTE_Budget ON CTE_Budget.PersonId = CTE_Forecast.PersonId 
INNER JOIN 
    CTE_Actual ON CTE_Actual.PersonId = CTE_Forecast.PersonId 
; 
Смежные вопросы