我有一个要求,我需要生成有关当前软件项目的报告。其中两列是最新里程碑的日期和之前里程碑的日期。显然,里程碑存储在事务表中,因此每个项目可以有很多里程碑。
到目前为止我已经到了这里,但现在我遇到了问题:
select proj.*
from zsof_projects proj
join zsof_milestones current_milestone on current_milestone.product_id = proj.id
join zsof_milestones last_milestone on last_milestone.product_id = proj.id
join (
select product_id, max(actual_date) maxDate
from zsof_milestones
group by product_id
) a on a.product_id = current_milestone.product_id and a.maxDate = current_milestone.actual_date
join (
select mile.product_id, max(actual_date) maxDate
from zsof_milestones mile
join (
select product_id, max(actual_date) maxDate
from zsof_milestones
group by product_id
) a on a.product_id = mile.product_id and mile.actual_date < a.maxDate
group by mile.product_id
) b on b.product_id = last_milestone.product_id and b.maxDate = last_milestone.actual_date
order by proj.id;
我遇到的问题是,并非所有项目都有最新的里程碑,并非所有项目都有不止一个里程碑。我尝试过左连接,但后来每个项目都返回多行(这是我需要避免的)。
我正在使用Oracle 10,所以如果我可以在PL / SQL中使用它,我也可以使用它。
答案 0 :(得分:4)
使用分析:)
SELECT v.*
FROM (SELECT proj.*, actual_date,
MAX(actual_date) over(PARTITION BY ms.product_id) last_milestone,
lag(actual_date) over(PARTITION BY ms.product_id
ORDER BY actual_date) previous_milestone
FROM zsof_projects proj
LEFT JOIN zsof_milestones ms ON ms.product_id = proj.id) v
WHERE last_milestone = actual_date
OR (actual_date IS NULL AND last_milestone IS NULL)
更新:我将JOIN转换为LEFT JOIN,以防项目没有里程碑。