2009-10-20 81 views
2

我有一個需求,我需要生成一個關於當前軟件項目的報告。其中兩列是最新里程碑的日期和之前的里程碑的日期。很顯然,里程碑存儲在交易表中,所以我們可以爲每個項目設立多個里程碑。選擇單行交易

我已經得到了到這裏爲止,但現在我有問題:

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中使用的,我也會這樣做。

回答

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) 

更新:我改變了連接成一個LEFT JOIN的情況下,一個項目沒有一個里程碑。

+0

謝謝!這很好。我還沒有看到你在那裏使用的一些功能,所以看起來我有一些閱讀要做。 – 2009-10-20 17:01:58