我为想象中的律师创建了一个数据库,我最后一次完成的查询让我疯了。我需要弄清楚律师在公司职业生涯中所取得的总数,我time_spent
和rate
要加倍和特殊费率。 (特价是公司合同的一次性费用,因此没有多少案例)。我能想出的最好的是下面的代码。它按照我想要的方式行事,但只显示处理特殊费率的案件的律师。
我基本上希望它在表中显示查询结果,即使特殊速率为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)
答案 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)