使用Oracle SQL进行复杂计算

时间:2011-03-02 19:16:29

标签: sql oracle oracle10g

我为想象中的律师创建了一个数据库,我最后一次完成的查询让我疯了。我需要弄清楚律师在公司职业生涯中所取得的总数,我time_spentrate要加倍和特殊费率。 (特价是公司合同的一次性费用,因此没有多少案例)。我能想出的最好的是下面的代码。它按照我想要的方式行事,但只显示处理特殊费率的案件的律师。

我基本上希望它在表中显示查询结果,即使特殊速率为NULL。

我已经命令该表首先显示最高金额,所以我可以使用ROWNUM仅显示前10%的收入者。

CREATE VIEW rich_solicitors AS 
  SELECT notes.time_spent * rate.rate_amnt + special_rate.s_rate_amnt AS solicitor_made,          
        notes.case_id
   FROM notes, 
        rate, 
        solicitor_rate, 
        solicitor, 
        case, 
        contract, 
        special_rate
  WHERE notes.solicitor_id = solicitor.solicitor_id
    AND solicitor.solicitor_id = solicitor_rate.solicitor_id
    AND solicitor_rate.rate_id = rate.rate_id
    AND notes.case_id = case.case_id
    AND case.contract_id = contract.contract_id
    AND contract.contract_id = special_rate.contract_id
ORDER BY -solicitor_made;

查询:

SELECT * 
  FROM rich_solicitors
 WHERE ROWNUM <= (SELECT COUNT(*)/10 
                    FROM rich_solicitors)

2 个答案:

答案 0 :(得分:5)

我怀疑你在示例查询中使用ROWNUM ......

Oracle9i +支持分析功能,如ROW_NUMBER和NTILE,使您的示例之类的查询更容易。分析也是ANSI,因此实现时语法是一致的(IE:不在MySQL或SQLite上)。我将您的查询重新编写为:

SELECT x.*
  FROM (SELECT n.time_spent * r.rate_amnt + COALESCE(spr.s_rate_amnt, 0) AS solicitor_made,          
               n.case_id,
               NTILE(10) OVER (ORDER BY solicitor_made) AS rank
          FROM NOTES n 
          JOIN SOLICITOR s ON s.solicitor_id = n.solicitor_id
          JOIN SOLICITOR_RATE sr ON sr.solicitor_id = s.solicitor_id 
          JOIN RATE r ON r.rate_id = sr.rate_id
          JOIN CASE c ON c.case_id = n.case_id 
          JOIN CONTRACT cntrct ON cntrct.contract_id = c.contract_id
     LEFT JOIN SPECIAL_RATE spr ON spr.contract_id = cntrct.contract_id) x
 WHERE x.rank = 1

如果您是SQL新手,我建议使用ANSI-92语法。您的示例使用ANSI-89,它不支持OUTER JOIN并且被视为已弃用。我对SPECIAL_RATE表使用了LEFT OUTER JOIN,因为并非所有作业都可能附加特殊费率。

也不建议在视图中包含ORDER BY,因为视图封装了查询 - 没有人知道默认排序是什么,并且可能包括他们自己的(可能浪费资源)。

答案 1 :(得分:3)

你需要以特价加入。

如果我记得oracle语法是这样的:

AND contract.contract_id = special_rate.contract_id (+) 

但现在special_rate。*可以为null,所以:

+ special_rate.s_rate_amnt

需要:

+ coalesce(special_rate.s_rate_amnt,0)