这3个查询如何加入1。
我不是在寻找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 :(得分: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
;
答案 1 :(得分: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