2016-02-16 32 views
0

這3個查詢怎麼可以加入到1中。我該如何加入3個SQL查詢

我不是在尋找UNION ALL結果。

每排我想預測,預算,實際

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不爲null)' –

+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 
;