选择事务作为单行

时间:2009-10-20 16:18:56

标签: sql oracle plsql oracle10g

我有一个要求,我需要生成有关当前软件项目的报告。其中两列是最新里程碑的日期和之前里程碑的日期。显然,里程碑存储在事务表中,因此每个项目可以有很多里程碑。

到目前为止我已经到了这里,但现在我遇到了问题:

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中使用它,我也可以使用它。

1 个答案:

答案 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,以防项目没有里程碑。